From f53d34d44ee035d0f1594c5fb7b1d86a394cc75d Mon Sep 17 00:00:00 2001 From: Borna Biro <43830307+BornaBiro@users.noreply.github.com> Date: Wed, 8 Nov 2023 15:10:36 +0100 Subject: [PATCH] Fixed deep sleep current on Inkplate 4 TEMPERA. --- ...e4TEMPERA_Accelerometer_Gyroscope_Read.ino | 3 + .../Inkplate4TEMPERA_BME688_Read.ino | 3 + .../Inkplate4TEMPERA_Fuel_Gauge.ino | 6 + .../Inkplate4TEMPERA_Image_Frame_Gesture.ino | 3 + src/boards/Inkplate4TEMPERA.cpp | 107 +++++++----------- src/boards/Inkplate4TEMPERA.h | 3 + src/include/Touch.cpp | 2 +- .../src/SparkFunBQ27441.cpp | 7 ++ .../src/SparkFunBQ27441.h | 3 + .../src/SparkFunLSM6DS3.cpp | 3 - 10 files changed, 71 insertions(+), 69 deletions(-) diff --git a/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_Accelerometer_Gyroscope_Read/Inkplate4TEMPERA_Accelerometer_Gyroscope_Read.ino b/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_Accelerometer_Gyroscope_Read/Inkplate4TEMPERA_Accelerometer_Gyroscope_Read.ino index 18c10ea7..4f5da38f 100644 --- a/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_Accelerometer_Gyroscope_Read/Inkplate4TEMPERA_Accelerometer_Gyroscope_Read.ino +++ b/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_Accelerometer_Gyroscope_Read/Inkplate4TEMPERA_Accelerometer_Gyroscope_Read.ino @@ -59,6 +59,9 @@ void setup() display.begin(); // Init Inkplate library (you should call this function ONLY ONCE) display.display(); // Put clear image on display + // Enable the accelerometer & gyroscope. + display.wakePeripheral(INKPLATE_ACCELEROMETER); + // Set text size to be 2x larger than default (5x7px) display.setTextSize(2); display.setTextColor(BLACK); // Set the text color to black also diff --git a/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_BME688_Read/Inkplate4TEMPERA_BME688_Read.ino b/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_BME688_Read/Inkplate4TEMPERA_BME688_Read.ino index 35c48792..6362c9b4 100644 --- a/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_BME688_Read/Inkplate4TEMPERA_BME688_Read.ino +++ b/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_BME688_Read/Inkplate4TEMPERA_BME688_Read.ino @@ -36,6 +36,9 @@ void setup() display.display(); // Put clear image on display display.setTextSize(3); // Set text to be 3 times bigger than classic 5x7 px text + // Enable the BME688 sensor. + display.wakePeripheral(INKPLATE_BME688); + display.bme688.begin(); // Init the sensor } diff --git a/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_Fuel_Gauge/Inkplate4TEMPERA_Fuel_Gauge.ino b/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_Fuel_Gauge/Inkplate4TEMPERA_Fuel_Gauge.ino index aaf0e37d..70409c73 100644 --- a/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_Fuel_Gauge/Inkplate4TEMPERA_Fuel_Gauge.ino +++ b/examples/Inkplate4TEMPERA/Advanced/Sensors/Inkplate4TEMPERA_Fuel_Gauge/Inkplate4TEMPERA_Fuel_Gauge.ino @@ -46,6 +46,12 @@ void setup() display.begin(); // Init Inkplate library (you should call this function ONLY ONCE) display.display(); // Put clear image on display + // Enable the Fuel Gauge. + // NOTE! + // Fuel Gauge is disabled by default. That will impact accuracy of the SoC (State of Charge). You can enable it, + // but it will have an impact on the deep sleep current (it will add additional 30-50uA). + display.wakePeripheral(INKPLATE_FUEL_GAUGE); + display.battery.begin(); // Init the fuel gauge // Note: You don't actually need to call display.battery.begin() to enable drawing power from the battery // Inkplate will do this automatically, this is just if you want to init the fuel gauge diff --git a/examples/Inkplate4TEMPERA/Projects/Inkplate4TEMPERA_Image_Frame_Gesture/Inkplate4TEMPERA_Image_Frame_Gesture.ino b/examples/Inkplate4TEMPERA/Projects/Inkplate4TEMPERA_Image_Frame_Gesture/Inkplate4TEMPERA_Image_Frame_Gesture.ino index c2257f2e..78c2f17d 100644 --- a/examples/Inkplate4TEMPERA/Projects/Inkplate4TEMPERA_Image_Frame_Gesture/Inkplate4TEMPERA_Image_Frame_Gesture.ino +++ b/examples/Inkplate4TEMPERA/Projects/Inkplate4TEMPERA_Image_Frame_Gesture/Inkplate4TEMPERA_Image_Frame_Gesture.ino @@ -64,6 +64,9 @@ void setup() display.setTextColor(BLACK); // Set text color to black display.setTextSize(5); // Scale text to be five times bigger then original (5x7 px) + // Enable the APDS9960 gesture sensor. + display.wakePeripheral(INKPLATE_APDS9960); + // Init SD card if (!display.sdCardInit()) { diff --git a/src/boards/Inkplate4TEMPERA.cpp b/src/boards/Inkplate4TEMPERA.cpp index f29ee2fa..267aa70a 100644 --- a/src/boards/Inkplate4TEMPERA.cpp +++ b/src/boards/Inkplate4TEMPERA.cpp @@ -88,27 +88,20 @@ bool Inkplate::begin(void) if (_beginDone == 1) return 0; + // Init Arduino Wire (i2C) library. Wire.begin(); - // Turn off the buzzer so it doesn't beep - digitalWriteInternal(IO_INT_ADDR, ioRegsInt, BUZZ_EN, HIGH); + // Init IO expander. + memset(ioRegsInt, 0, 22); + memset(ioRegsEx, 0, 22); + ioBegin(IO_INT_ADDR, ioRegsInt); + ioBegin(IO_EXT_ADDR, ioRegsEx); #ifndef ARDUINO_INKPLATECOLOR for (uint32_t i = 0; i < 256; ++i) pinLUT[i] = ((i & B00000011) << 4) | (((i & B00001100) >> 2) << 18) | (((i & B00010000) >> 4) << 23) | (((i & B11100000) >> 5) << 25); #endif - -#ifdef ARDUINO_ESP32_DEV - digitalWriteInternal(IO_INT_ADDR, ioRegsInt, 9, HIGH); -#else - digitalWriteInternal(IO_INT_ADDR, ioRegsInt, 9, LOW); -#endif - - memset(ioRegsInt, 0, 22); - memset(ioRegsEx, 0, 22); - ioBegin(IO_INT_ADDR, ioRegsInt); - ioBegin(IO_EXT_ADDR, ioRegsEx); pinModeInternal(IO_INT_ADDR, ioRegsInt, VCOM, OUTPUT); pinModeInternal(IO_INT_ADDR, ioRegsInt, PWRUP, OUTPUT); pinModeInternal(IO_INT_ADDR, ioRegsInt, WAKEUP, OUTPUT); @@ -148,28 +141,41 @@ bool Inkplate::begin(void) // Set the rest of the internal GPIO expander pins pinModeInternal(IO_INT_ADDR, ioRegsInt, INT_APDS, INPUT_PULLUP); // Gesture interrupt pin - pinModeInternal(IO_INT_ADDR, ioRegsInt, INT2_LSM, INPUT_PULLUP); // LSM interrupt pins - pinModeInternal(IO_INT_ADDR, ioRegsInt, INT1_LSM, INPUT_PULLUP); - pinModeInternal(IO_INT_ADDR, ioRegsInt, BUZZ_EN, OUTPUT); // Buzzer enable + // LSM interrupt pins. Pins must be set as inputs, since the default state of the INT pin on LSM is push-pull. + pinModeInternal(IO_INT_ADDR, ioRegsInt, INT2_LSM, INPUT); + pinModeInternal(IO_INT_ADDR, ioRegsInt, INT1_LSM, INPUT); + + // Turn off the buzzer so it doesn't beep + pinModeInternal(IO_INT_ADDR, ioRegsInt, BUZZ_EN, OUTPUT); digitalWriteInternal(IO_INT_ADDR, ioRegsInt, BUZZ_EN, HIGH); + // Disable microSD card. pinModeInternal(IO_INT_ADDR, ioRegsInt, SD_PMOS_PIN, OUTPUT); - digitalWriteInternal(IO_INT_ADDR, ioRegsInt, SD_PMOS_PIN, LOW); + digitalWriteInternal(IO_INT_ADDR, ioRegsInt, SD_PMOS_PIN, HIGH); + // Disable frontlight at start. pinModeInternal(IO_INT_ADDR, ioRegsInt, FRONTLIGHT_EN, OUTPUT); digitalWriteInternal(IO_INT_ADDR, ioRegsInt, FRONTLIGHT_EN, LOW); + // Disable touchscreen. pinModeInternal(TOUCHSCREEN_IO_EXPANDER, ioRegsEx, TOUCHSCREEN_EN, OUTPUT); digitalWriteInternal(TOUCHSCREEN_IO_EXPANDER, ioRegsEx, TOUCHSCREEN_EN, HIGH); + // Set Fuel Gauge GPOUT to input with pull up enabled. + pinModeInternal(IO_INT_ADDR, ioRegsInt, FG_GPOUT, INPUT_PULLUP); + + // Disable SPI pins on microSD card. + sdCardSleep(); + // Set the rest of the IO Expander pins to low to reduce power in deep sleep. - for (int i = 2; i < 15; i++) + for (int i = 2; i < 16; i++) { pinModeInternal(IO_EXT_ADDR, ioRegsEx, i, OUTPUT); digitalWriteInternal(IO_EXT_ADDR, ioRegsEx, i, LOW); } + // Allocate the memory for the framebuffer. DMemoryNew = (uint8_t *)ps_malloc(E_INK_WIDTH * E_INK_HEIGHT / 8); _partial = (uint8_t *)ps_malloc(E_INK_WIDTH * E_INK_HEIGHT / 8); _pBuffer = (uint8_t *)ps_malloc(E_INK_WIDTH * E_INK_HEIGHT / 4); @@ -516,30 +522,6 @@ uint32_t Inkplate::partialUpdate(bool _forced, bool leaveOn) delayMicroseconds(230); } - // for (int k = 0; k < 60; ++k) - // { - // uint8_t _send = B11111111; - // vscan_start(); - - // writeRow(_send); - // for (int i = 0; i < E_INK_HEIGHT / 2; i++) - // { - // hscan_start(pinLUT[_send]); - // delayMicroseconds(1); - // vscan_end(); - // } - - // _send = B01010101; - - // writeRow(_send); - // for (int i = 0; i < E_INK_HEIGHT / 2; i++) - // { - // hscan_start(pinLUT[_send]); - // delayMicroseconds(1); - // vscan_end(); - // } - // } - clean(2, 2); clean(3, 1); vscan_start(); @@ -567,11 +549,9 @@ void Inkplate::wakePeripheral(uint8_t _peripheral) if (_peripheral & INKPLATE_ACCELEROMETER) { // Wake accelerometer - uint8_t accControlReg; - lsm6ds3.readRegister(&accControlReg, 0x13); - lsm6ds3.writeRegister(0x13, accControlReg & 0xBF); - delay(2); - lsm6ds3.beginCore(); + lsm6ds3.settings.gyroEnabled = 1; + lsm6ds3.settings.accelEnabled = 1; + lsm6ds3.begin(&lsm6ds3.settings); } if (_peripheral & INKPLATE_BME688) @@ -589,11 +569,11 @@ void Inkplate::wakePeripheral(uint8_t _peripheral) if (_peripheral & INKPLATE_FUEL_GAUGE) { - uint8_t fuelGaugeControlReg1 = battery.readBlockData(0x3A); - uint8_t fuelGaugeControlReg2 = battery.readBlockData(0x3B); - fuelGaugeControlReg2 &= 0xCF; - uint16_t fuelGaugeControlRegToWrite = (fuelGaugeControlReg1 << 8) | fuelGaugeControlReg2; - battery.writeOpConfig(fuelGaugeControlRegToWrite); + // To wake up fuel gauge, just create rising edge signal on GPOUT pin. + pinModeInternal(IO_INT_ADDR, ioRegsInt, FG_GPOUT, INPUT_PULLUP); + + // Wait a little bit. + delayMicroseconds(250); } } @@ -611,20 +591,17 @@ void Inkplate::sleepPeripheral(uint8_t _peripheral) { if (_peripheral & INKPLATE_ACCELEROMETER) { - uint8_t accControlReg; - // First, put the gyro in sleep mode - lsm6ds3.readRegister(&accControlReg, 0x16); - lsm6ds3.writeRegister(0x16, accControlReg | 0x80); - // Then, the accelerometer - lsm6ds3.readRegister(&accControlReg, 0x15); - lsm6ds3.writeRegister(0x15, accControlReg | 0x10); + lsm6ds3.settings.gyroEnabled = 0; + lsm6ds3.settings.accelEnabled = 0; + lsm6ds3.begin(&lsm6ds3.settings); } if (_peripheral & INKPLATE_BME688) { // Put BME in sleep mode uint8_t bmeControlReg = bme688.readByte(BME_CONTROL_ADDR); - bme688.putData(BME_CONTROL_ADDR, bmeControlReg & 0xFC); + bmeControlReg &= ~(0b00000011); + bme688.putData(BME_CONTROL_ADDR, bmeControlReg); } if (_peripheral & INKPLATE_APDS9960) @@ -634,11 +611,11 @@ void Inkplate::sleepPeripheral(uint8_t _peripheral) if (_peripheral & INKPLATE_FUEL_GAUGE) { - uint8_t fuelGaugeControlReg1 = battery.readBlockData(0x3A); - uint8_t fuelGaugeControlReg2 = battery.readBlockData(0x3B); - fuelGaugeControlReg2 |= 0x20; - uint16_t fuelGaugeControlRegToWrite = (fuelGaugeControlReg1 << 8) | fuelGaugeControlReg2; - battery.writeOpConfig(fuelGaugeControlRegToWrite); + // First, set the GPOUT pin of the Fuel Gauge to pull down. + pinModeInternal(IO_INT_ADDR, ioRegsInt, FG_GPOUT, INPUT_PULLDOWN); + + // Issue a shutdown command. + battery.shutdown(); } } diff --git a/src/boards/Inkplate4TEMPERA.h b/src/boards/Inkplate4TEMPERA.h index d256f847..9a5478be 100644 --- a/src/boards/Inkplate4TEMPERA.h +++ b/src/boards/Inkplate4TEMPERA.h @@ -55,6 +55,9 @@ // Buzzer enable pin (pin P1_4 on internal IO expander) #define BUZZ_EN 12 +// Pin for Fuel Gauge GPOUT. +#define FG_GPOUT 15 + #define DATA 0x0E8C0030 // D0-D7 = GPIO4 GPIO5 GPIO18 GPIO19 GPIO23 GPIO25 GPIO26 GPIO27 #define CL 0x01 // GPIO0 diff --git a/src/include/Touch.cpp b/src/include/Touch.cpp index b3c21877..d706745f 100644 --- a/src/include/Touch.cpp +++ b/src/include/Touch.cpp @@ -184,7 +184,7 @@ bool Touch::tsInit(uint8_t _pwrState) */ void Touch::tsShutdown() { - digitalWriteInternal(TOUCHSCREEN_IO_EXPANDER, TOUCHSCREEN_IO_REGS, TOUCHSCREEN_EN, LOW); + digitalWriteInternal(TOUCHSCREEN_IO_EXPANDER, TOUCHSCREEN_IO_REGS, TOUCHSCREEN_EN, HIGH); } /** diff --git a/src/libs/BQ27441/src/libs/SparkFun_BQ27441_Arduino_Library/src/SparkFunBQ27441.cpp b/src/libs/BQ27441/src/libs/SparkFun_BQ27441_Arduino_Library/src/SparkFunBQ27441.cpp index d068aa60..50274a82 100644 --- a/src/libs/BQ27441/src/libs/SparkFun_BQ27441_Arduino_Library/src/SparkFunBQ27441.cpp +++ b/src/libs/BQ27441/src/libs/SparkFun_BQ27441_Arduino_Library/src/SparkFunBQ27441.cpp @@ -471,6 +471,13 @@ uint16_t BQ27441::status(void) return readControlWord(BQ27441_CONTROL_STATUS); } +// Added by Soldered Electronics. +void BQ27441::shutdown() +{ + readControlWord(BQ27441_CONTROL_SHUTDOWN_ENABLE); + readControlWord(BQ27441_CONTROL_SHUTDOWN); +} + /***************************** Private Functions *****************************/ // Check if the BQ27441-G1A is sealed or not. diff --git a/src/libs/BQ27441/src/libs/SparkFun_BQ27441_Arduino_Library/src/SparkFunBQ27441.h b/src/libs/BQ27441/src/libs/SparkFun_BQ27441_Arduino_Library/src/SparkFunBQ27441.h index d9fe142f..e4c8c33a 100644 --- a/src/libs/BQ27441/src/libs/SparkFun_BQ27441_Arduino_Library/src/SparkFunBQ27441.h +++ b/src/libs/BQ27441/src/libs/SparkFun_BQ27441_Arduino_Library/src/SparkFunBQ27441.h @@ -373,6 +373,9 @@ class BQ27441 */ uint8_t readBlockData(uint8_t offset); + // Added by Soldered Electronics. Enable or disable hibernate state to reduce power consumption. + void shutdown(); + private: uint8_t _deviceAddress; // Stores the BQ27441-G1A's I2C address bool _sealFlag; // Global to identify that IC was previously sealed diff --git a/src/libs/LSM6DS3/src/libs/SparkFun_LSM6DS3_Arduino_Library/src/SparkFunLSM6DS3.cpp b/src/libs/LSM6DS3/src/libs/SparkFun_LSM6DS3_Arduino_Library/src/SparkFunLSM6DS3.cpp index af7ea429..f8e20538 100644 --- a/src/libs/LSM6DS3/src/libs/SparkFun_LSM6DS3_Arduino_Library/src/SparkFunLSM6DS3.cpp +++ b/src/libs/LSM6DS3/src/libs/SparkFun_LSM6DS3_Arduino_Library/src/SparkFunLSM6DS3.cpp @@ -417,9 +417,6 @@ status_t LSM6DS3::begin(SensorSettings *pSettingsYouWanted) // Setup the accelerometer****************************** // First, wake the device - // This was added by Soldered due to the fact that on Inkplate 4TEMPERA peripherals are off by default - settings.accelEnabled = 1; - settings.gyroEnabled = 1; dataToWrite = 0; // Start Fresh! if (settings.accelEnabled == 1)