9
9
#include " ../M5Stack.h"
10
10
#include < rom/rtc.h>
11
11
#include < esp_sleep.h>
12
+ #include < esp_bt_main.h>
13
+ #include < esp_wifi.h>
12
14
13
15
// ================ Power IC IP5306 ===================
14
16
#define IP5306_ADDR (117 ) // 0x75
15
17
#define IP5306_REG_SYS_CTL0 (0x00 )
16
18
#define IP5306_REG_SYS_CTL1 (0x01 )
19
+ #define IP5306_REG_SYS_CTL2 (0x02 )
17
20
#define IP5306_REG_READ0 (0x70 )
18
21
#define IP5306_REG_READ1 (0x71 )
19
22
#define IP5306_REG_READ3 (0x78 )
20
23
21
24
// - REG_CTL0
22
- #define BOOST_ENABLET_BIT (0x20 )
25
+ #define BOOST_ENABLE_BIT (0x20 )
23
26
#define CHARGE_OUT_BIT (0x10 )
24
27
#define BOOT_ON_LOAD_BIT (0x04 )
25
28
#define BOOST_OUT_BIT (0x02 )
29
+ #define BOOST_BUTTON_EN_BIT (0x01 )
26
30
27
31
// - REG_CTL1
28
32
#define BOOST_SET_BIT (0x80 )
29
33
#define WLED_SET_BIT (0x40 )
30
- #define BOOST_ENABLE_BIT (0x20 )
34
+ #define SHORT_BOOST_BIT (0x20 )
31
35
#define VIN_ENABLE_BIT (0x04 )
32
36
37
+ // - REG_CTL2
38
+ #define SHUTDOWNTIME_MASK (0x0c )
39
+ #define SHUTDOWNTIME_64S (0x0c )
40
+ #define SHUTDOWNTIME_32S (0x04 )
41
+ #define SHUTDOWNTIME_16S (0x08 )
42
+ #define SHUTDOWNTIME_8S (0x00 )
43
+
33
44
// - REG_READ0
34
45
#define CHARGE_ENABLE_BIT (0x08 )
35
46
@@ -46,9 +57,12 @@ POWER::POWER() {
46
57
}
47
58
48
59
void POWER::begin () {
60
+
61
+ // Initial I2C
49
62
Wire.begin (21 , 22 );
50
63
}
51
64
65
+
52
66
static bool getI2CReg (uint8_t *result, uint8_t address, uint8_t *reg) {
53
67
return (M5.I2C .readByte (address, *reg, result));
54
68
}
@@ -68,7 +82,7 @@ bool POWER::setPowerBoostOnOff(bool en) {
68
82
bool POWER::setPowerBoostSet (bool en) {
69
83
uint8_t data;
70
84
if (M5.I2C .readByte (IP5306_ADDR, IP5306_REG_SYS_CTL1, &data) == true ) {
71
- return M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL1, en ? (data | BOOST_ENABLE_BIT ) : (data & (~BOOST_ENABLE_BIT )));
85
+ return M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL1, en ? (data | SHORT_BOOST_BIT ) : (data & (~SHORT_BOOST_BIT )));
72
86
}
73
87
return false ;
74
88
}
@@ -92,7 +106,34 @@ bool POWER::setPowerWLEDSet(bool en) {
92
106
bool POWER::setPowerBtnEn (bool en) {
93
107
uint8_t data;
94
108
if (M5.I2C .readByte (IP5306_ADDR, IP5306_REG_SYS_CTL0, &data) == true ) {
95
- return M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL0, en ? (data | 0x01 ) : (data & (~0x01 )));
109
+ return M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL0, en ? (data | BOOST_BUTTON_EN_BIT) : (data & (~BOOST_BUTTON_EN_BIT)));
110
+ }
111
+ return false ;
112
+ }
113
+
114
+ bool POWER::setLowPowerShutdownTime (ShutdownTime time)
115
+ {
116
+ uint8_t data;
117
+ bool ret;
118
+ if (M5.I2C .readByte (IP5306_ADDR, IP5306_REG_SYS_CTL2, &data) == true ){
119
+ switch (time){
120
+ case ShutdownTime::SHUTDOWN_8S:
121
+ ret = M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL2, ((data & (~SHUTDOWNTIME_MASK)) | SHUTDOWNTIME_8S));
122
+ break ;
123
+ case ShutdownTime::SHUTDOWN_16S:
124
+ ret = M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL2, ((data & (~SHUTDOWNTIME_MASK)) | SHUTDOWNTIME_16S));
125
+ break ;
126
+ case ShutdownTime::SHUTDOWN_32S:
127
+ ret = M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL2, ((data & (~SHUTDOWNTIME_MASK)) | SHUTDOWNTIME_32S));
128
+ break ;
129
+ case ShutdownTime::SHUTDOWN_64S:
130
+ ret = M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL2, ((data & (~SHUTDOWNTIME_MASK)) | SHUTDOWNTIME_64S));
131
+ break ;
132
+ default :
133
+ ret = false ;
134
+ break ;
135
+ }
136
+ return ret;
96
137
}
97
138
return false ;
98
139
}
@@ -101,8 +142,11 @@ bool POWER::setPowerBtnEn(bool en) {
101
142
default: false
102
143
false: when the current is too small, ip5306 will automatically shut down
103
144
note: it seem not work and has problems
145
+ Function has disabled.(Stab for compatibility)
146
+ This function will be removed in a future release.
104
147
*/
105
- bool POWER::setKeepLightLoad (bool en) {
148
+ bool POWER::setKeepLightLoad (bool en)
149
+ {
106
150
// uint8_t data;
107
151
// if (M5.I2C.readByte(IP5306_ADDR, IP5306_REG_SYS_CTL0, &data) == true) {
108
152
// return M5.I2C.writeByte(IP5306_ADDR, IP5306_REG_SYS_CTL0, !en ? (data | LIGHT_LOAD_BIT) : (data & (~LIGHT_LOAD_BIT)));
@@ -119,13 +163,17 @@ bool POWER::setPowerBoostKeepOn(bool en) {
119
163
return false ;
120
164
}
121
165
122
- // true: if come low battery , the system going shutdown
123
- bool POWER::setLowPowerShutdown (bool en) {
124
- uint8_t data;
125
- if (M5.I2C .readByte (IP5306_ADDR, IP5306_REG_SYS_CTL1, &data) == true ) {
126
- return M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL1, en ? (data | LOWPOWER_SHUTDOWN_BIT) : (data & (~LOWPOWER_SHUTDOWN_BIT)));
127
- }
128
- return false ;
166
+ /* *
167
+ * Function has disabled.(Stab for compatibility)
168
+ * This function will be removed in a future release.
169
+ */
170
+ bool POWER::setLowPowerShutdown (bool en)
171
+ {
172
+ // uint8_t data;
173
+ // if (M5.I2C.readByte(IP5306_ADDR, IP5306_REG_SYS_CTL1, &data) == true) {
174
+ // return M5.I2C.writeByte(IP5306_ADDR, IP5306_REG_SYS_CTL1, en ? (data | LOWPOWER_SHUTDOWN_BIT) : (data & (~LOWPOWER_SHUTDOWN_BIT)));
175
+ // }
176
+ return setPowerBoostKeepOn (!en);
129
177
}
130
178
/*
131
179
default: true
@@ -200,17 +248,18 @@ void POWER::reset() {
200
248
bool POWER::isResetbySoftware () {
201
249
RESET_REASON reset_reason = rtc_get_reset_reason (0 );
202
250
return (reset_reason == SW_RESET ||
203
- reset_reason == SW_CPU_RESET);
251
+ reset_reason == SW_CPU_RESET);
204
252
}
205
253
206
254
bool POWER::isResetbyWatchdog () {
207
255
RESET_REASON reset_reason = rtc_get_reset_reason (0 );
208
256
return (reset_reason == TG0WDT_SYS_RESET ||
209
- reset_reason == TG1WDT_SYS_RESET ||
210
- reset_reason == OWDT_RESET ||
211
- reset_reason == RTCWDT_CPU_RESET ||
212
- reset_reason == RTCWDT_RTC_RESET ||
213
- reset_reason == TGWDT_CPU_RESET);
257
+ reset_reason == TG1WDT_SYS_RESET ||
258
+ reset_reason == OWDT_RESET ||
259
+ reset_reason == RTCWDT_SYS_RESET ||
260
+ reset_reason == RTCWDT_CPU_RESET ||
261
+ reset_reason == RTCWDT_RTC_RESET ||
262
+ reset_reason == TGWDT_CPU_RESET);
214
263
}
215
264
216
265
bool POWER::isResetbyDeepsleep () {
@@ -223,9 +272,14 @@ bool POWER::isResetbyPowerSW() {
223
272
return (reset_reason == POWERON_RESET);
224
273
}
225
274
226
- void POWER::deepSleep (uint64_t time_in_us) {
275
+ // note:
276
+ // If the IP5306 I2C communication is not available,
277
+ // such as the old model, there is a limit to the maximum time for sleep return.
278
+ // When using this function, pay attention to the constraints.
279
+ void POWER::deepSleep (uint64_t time_in_us){
227
280
228
281
// Keep power keep boost on
282
+ setLowPowerShutdown (false );
229
283
setPowerBoostKeepOn (true );
230
284
231
285
// power off the Lcd
@@ -235,13 +289,23 @@ void POWER::deepSleep(uint64_t time_in_us) {
235
289
// ESP32 into deep sleep
236
290
esp_sleep_enable_ext0_wakeup ((gpio_num_t )_wakeupPin, LOW);
237
291
292
+ if (time_in_us > 0 ){
293
+ esp_sleep_enable_timer_wakeup (time_in_us);
294
+ }else {
295
+ esp_sleep_disable_wakeup_source (ESP_SLEEP_WAKEUP_TIMER);
296
+ }
297
+
238
298
while (digitalRead (_wakeupPin) == LOW) {
239
299
delay (10 );
240
300
}
241
301
242
302
(time_in_us == 0 ) ? esp_deep_sleep_start () : esp_deep_sleep (time_in_us);
243
303
}
244
304
305
+ // note:
306
+ // If the IP5306 I2C communication is not available,
307
+ // such as the old model, there is a limit to the maximum time for sleep return.
308
+ // When using this function, pay attention to the constraints.
245
309
void POWER::lightSleep (uint64_t time_in_us) {
246
310
247
311
// Keep power keep boost on
@@ -258,12 +322,50 @@ void POWER::lightSleep(uint64_t time_in_us) {
258
322
while (digitalRead (_wakeupPin) == LOW) {
259
323
delay (10 );
260
324
}
261
- if (time_in_us > 0 ) {
325
+ if (time_in_us > 0 ){
262
326
esp_sleep_enable_timer_wakeup (time_in_us);
327
+ }else {
328
+ esp_sleep_disable_wakeup_source (ESP_SLEEP_WAKEUP_TIMER);
263
329
}
264
330
esp_light_sleep_start ();
265
331
266
332
// power on the Lcd
267
333
M5.Lcd .wakeup ();
268
334
M5.Lcd .setBrightness (200 );
269
335
}
336
+
337
+ // note:
338
+ // To ensure that the power is turned off,
339
+ // reduce the power consumption according to the specifications of the power supply IC.
340
+ // Otherwise, the power supply IC will continue to supply power.
341
+ void POWER::powerOFF (){
342
+ uint8_t data;
343
+ // power off the Lcd
344
+ M5.Lcd .setBrightness (0 );
345
+ M5.Lcd .sleep ();
346
+
347
+ // Power off request
348
+ if (M5.I2C .readByte (IP5306_ADDR, IP5306_REG_SYS_CTL1, &data) == true ){
349
+ M5.I2C .writeByte (IP5306_ADDR, IP5306_REG_SYS_CTL1, (data & (~BOOST_ENABLE_BIT)));
350
+ }
351
+
352
+ // stop wifi
353
+ esp_wifi_disconnect ();
354
+ esp_wifi_stop ();
355
+
356
+ // stop bt
357
+ esp_bluedroid_disable ();
358
+
359
+ // disable interrupt/peripheral
360
+ esp_sleep_disable_wakeup_source (ESP_SLEEP_WAKEUP_ALL);
361
+ gpio_deep_sleep_hold_dis ();
362
+
363
+ // Shutdown setting
364
+ setPowerBoostKeepOn (false );
365
+ setLowPowerShutdownTime (ShutdownTime::SHUTDOWN_8S);
366
+ setPowerBtnEn (true );
367
+
368
+
369
+ // wait shutdown from IP5306 (low-current shutdown)
370
+ esp_deep_sleep_start ();
371
+ }
0 commit comments