Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 49e8fae

Browse files
committedMar 16, 2022·
added support for new pmic
1 parent 5ae2f68 commit 49e8fae

File tree

6 files changed

+769
-41
lines changed

6 files changed

+769
-41
lines changed
 

‎boards.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ mkrwifi1010.build.usb_product="Arduino MKR WiFi 1010"
208208
mkrwifi1010.build.usb_manufacturer="Arduino LLC"
209209
mkrwifi1010.build.board=SAMD_MKRWIFI1010
210210
mkrwifi1010.build.core=arduino
211-
mkrwifi1010.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -DUSE_BQ24195L_PMIC
211+
mkrwifi1010.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -DUSE_BQ24195L_PMIC -DUSE_MP2629_PMIC
212212
mkrwifi1010.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld
213213
mkrwifi1010.build.openocdscript=openocd_scripts/arduino_zero.cfg
214214
mkrwifi1010.build.variant=mkrwifi1010

‎cores/arduino/PMIC/BQ24195.h

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
BQ24195.h - Register definitions for BQ24195/BQ24195L PMICs.
3+
Copyright (c) 2020 Kevin P. Fleming. All right reserved.
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
This library is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+
See the GNU Lesser General Public License for more details.
12+
You should have received a copy of the GNU Lesser General Public
13+
License along with this library; if not, write to the Free Software
14+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
17+
#pragma once
18+
19+
#include <stdint.h>
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
25+
typedef union {
26+
struct {
27+
uint8_t IINLIM:3;
28+
uint8_t VINDPM:4;
29+
uint8_t EN_HIZ:1;
30+
};
31+
uint8_t val;
32+
} BQ24195_REG00;
33+
34+
static_assert(sizeof(BQ24195_REG00) == 1, "BQ24195_REG00 union size is incorrect, should be 1 byte.");
35+
36+
typedef union {
37+
struct {
38+
uint8_t RSVD:1;
39+
uint8_t SYS_MIN:3;
40+
uint8_t CHG_CONFIG_ENABLE:1;
41+
uint8_t CHG_CONFIG_OTG:1;
42+
uint8_t WATCHDOG_TIMER_RESET:1;
43+
uint8_t REGISTER_RESET:1;
44+
};
45+
uint8_t val;
46+
} BQ24195_REG01;
47+
48+
static_assert(sizeof(BQ24195_REG01) == 1, "BQ24195_REG01 union size is incorrect, should be 1 byte.");
49+
50+
typedef union {
51+
struct {
52+
uint8_t FORCE_20PCT:1;
53+
uint8_t RSVD:1;
54+
uint8_t ICHG:6;
55+
};
56+
uint8_t val;
57+
} BQ24195_REG02;
58+
59+
static_assert(sizeof(BQ24195_REG02) == 1, "BQ24195_REG02 union size is incorrect, should be 1 byte.");
60+
61+
typedef union {
62+
struct {
63+
uint8_t ITERM:4;
64+
uint8_t IPRECHG:4;
65+
};
66+
uint8_t val;
67+
} BQ24195_REG03;
68+
69+
static_assert(sizeof(BQ24195_REG03) == 1, "BQ24195_REG03 union size is incorrect, should be 1 byte.");
70+
71+
typedef union {
72+
struct {
73+
uint8_t VRECHG:1;
74+
uint8_t BATLOWV:1;
75+
uint8_t VREG:6;
76+
};
77+
uint8_t val;
78+
} BQ24195_REG04;
79+
80+
static_assert(sizeof(BQ24195_REG04) == 1, "BQ24195_REG04 union size is incorrect, should be 1 byte.");
81+
82+
typedef union {
83+
struct {
84+
uint8_t RSVD:1;
85+
uint8_t CHG_TIMER:2;
86+
uint8_t EN_TIMER:1;
87+
uint8_t WATCHDOG:2;
88+
uint8_t TERM_STAT:1;
89+
uint8_t EN_TERM:1;
90+
};
91+
uint8_t val;
92+
} BQ24195_REG05;
93+
94+
static_assert(sizeof(BQ24195_REG05) == 1, "BQ24195_REG05 union size is incorrect, should be 1 byte.");
95+
96+
typedef union {
97+
struct {
98+
uint8_t VRECHG:1;
99+
uint8_t BATLOWV:1;
100+
uint8_t VREG:6;
101+
};
102+
uint8_t val;
103+
} BQ24195_REG06;
104+
105+
static_assert(sizeof(BQ24195_REG06) == 1, "BQ24195_REG06 union size is incorrect, should be 1 byte.");
106+
107+
typedef union {
108+
struct {
109+
uint8_t INT_MASK_BAT:1;
110+
uint8_t INT_MASK_CHG:1;
111+
uint8_t RSVD:3;
112+
uint8_t BATFET_DISABLE:1;
113+
uint8_t TMR2X_EN:1;
114+
uint8_t DPDM_EN:1;
115+
};
116+
uint8_t val;
117+
} BQ24195_REG07;
118+
119+
static_assert(sizeof(BQ24195_REG07) == 1, "BQ24195_REG07 union size is incorrect, should be 1 byte.");
120+
121+
typedef union {
122+
struct {
123+
uint8_t VSYS_STAT:1;
124+
uint8_t THERM_STAT:1;
125+
uint8_t PG_STAT:1;
126+
uint8_t DPM_STAT:1;
127+
uint8_t CHRG_STAT:2;
128+
uint8_t VBUS_STAT:2;
129+
};
130+
uint8_t val;
131+
} BQ24195_REG08;
132+
133+
static_assert(sizeof(BQ24195_REG08) == 1, "BQ24195_REG08 union size is incorrect, should be 1 byte.");
134+
135+
typedef union {
136+
struct {
137+
uint8_t NTC_FAULT:3;
138+
uint8_t BAT_FAULT:1;
139+
uint8_t CHRG_FAULT:2;
140+
uint8_t RSVD:1;
141+
uint8_t WATCHDOG_FAULT:1;
142+
};
143+
uint8_t val;
144+
} BQ24195_REG09;
145+
146+
static_assert(sizeof(BQ24195_REG09) == 1, "BQ24195_REG09 union size is incorrect, should be 1 byte.");
147+
148+
typedef union {
149+
struct {
150+
uint8_t DEV_REG:2;
151+
uint8_t TS_PROFILE:1;
152+
uint8_t PN:3;
153+
uint8_t RSVD:2;
154+
};
155+
uint8_t val;
156+
} BQ24195_REG0A;
157+
158+
static_assert(sizeof(BQ24195_REG0A) == 1, "BQ24195_REG0A union size is incorrect, should be 1 byte.");
159+
160+
#define BQ24195_ADDRESS 0x6B
161+
#define BQ24195_REG00_ADDRESS 0x00
162+
#define BQ24195_REG01_ADDRESS 0x01
163+
#define BQ24195_REG02_ADDRESS 0x02
164+
#define BQ24195_REG03_ADDRESS 0x03
165+
#define BQ24195_REG04_ADDRESS 0x04
166+
#define BQ24195_REG05_ADDRESS 0x05
167+
#define BQ24195_REG06_ADDRESS 0x06
168+
#define BQ24195_REG07_ADDRESS 0x07
169+
#define BQ24195_REG08_ADDRESS 0x08
170+
#define BQ24195_REG09_ADDRESS 0x09
171+
#define BQ24195_REG0A_ADDRESS 0x0A
172+
173+
#ifdef __cplusplus
174+
} // extern "C"
175+
#endif

‎cores/arduino/PMIC/MP2629.h

Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
/*
2+
MP2629.h - Register definitions for MP2629/MP2629L PMICs.
3+
Copyright (c) 2020 Kevin P. Fleming. All right reserved.
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
This library is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+
See the GNU Lesser General Public License for more details.
12+
You should have received a copy of the GNU Lesser General Public
13+
License along with this library; if not, write to the Free Software
14+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
17+
#pragma once
18+
19+
#include <stdint.h>
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
25+
typedef union {
26+
struct {
27+
uint8_t IIN_LIM:6;
28+
uint8_t EN_LIM:1;
29+
uint8_t EN_HIZ:1;
30+
};
31+
uint8_t val;
32+
} MP2629_REG00;
33+
34+
static_assert(sizeof(MP2629_REG00) == 1, "MP2629_REG00 union size is incorrect, should be 1 byte.");
35+
36+
typedef union {
37+
struct {
38+
uint8_t VIN_MIN:4;
39+
uint8_t RSVD:3;
40+
uint8_t REGISTER_RESET:1;
41+
};
42+
uint8_t val;
43+
} MP2629_REG01;
44+
45+
static_assert(sizeof(MP2629_REG01) == 1, "MP2629_REG01 union size is incorrect, should be 1 byte.");
46+
47+
typedef union {
48+
struct {
49+
uint8_t AICO_EN:1;
50+
uint8_t NTC_OPTION:1;
51+
uint8_t TJ_REG:2;
52+
uint8_t EN_CHG_NTC:1;
53+
uint8_t EN_OTG_NTC:1;
54+
uint8_t NTC_TYPE:1;
55+
uint8_t TSM_DLY:1;
56+
};
57+
uint8_t val;
58+
} MP2629_REG02;
59+
60+
static_assert(sizeof(MP2629_REG02) == 1, "MP2629_REG02 union size is incorrect, should be 1 byte.");
61+
62+
typedef union {
63+
struct {
64+
uint8_t IIN_DSCHG:3;
65+
uint8_t VIN_DSCHG:3;
66+
uint8_t ADC_RATE:1;
67+
uint8_t ADC_START:1;
68+
};
69+
uint8_t val;
70+
} MP2629_REG03;
71+
72+
static_assert(sizeof(MP2629_REG03) == 1, "MP2629_REG03 union size is incorrect, should be 1 byte.");
73+
74+
typedef union {
75+
struct {
76+
uint8_t VTRACK:1;
77+
uint8_t VSYS_MIN:3;
78+
uint8_t CHG_CONFIG:2;
79+
uint8_t STAT_EN:1;
80+
uint8_t BAT_LOADEN:1;
81+
};
82+
uint8_t val;
83+
} MP2629_REG04;
84+
85+
static_assert(sizeof(MP2629_REG04) == 1, "MP2629_REG04 union size is incorrect, should be 1 byte.");
86+
87+
typedef union {
88+
struct {
89+
uint8_t ICC:7;
90+
uint8_t VBATT_PRE:1;
91+
};
92+
uint8_t val;
93+
} MP2629_REG05;
94+
95+
static_assert(sizeof(MP2629_REG05) == 1, "MP2629_REG05 union size is incorrect, should be 1 byte.");
96+
97+
typedef union {
98+
struct {
99+
uint8_t ITERM:4;
100+
uint8_t IPRE:4;
101+
};
102+
uint8_t val;
103+
} MP2629_REG06;
104+
105+
static_assert(sizeof(MP2629_REG06) == 1, "MP2629_REG06 union size is incorrect, should be 1 byte.");
106+
107+
typedef union {
108+
struct {
109+
uint8_t VRECH:1;
110+
uint8_t VBATT_REG:7;
111+
};
112+
uint8_t val;
113+
} MP2629_REG07;
114+
115+
static_assert(sizeof(MP2629_REG07) == 1, "MP2629_REG07 union size is incorrect, should be 1 byte.");
116+
117+
typedef union {
118+
struct {
119+
uint8_t EN_TIMER:1;
120+
uint8_t CHG_TMR:2;
121+
uint8_t WATCHDOG_TIM_RST:1;
122+
uint8_t WATCHDOG:2;
123+
uint8_t RSVD:1;
124+
uint8_t EN_TERM:1;
125+
};
126+
uint8_t val;
127+
} MP2629_REG08;
128+
129+
static_assert(sizeof(MP2629_REG08) == 1, "MP2629_REG08 union size is incorrect, should be 1 byte.");
130+
131+
typedef union {
132+
struct {
133+
uint8_t VCLAMP:3;
134+
uint8_t RSVD:1;
135+
uint8_t RBAT_CMP:4;
136+
};
137+
uint8_t val;
138+
} MP2629_REG09;
139+
140+
static_assert(sizeof(MP2629_REG09) == 1, "MP2629_REG09 union size is incorrect, should be 1 byte.");
141+
142+
typedef union {
143+
struct {
144+
uint8_t TDISC_L:2;
145+
uint8_t TDISC_H:2;
146+
uint8_t SYSRST_SEL:1;
147+
uint8_t BATFET_DIS:1;
148+
uint8_t TMR2X_EN:1;
149+
uint8_t SW_FREQ:1;
150+
};
151+
uint8_t val;
152+
} MP2629_REG0A;
153+
154+
static_assert(sizeof(MP2629_REG0A) == 1, "MP2629_REG0A union size is incorrect, should be 1 byte.");
155+
156+
typedef union {
157+
struct {
158+
uint8_t RSVD:6;
159+
uint8_t USB_DET_EN:1;
160+
uint8_t INT_MASK:1;
161+
};
162+
uint8_t val;
163+
} MP2629_REG0B;
164+
165+
static_assert(sizeof(MP2629_REG0B) == 1, "MP2629_REG0B union size is incorrect, should be 1 byte.");
166+
167+
typedef union {
168+
struct {
169+
uint8_t VSYS_STAT:1;
170+
uint8_t THERM_STAT:1;
171+
uint8_t RNTC_FLOAT_STAT:1;
172+
uint8_t CHG_STAT:2;
173+
uint8_t VIN_STAT:3;
174+
};
175+
uint8_t val;
176+
} MP2629_REG0C;
177+
178+
static_assert(sizeof(MP2629_REG0C) == 1, "MP2629_REG0C union size is incorrect, should be 1 byte.");
179+
180+
typedef union {
181+
struct {
182+
uint8_t NTC_FAULT:3;
183+
uint8_t BAT_FAULT:1;
184+
uint8_t THERMAL_SHUTDOWN:1;
185+
uint8_t INPUT_FAULT:1;
186+
uint8_t OTG_FAULT:1;
187+
uint8_t WATCHDOG_FAULT:1;
188+
};
189+
uint8_t val;
190+
} MP2629_REG0D;
191+
192+
static_assert(sizeof(MP2629_REG0D) == 1, "MP2629_REG0D union size is incorrect, should be 1 byte.");
193+
194+
typedef union {
195+
struct {
196+
uint8_t VBATT:8;
197+
};
198+
uint8_t val;
199+
} MP2629_REG0E;
200+
201+
static_assert(sizeof(MP2629_REG0E) == 1, "MP2629_REG0E union size is incorrect, should be 1 byte.");
202+
203+
typedef union {
204+
struct {
205+
uint8_t VSYS:8;
206+
};
207+
uint8_t val;
208+
} MP2629_REG0F;
209+
210+
static_assert(sizeof(MP2629_REG0F) == 1, "MP2629_REG0F union size is incorrect, should be 1 byte.");
211+
212+
typedef union {
213+
struct {
214+
uint8_t NTC:8;
215+
};
216+
uint8_t val;
217+
} MP2629_REG10;
218+
219+
static_assert(sizeof(MP2629_REG10) == 1, "MP2629_REG10 union size is incorrect, should be 1 byte.");
220+
221+
typedef union {
222+
struct {
223+
uint8_t VIN:7;
224+
uint8_t RSVD:1;
225+
};
226+
uint8_t val;
227+
} MP2629_REG11;
228+
229+
static_assert(sizeof(MP2629_REG11) == 1, "MP2629_REG11 union size is incorrect, should be 1 byte.");
230+
231+
typedef union {
232+
struct {
233+
uint8_t ICHG:8;
234+
};
235+
uint8_t val;
236+
} MP2629_REG12;
237+
238+
static_assert(sizeof(MP2629_REG12) == 1, "MP2629_REG12 union size is incorrect, should be 1 byte.");
239+
240+
typedef union {
241+
struct {
242+
uint8_t IIN:8;
243+
};
244+
uint8_t val;
245+
} MP2629_REG13;
246+
247+
static_assert(sizeof(MP2629_REG13) == 1, "MP2629_REG13 union size is incorrect, should be 1 byte.");
248+
249+
typedef union {
250+
struct {
251+
uint8_t IIN_DPM:6;
252+
uint8_t IINPPM_STAT:1;
253+
uint8_t VINPPM_STAT:1;
254+
};
255+
uint8_t val;
256+
} MP2629_REG14;
257+
258+
static_assert(sizeof(MP2629_REG14) == 1, "MP2629_REG14 union size is incorrect, should be 1 byte.");
259+
260+
typedef union {
261+
struct {
262+
uint8_t RSVD:5;
263+
uint8_t VINPPM_INT_MASK:2;
264+
uint8_t AICO_STAT:1;
265+
};
266+
uint8_t val;
267+
} MP2629_REG15;
268+
269+
static_assert(sizeof(MP2629_REG15) == 1, "MP2629_REG15 union size is incorrect, should be 1 byte.");
270+
271+
typedef union {
272+
struct {
273+
uint8_t VCOLD:1;
274+
uint8_t VCOOL:2;
275+
uint8_t VWARM:2;
276+
uint8_t VHOT:1;
277+
uint8_t JEITA_ISET:1;
278+
uint8_t JEITA_VSET:1;
279+
};
280+
uint8_t val;
281+
} MP2629_REG16;
282+
283+
static_assert(sizeof(MP2629_REG16) == 1, "MP2629_REG16 union size is incorrect, should be 1 byte.");
284+
285+
typedef union {
286+
struct {
287+
uint8_t RSVDL3_0:3;
288+
uint8_t PN:3;
289+
uint8_t RSVD7:1;
290+
uint8_t SAFETY_TIMER:1;
291+
};
292+
uint8_t val;
293+
} MP2629_REG17;
294+
295+
static_assert(sizeof(MP2629_REG17) == 1, "MP2629_REG17 union size is incorrect, should be 1 byte.");
296+
297+
typedef union {
298+
struct {
299+
uint8_t RSVD4_0:5;
300+
uint8_t ADDRESS:1;
301+
uint8_t RSVD7:1;
302+
uint8_t IINLIM_VINMIN_RESET_EN:1;
303+
};
304+
uint8_t val;
305+
} MP2629_REG18;
306+
307+
static_assert(sizeof(MP2629_REG18) == 1, "MP2629_REG18 union size is incorrect, should be 1 byte.");
308+
309+
310+
#define MP2629_ADDRESS 0x4B
311+
#define MP2629_REG00_ADDRESS 0x00
312+
#define MP2629_REG01_ADDRESS 0x01
313+
#define MP2629_REG02_ADDRESS 0x02
314+
#define MP2629_REG03_ADDRESS 0x03
315+
#define MP2629_REG04_ADDRESS 0x04
316+
#define MP2629_REG05_ADDRESS 0x05
317+
#define MP2629_REG06_ADDRESS 0x06
318+
#define MP2629_REG07_ADDRESS 0x07
319+
#define MP2629_REG08_ADDRESS 0x08
320+
#define MP2629_REG09_ADDRESS 0x09
321+
#define MP2629_REG0A_ADDRESS 0x0A
322+
#define MP2629_REG0B_ADDRESS 0x0B
323+
#define MP2629_REG0C_ADDRESS 0x0C
324+
#define MP2629_REG0D_ADDRESS 0x0D
325+
#define MP2629_REG0E_ADDRESS 0x0E
326+
#define MP2629_REG0F_ADDRESS 0x0F
327+
#define MP2629_REG0G_ADDRESS 0x0G
328+
#define MP2629_REG10_ADDRESS 0x10
329+
#define MP2629_REG11_ADDRESS 0x11
330+
#define MP2629_REG12_ADDRESS 0x12
331+
#define MP2629_REG13_ADDRESS 0x13
332+
#define MP2629_REG14_ADDRESS 0x14
333+
#define MP2629_REG15_ADDRESS 0x15
334+
#define MP2629_REG16_ADDRESS 0x16
335+
#define MP2629_REG17_ADDRESS 0x17
336+
#define MP2629_REG18_ADDRESS 0x18
337+
338+
339+
#ifdef __cplusplus
340+
} // extern "C"
341+
#endif

‎cores/arduino/PMICClass.cpp

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
PMIC.cpp - initialization of Power Management ICs
3+
Copyright (c) 2020 Kevin P. Fleming. All right reserved.
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
This library is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+
Lesser General Public License for more details.
12+
You should have received a copy of the GNU Lesser General Public
13+
License along with this library; if not, write to the Free Software
14+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
17+
#include "PMICClass.h"
18+
19+
PMICClass::PMICClass(void) {
20+
}
21+
22+
PMICClass::~PMICClass(void) {
23+
}
24+
25+
26+
void PMICClass::init(SERCOM * sercom) {
27+
_sercom = sercom;
28+
}
29+
30+
void PMICClass::setupBQ24195(bool batteryPresent, bool USBDetect) {
31+
BQ24195_REG00 reg00;
32+
reg00.IINLIM = _ilim; // input current limit 500 mA
33+
reg00.VINDPM = 0x00; // input voltage limit 3.88V
34+
reg00.EN_HIZ = 0x00; // disable
35+
36+
writereg(BQ24195_ADDRESS, BQ24195_REG00_ADDRESS, (reg00.val));
37+
38+
BQ24195_REG01 reg01;
39+
reg01.RSVD = 0x01;
40+
reg01.SYS_MIN = 0x05; // minimum system voltage 3.5V
41+
reg01.CHG_CONFIG_ENABLE = (batteryPresent ? 0x01 : 0x00); // battery charge enable/disable
42+
reg01.CHG_CONFIG_OTG = 0x00;
43+
reg01.WATCHDOG_TIMER_RESET = 0x01; // reset watchdog timer
44+
reg01.REGISTER_RESET = 0x00; // keep current register setting
45+
46+
writereg(BQ24195_ADDRESS, BQ24195_REG01_ADDRESS, (reg01.val));
47+
48+
BQ24195_REG05 reg05;
49+
reg05.RSVD = 0x00;
50+
reg05.CHG_TIMER = 0x01; // fast charge timer 8 hours
51+
reg05.EN_TIMER = (batteryPresent ? 0x01 : 0x00); // enable/disable charge safety timer
52+
reg05.WATCHDOG = 0x00; // disable watchdog timer to stay in host mode
53+
reg05.TERM_STAT = 0x00; // charge termination indicator match ITERM
54+
reg05.EN_TERM = 0x01; // enable charge termination
55+
56+
writereg(BQ24195_ADDRESS, BQ24195_REG05_ADDRESS, (reg05.val));
57+
58+
BQ24195_REG07 reg07;
59+
reg07.INT_MASK_BAT = 0x01; // INT on battery fault
60+
reg07.INT_MASK_CHG = 0x01; // INT on charge fault
61+
reg07.RSVD = 0x02;
62+
reg07.BATFET_DISABLE = (batteryPresent ? 0x00: 0x01); // battery FET enable/disable
63+
reg07.TMR2X_EN = 0x00; // safety timer not slowed by 2X
64+
reg07.DPDM_EN = 0x00; // D+/D- detection enable/disable
65+
66+
writereg(BQ24195_ADDRESS, BQ24195_REG07_ADDRESS, (reg07.val));
67+
68+
BQ24195_REG04 reg04;
69+
reg04.VRECHG = 0x2C;
70+
reg04.BATLOWV = 0x01;
71+
reg04.VREG = 0x01;
72+
writereg(BQ24195_ADDRESS, BQ24195_REG04_ADDRESS, (reg04.val));
73+
}
74+
75+
void PMICClass::setupMP2629(bool batteryPresent) {
76+
// disable or enable battery bat feet
77+
MP2629_REG0A reg0A;
78+
uint8_t byte = readFrom(MP2629_ADDRESS, MP2629_REG0A_ADDRESS);
79+
reg0A.TDISC_L = byte & 0x03;
80+
reg0A.TDISC_H = (byte & 0x0C) >> 2;
81+
reg0A.SYSRST_SEL = (byte & 0x10) >> 5;
82+
reg0A.BATFET_DIS = (batteryPresent ? 0b0 : 0b1);
83+
reg0A.TMR2X_EN = (byte & 0x40) >> 6;
84+
reg0A.SW_FREQ = byte >> 7;
85+
writereg(MP2629_ADDRESS, MP2629_REG0A_ADDRESS, reg0A.val);
86+
delay(300);
87+
88+
// disable watchdog timer reset
89+
byte = readFrom(MP2629_ADDRESS, MP2629_REG08_ADDRESS);
90+
MP2629_REG08 reg08;
91+
reg08.EN_TIMER = byte & 0x01;
92+
reg08.CHG_TMR = (byte & 0x06) >> 1;
93+
reg08.WATCHDOG_TIM_RST = 0;
94+
reg08.WATCHDOG = (byte & 0x30) >> 4;
95+
reg08.RSVD = (byte & 0x40) >> 6;
96+
reg08.EN_TIMER = byte >> 7;
97+
writereg(MP2629_ADDRESS, MP2629_REG08_ADDRESS, reg08.val);
98+
99+
MP2629_REG0B reg0B;
100+
reg0B.RSVD = byte & 0x3F;
101+
reg0B.USB_DET_EN = 1;
102+
reg0B.INT_MASK = 1;
103+
writereg(MP2629_ADDRESS, MP2629_REG0B_ADDRESS, reg0B.val);
104+
105+
// set ICC
106+
byte = readFrom(MP2629_ADDRESS, MP2629_REG05_ADDRESS);
107+
MP2629_REG05 reg05;
108+
reg05.ICC = 0x05;
109+
reg05.VBATT_PRE = byte >> 7;
110+
writereg(MP2629_ADDRESS, MP2629_REG05_ADDRESS, reg05.val);
111+
112+
// set the vbat voltage to 4.1 V
113+
byte = readFrom(MP2629_ADDRESS, MP2629_REG07_ADDRESS);
114+
MP2629_REG07 reg07;
115+
reg07.VRECH = byte & 0x01;
116+
reg07.VBATT_REG = 0x46;//set vbat charge threshold to 4.1 V
117+
writereg(MP2629_ADDRESS, MP2629_REG07_ADDRESS, reg07.val);
118+
}
119+
120+
bool PMICClass::isBatteryConnected() {
121+
// reset bat feet to default value
122+
MP2629_REG0A reg0A;
123+
uint8_t byte = readFrom(MP2629_ADDRESS, MP2629_REG0A_ADDRESS);
124+
reg0A.TDISC_L = byte & 0x03;
125+
reg0A.TDISC_H = (byte & 0x0C) >> 2;
126+
reg0A.SYSRST_SEL = (byte & 0x10) >> 5;
127+
reg0A.BATFET_DIS = 0;
128+
reg0A.TMR2X_EN = (byte & 0x40) >> 6;
129+
reg0A.SW_FREQ = byte >> 7;
130+
writereg(MP2629_ADDRESS, MP2629_REG0A_ADDRESS, reg0A.val);
131+
132+
133+
MP2629_REG03 reg03;
134+
// set MP2'S ADC in CONTINUOS acquision mode
135+
byte = readFrom(MP2629_ADDRESS, MP2629_REG03_ADDRESS);
136+
reg03.IIN_DSCHG = (byte & 0x07);
137+
reg03.VIN_DSCHG = (byte & 0x56) >> 3;
138+
reg03.ADC_RATE = 1;
139+
reg03.ADC_START = byte >> 7;
140+
writereg(MP2629_ADDRESS, MP2629_REG03_ADDRESS, reg03.val);
141+
delay(10);
142+
143+
return readFrom(MP2629_ADDRESS, MP2629_REG12_ADDRESS) > 0;
144+
}
145+
146+
bool PMICClass::isBQ24195() {
147+
return (readFrom(BQ24195_ADDRESS, BQ24195_REG0A_ADDRESS) == 0x23);
148+
}
149+
150+
void PMICClass::setIlim(uint8_t ilim){
151+
_ilim = ilim;
152+
}
153+
154+
uint8_t PMICClass::readFrom(uint8_t pmicAddress, uint8_t address) {
155+
uint8_t readedValue = 0;
156+
157+
_sercom->startTransmissionWIRE(pmicAddress, WIRE_WRITE_FLAG);
158+
_sercom->sendDataMasterWIRE(address);
159+
_sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
160+
161+
if (_sercom->startTransmissionWIRE(pmicAddress, WIRE_READ_FLAG))
162+
{
163+
readedValue = _sercom->readDataWIRE();
164+
_sercom->prepareNackBitWIRE();
165+
_sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
166+
}
167+
return readedValue;
168+
}
169+
170+
void PMICClass::writereg(uint8_t pmicAddress, uint8_t address, uint8_t value) {
171+
_sercom->startTransmissionWIRE(pmicAddress, WIRE_WRITE_FLAG );
172+
_sercom->sendDataMasterWIRE(address);
173+
_sercom->sendDataMasterWIRE(value);
174+
_sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
175+
}
176+
177+
PMICClass PMICArduino;

‎cores/arduino/PMICClass.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
PMIC.h - initialization of Power Management ICs
3+
Copyright (c) 2020 Kevin P. Fleming. All right reserved.
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
This library is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+
Lesser General Public License for more details.
12+
You should have received a copy of the GNU Lesser General Public
13+
License along with this library; if not, write to the Free Software
14+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
#ifndef _PMIC_ARDUINO_H_
17+
#define _PMIC_ARDUINO_H_
18+
19+
#include "Arduino.h"
20+
#include "PMIC/BQ24195.h"
21+
#include "PMIC/MP2629.h"
22+
#include "wiring_private.h"
23+
24+
#define ILIM_100MA 0x00
25+
#define ILIM_150MA 0x01
26+
#define ILIM_500MA 0x02
27+
#define ILIM_900MA 0x03
28+
#define ILIM_1_2A 0x04
29+
#define ILIM_1_5A 0x05
30+
#define ILIM_2_0A 0x06
31+
#define ILIM_3_0A 0x07
32+
33+
34+
35+
36+
class PMICClass
37+
{
38+
public:
39+
PMICClass(void);
40+
~PMICClass(void);
41+
void init(SERCOM * sercom);
42+
void setupBQ24195(bool batteryPresent, bool USBDetect);
43+
void setupMP2629(bool batteryPresent);
44+
bool isBatteryConnected();
45+
bool isBQ24195();
46+
void setIlim(uint8_t ilim = ILIM_500MA);
47+
private:
48+
uint8_t readFrom(uint8_t pmicAdd, uint8_t address);
49+
void writereg(uint8_t pmicAdd, uint8_t address, uint8_t value);
50+
private:
51+
SERCOM * _sercom;
52+
uint8_t _ilim = ILIM_500MA;
53+
};
54+
55+
extern PMICClass PMICArduino;
56+
#endif

‎variants/mkrwifi1010/variant.cpp

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -177,60 +177,39 @@ SERCOM sercom3(SERCOM3);
177177
SERCOM sercom4(SERCOM4);
178178
SERCOM sercom5(SERCOM5);
179179

180-
#if defined(USE_BQ24195L_PMIC)
181-
180+
#ifdef USE_BQ24195L_PMIC
181+
#include "PMICClass.h"
182182
#include "wiring_private.h"
183+
#endif
183184

184-
#define PMIC_ADDRESS 0x6B
185-
#define PMIC_REG01 0x01
186-
#define PMIC_REG07 0x07
185+
void initVariant() {
187186

188-
static inline void enable_battery_charging() {
187+
#if defined(USE_BQ24195L_PMIC) or defined(USE_MP2629_PMIC)
189188
PERIPH_WIRE.initMasterWIRE(100000);
190189
PERIPH_WIRE.enableWIRE();
191190
pinPeripheral(PIN_WIRE_SDA, g_APinDescription[PIN_WIRE_SDA].ulPinType);
192191
pinPeripheral(PIN_WIRE_SCL, g_APinDescription[PIN_WIRE_SCL].ulPinType);
193192

194-
PERIPH_WIRE.startTransmissionWIRE( PMIC_ADDRESS, WIRE_WRITE_FLAG );
195-
PERIPH_WIRE.sendDataMasterWIRE(PMIC_REG01);
196-
PERIPH_WIRE.sendDataMasterWIRE(0x1B); // Charge Battery + Minimum System Voltage 3.5V
197-
PERIPH_WIRE.prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
193+
PMICArduino.init(&PERIPH_WIRE);
198194

199-
PERIPH_WIRE.disableWIRE();
200-
}
195+
if(PMICArduino.isBQ24195()){// USE_BQ24195L_PMIC
196+
pinMode(ADC_BATTERY, OUTPUT);
197+
digitalWrite(ADC_BATTERY, LOW);
198+
delay(10);
199+
pinMode(ADC_BATTERY, INPUT);
200+
delay(100);
201201

202-
static inline void disable_battery_fet(bool disabled) {
203-
PERIPH_WIRE.initMasterWIRE(100000);
204-
PERIPH_WIRE.enableWIRE();
205-
pinPeripheral(PIN_WIRE_SDA, g_APinDescription[PIN_WIRE_SDA].ulPinType);
206-
pinPeripheral(PIN_WIRE_SCL, g_APinDescription[PIN_WIRE_SCL].ulPinType);
207-
208-
PERIPH_WIRE.startTransmissionWIRE( PMIC_ADDRESS, WIRE_WRITE_FLAG );
209-
PERIPH_WIRE.sendDataMasterWIRE(PMIC_REG07);
210-
// No D+/D– detection + Safety timer not slowed by 2X during input DPM or thermal regulation +
211-
// BAT fet disabled/enabled + charge and bat fault INT
212-
PERIPH_WIRE.sendDataMasterWIRE(0x0B | (disabled ? 0x20 : 0x00));
213-
PERIPH_WIRE.prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
202+
bool batteryConnected = analogRead(ADC_BATTERY) > 600;
214203

204+
PMICArduino.setupBQ24195(batteryConnected, false);
205+
} else {;
206+
bool batteryConnected = PMICArduino.isBatteryConnected();
207+
PMICArduino.setupMP2629(batteryConnected);
208+
}
215209
PERIPH_WIRE.disableWIRE();
216-
}
217-
218210
#endif
219211

220-
void initVariant() {
221-
#if defined(USE_BQ24195L_PMIC)
222-
pinMode(ADC_BATTERY, OUTPUT);
223-
digitalWrite(ADC_BATTERY, LOW);
224-
delay(10);
225-
pinMode(ADC_BATTERY, INPUT);
226-
delay(100);
227-
228-
bool batteryPresent = analogRead(ADC_BATTERY) > 600;
229-
if (batteryPresent) {
230-
enable_battery_charging();
231-
}
232-
disable_battery_fet(!batteryPresent);
233-
#endif
212+
234213

235214
// NINA - SPI boot
236215
pinMode(NINA_GPIO0, OUTPUT);

0 commit comments

Comments
 (0)
Please sign in to comment.