Skip to content

Commit 317f2a2

Browse files
nmoriEeeeBin
authored andcommitted
Add:power related functions (#160)
* Addition: Shutdown time setting * Add a function to change the time setting register * Add maximum time (64s) setting at initialization  (If you prefer short time settings, set them yourself after initialization) * Add : powerOFF function * Fix : Adjusted function name *setLowCurrentShutdownTime -> setLowPowerShutdownTime *SleepTime -> ShutdownTime *SLEEP_xxS -> SHUTDOWN_xxS Add : powerOFF function * fix:Detailed setting of wakeup factor If you set the wakeup time, it will be reflected incorrectly even when it is not needed. * modify : Exclude functions that don't work properly *setLowPowerShutdown() -> Add attribute *setKeepLightLoad() -> Add attribute * add : add Link *Add a reference to the official document * Modify sleep.ino comment
1 parent fb3453a commit 317f2a2

File tree

6 files changed

+162
-27
lines changed

6 files changed

+162
-27
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ https://github.com/m5stack/M5Stack/tree/master/examples
2525

2626
https://github.com/m5stack/M5Stack/blob/master/src/M5Stack.h#L19
2727

28+
https://docs.m5stack.com/#/en/api
29+
2830
## 4. H/W Reference
2931

3032
#### Pinout

docs/getting_started_cn.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ https://github.com/m5stack/M5Stack/tree/master/examples
2121

2222
https://github.com/m5stack/M5Stack/blob/master/src/M5Stack.h#L19
2323

24+
https://docs.m5stack.com/#/zh_CN/api
25+
2426
## 4. H/W 参考
2527

2628
#### 管脚映射

docs/getting_started_ja.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ https://github.com/m5stack/M5Stack/tree/master/examples
2525

2626
https://github.com/m5stack/M5Stack/blob/master/src/M5Stack.h#L19
2727

28+
https://docs.m5stack.com/#/ja/api
29+
30+
2831
## 4. ハードウェア仕様
2932

3033
#### I/Oインタフェイス

examples/Basics/Sleep/Sleep.ino

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,22 @@ void loop() {
2020
M5.Lcd.printf("<<Sleep test>>\n");
2121
M5.Lcd.printf("power-on triggered at:%s%s\n\n",c?"POWER-SW":"",d?"DeepSleep-end":"");
2222

23-
M5.Lcd.printf("Go lightSleep (5s or press buttonA)\n");
23+
M5.Lcd.printf("Go lightSleep (5s or press buttonA wake up)\n");
24+
delay(2500);
25+
// call this fun, power btn will Invalid
26+
// Restore power btn please call M5.Power.setPowerBoostKeepOn(false)
27+
M5.Power.lightSleep(SLEEP_SEC(5));
28+
29+
M5.Lcd.printf("Go lightSleep (press buttonA wake up)\n");
2430
delay(2500);
2531
// call this fun, power btn will Invalid
2632
// Restore power btn please call M5.Power.setPowerBoostKeepOn(false)
2733
M5.Power.lightSleep(0);
2834

29-
M5.Lcd.printf("resume.\n\nGo deepSleep (5s or press buttonA) ");
35+
M5.Lcd.printf("resume.\n\nGo deepSleep (press buttonA wake up) ");
3036
delay(2500);
3137
// call this fun, power btn will Invalid
38+
// Restore power btn please call M5.Power.setPowerBoostKeepOn(false)
3239
M5.Power.deepSleep(0);
3340

3441
}

src/utility/Power.cpp

Lines changed: 122 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,38 @@
99
#include "../M5Stack.h"
1010
#include <rom/rtc.h>
1111
#include <esp_sleep.h>
12+
#include <esp_bt_main.h>
13+
#include <esp_wifi.h>
1214

1315
// ================ Power IC IP5306 ===================
1416
#define IP5306_ADDR (117) // 0x75
1517
#define IP5306_REG_SYS_CTL0 (0x00)
1618
#define IP5306_REG_SYS_CTL1 (0x01)
19+
#define IP5306_REG_SYS_CTL2 (0x02)
1720
#define IP5306_REG_READ0 (0x70)
1821
#define IP5306_REG_READ1 (0x71)
1922
#define IP5306_REG_READ3 (0x78)
2023

2124
//- REG_CTL0
22-
#define BOOST_ENABLET_BIT (0x20)
25+
#define BOOST_ENABLE_BIT (0x20)
2326
#define CHARGE_OUT_BIT (0x10)
2427
#define BOOT_ON_LOAD_BIT (0x04)
2528
#define BOOST_OUT_BIT (0x02)
29+
#define BOOST_BUTTON_EN_BIT (0x01)
2630

2731
//- REG_CTL1
2832
#define BOOST_SET_BIT (0x80)
2933
#define WLED_SET_BIT (0x40)
30-
#define BOOST_ENABLE_BIT (0x20)
34+
#define SHORT_BOOST_BIT (0x20)
3135
#define VIN_ENABLE_BIT (0x04)
3236

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+
3344
//- REG_READ0
3445
#define CHARGE_ENABLE_BIT (0x08)
3546

@@ -46,9 +57,12 @@ POWER::POWER() {
4657
}
4758

4859
void POWER::begin() {
60+
61+
//Initial I2C
4962
Wire.begin(21, 22);
5063
}
5164

65+
5266
static bool getI2CReg(uint8_t *result, uint8_t address, uint8_t *reg) {
5367
return (M5.I2C.readByte(address, *reg, result));
5468
}
@@ -68,7 +82,7 @@ bool POWER::setPowerBoostOnOff(bool en) {
6882
bool POWER::setPowerBoostSet(bool en) {
6983
uint8_t data;
7084
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)));
7286
}
7387
return false;
7488
}
@@ -92,7 +106,34 @@ bool POWER::setPowerWLEDSet(bool en) {
92106
bool POWER::setPowerBtnEn(bool en) {
93107
uint8_t data;
94108
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;
96137
}
97138
return false;
98139
}
@@ -101,8 +142,11 @@ bool POWER::setPowerBtnEn(bool en) {
101142
default: false
102143
false: when the current is too small, ip5306 will automatically shut down
103144
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.
104147
*/
105-
bool POWER::setKeepLightLoad(bool en) {
148+
bool POWER::setKeepLightLoad(bool en)
149+
{
106150
// uint8_t data;
107151
// if (M5.I2C.readByte(IP5306_ADDR, IP5306_REG_SYS_CTL0, &data) == true) {
108152
// 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) {
119163
return false;
120164
}
121165

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);
129177
}
130178
/*
131179
default: true
@@ -200,17 +248,18 @@ void POWER::reset() {
200248
bool POWER::isResetbySoftware() {
201249
RESET_REASON reset_reason = rtc_get_reset_reason(0);
202250
return (reset_reason == SW_RESET ||
203-
reset_reason == SW_CPU_RESET);
251+
reset_reason == SW_CPU_RESET);
204252
}
205253

206254
bool POWER::isResetbyWatchdog() {
207255
RESET_REASON reset_reason = rtc_get_reset_reason(0);
208256
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);
214263
}
215264

216265
bool POWER::isResetbyDeepsleep() {
@@ -223,9 +272,14 @@ bool POWER::isResetbyPowerSW() {
223272
return (reset_reason == POWERON_RESET);
224273
}
225274

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){
227280

228281
// Keep power keep boost on
282+
setLowPowerShutdown(false);
229283
setPowerBoostKeepOn(true);
230284

231285
// power off the Lcd
@@ -235,13 +289,23 @@ void POWER::deepSleep(uint64_t time_in_us) {
235289
// ESP32 into deep sleep
236290
esp_sleep_enable_ext0_wakeup((gpio_num_t)_wakeupPin, LOW);
237291

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+
238298
while (digitalRead(_wakeupPin) == LOW) {
239299
delay(10);
240300
}
241301

242302
(time_in_us == 0) ? esp_deep_sleep_start() : esp_deep_sleep(time_in_us);
243303
}
244304

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.
245309
void POWER::lightSleep(uint64_t time_in_us) {
246310

247311
// Keep power keep boost on
@@ -258,12 +322,50 @@ void POWER::lightSleep(uint64_t time_in_us) {
258322
while (digitalRead(_wakeupPin) == LOW) {
259323
delay(10);
260324
}
261-
if (time_in_us > 0) {
325+
if (time_in_us > 0){
262326
esp_sleep_enable_timer_wakeup(time_in_us);
327+
}else{
328+
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
263329
}
264330
esp_light_sleep_start();
265331

266332
// power on the Lcd
267333
M5.Lcd.wakeup();
268334
M5.Lcd.setBrightness(200);
269335
}
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+
}

src/utility/Power.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,33 @@
1010
#include <Arduino.h>
1111
#include <Wire.h>
1212

13-
class POWER {
13+
#define SLEEP_MSEC(us) (((uint64_t)us) * 1000L)
14+
#define SLEEP_SEC(us) (((uint64_t)us) * 1000000L)
15+
#define SLEEP_MIN(us) (((uint64_t)us) * 60L * 1000000L)
16+
#define SLEEP_HR(us) (((uint64_t)us) * 60L * 60L * 1000000L)
17+
18+
class POWER
19+
{
1420
public:
1521
POWER();
1622
bool canControl();
1723
void begin();
1824

25+
// -- ShutdownTimeParam
26+
enum ShutdownTime
27+
{
28+
SHUTDOWN_8S = 0,
29+
SHUTDOWN_16S,
30+
SHUTDOWN_32S,
31+
SHUTDOWN_64S
32+
};
33+
1934
// -- control for power
20-
bool setKeepLightLoad(bool en);
35+
bool setKeepLightLoad(bool en) __attribute__((deprecated));
2136
bool setPowerBoostKeepOn(bool en);
2237
bool setAutoBootOnLoad(bool en);
23-
bool setLowPowerShutdown(bool en);
38+
bool setLowPowerShutdown(bool en) __attribute__((deprecated));
39+
bool setLowPowerShutdownTime(ShutdownTime time);
2440
bool setPowerBoostOnOff(bool en);
2541
bool setPowerBoostSet(bool en);
2642
bool setPowerVin(bool en);
@@ -44,8 +60,11 @@
4460
bool isResetbyPowerSW();
4561

4662
// -- sleep
47-
void deepSleep(uint64_t time_in_us=0);
48-
void lightSleep(uint64_t time_in_us=0);
63+
void deepSleep(uint64_t time_in_us = 0);
64+
void lightSleep(uint64_t time_in_us = 0);
65+
66+
// -- power off
67+
void powerOFF();
4968

5069
// -- software reset
5170
void reset();

0 commit comments

Comments
 (0)