From fcd14eaad4fdf654010d478cf38ba1512757eac5 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 3 Dec 2025 17:19:01 +0100 Subject: [PATCH 1/2] nesso_n1: move expander and battery to external library Library lives in https://github.com/arduino-libraries/Arduino_Nesso_N1 --- variants/arduino_nesso_n1/expander.cpp | 347 ----------------------- variants/arduino_nesso_n1/pins_arduino.h | 129 +++------ 2 files changed, 33 insertions(+), 443 deletions(-) delete mode 100644 variants/arduino_nesso_n1/expander.cpp diff --git a/variants/arduino_nesso_n1/expander.cpp b/variants/arduino_nesso_n1/expander.cpp deleted file mode 100644 index e8a6cdbfa25..00000000000 --- a/variants/arduino_nesso_n1/expander.cpp +++ /dev/null @@ -1,347 +0,0 @@ -#define TwoWire TwoWireInternal -#define Wire WireInternal -#define Wire1 WireInternal1 - -#include "pins_arduino.h" -#include "../../libraries/Wire/src/Wire.h" -#include "../../libraries/Wire/src/Wire.cpp" - -static bool wireInitialized = false; - -// IO expander datasheet from https://www.diodes.com/datasheet/download/PI4IOE5V6408.pdf -// Battery charger datasheet from https://www.awinic.com/en/productDetail/AW32001ACSR -// battery gauge datasheet from https://www.ti.com/product/BQ27220 - -static void writeRegister(uint8_t address, uint8_t reg, uint8_t value) { - WireInternal.beginTransmission(address); - WireInternal.write(reg); - WireInternal.write(value); - WireInternal.endTransmission(); -} - -static uint8_t readRegister(uint8_t address, uint8_t reg) { - WireInternal.beginTransmission(address); - WireInternal.write(reg); - WireInternal.endTransmission(false); - WireInternal.requestFrom(address, 1); - return WireInternal.read(); -} - -static void writeBitRegister(uint8_t address, uint8_t reg, uint8_t bit, uint8_t value) { - uint8_t val = readRegister(address, reg); - if (value) { - writeRegister(address, reg, val | (1 << bit)); - } else { - writeRegister(address, reg, val & ~(1 << bit)); - } -} - -static bool readBitRegister(uint8_t address, uint8_t reg, uint8_t bit) { - uint8_t val = readRegister(address, reg); - return ((val & (1 << bit)) > 0); -} - -void pinMode(ExpanderPin pin, uint8_t mode) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - // reset all registers to default state - writeRegister(pin.address, 0x1, 0x1); - // set all pins as high as default state - writeRegister(pin.address, 0x9, 0xFF); - // interrupt mask to all pins - writeRegister(pin.address, 0x11, 0xFF); - // all input - writeRegister(pin.address, 0x3, 0); - } - writeBitRegister(pin.address, 0x3, pin.pin, mode == OUTPUT); - if (mode == OUTPUT) { - // remove high impedance - writeBitRegister(pin.address, 0x7, pin.pin, false); - } else if (mode == INPUT_PULLUP) { - // set pull-up resistor - writeBitRegister(pin.address, 0xB, pin.pin, true); - writeBitRegister(pin.address, 0xD, pin.pin, true); - } else if (mode == INPUT_PULLDOWN) { - // disable pull-up resistor - writeBitRegister(pin.address, 0xB, pin.pin, true); - writeBitRegister(pin.address, 0xD, pin.pin, false); - } else if (mode == INPUT) { - // disable pull selector resistor - writeBitRegister(pin.address, 0xB, pin.pin, false); - } -} - -void digitalWrite(ExpanderPin pin, uint8_t val) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - writeBitRegister(pin.address, 0x5, pin.pin, val == HIGH); -} - -int digitalRead(ExpanderPin pin) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - return readBitRegister(pin.address, 0xF, pin.pin); -} - -void NessoBattery::begin(uint16_t current, uint16_t voltage, UnderVoltageLockout uvlo, uint16_t dpm_voltage, uint8_t timeout) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - - setChargeCurrent(current); - setChargeVoltage(voltage); - setWatchdogTimer(timeout); - setBatUVLO(uvlo); - setVinDPMVoltage(dpm_voltage); - setHiZ(false); - setChargeEnable(true); -} - -void NessoBattery::enableCharge() { - setChargeEnable(true); -} - -void NessoBattery::setChargeEnable(bool enable) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - // bit 3 set charge enable - writeBitRegister(AW32001_I2C_ADDR, AW3200_POWER_ON_CFG, 3, !enable); -} - -void NessoBattery::setVinDPMVoltage(uint16_t voltage) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - if (voltage < 3880) { - voltage = 3880; - } - if (voltage > 5080) { - voltage = 5080; - } - uint8_t reg_value = readRegister(AW32001_I2C_ADDR, AW3200_INPUT_SRC); - // bits 7-4 set Vin DPM voltage - reg_value &= ~0b01111000; - reg_value |= ((voltage - 3880) / 80) << 4; - writeRegister(AW32001_I2C_ADDR, AW3200_INPUT_SRC, reg_value); -} - -void NessoBattery::setIinLimitCurrent(uint16_t current) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - if (current < 50) { - current = 50; - } - if (current > 500) { - current = 500; - } - uint8_t reg_value = readRegister(AW32001_I2C_ADDR, AW3200_INPUT_SRC); - // bits 3-0 set Iin limit current - reg_value &= ~0b00001111; - reg_value |= ((current - 50) / 30) & 0b00001111; - writeRegister(AW32001_I2C_ADDR, AW3200_INPUT_SRC, reg_value); -} - -void NessoBattery::setBatUVLO(UnderVoltageLockout uvlo) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - uint8_t reg_value = readRegister(AW32001_I2C_ADDR, AW3200_POWER_ON_CFG); - // bits 2-0 set UVLO - reg_value &= ~0b00000111; - reg_value |= (uvlo & 0b00000111); - writeRegister(AW32001_I2C_ADDR, AW3200_POWER_ON_CFG, reg_value); -} - -void NessoBattery::setChargeCurrent(uint16_t current) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - if (current < 8) { - current = 8; - } - if (current > 456) { - current = 456; - } - uint8_t reg_value = readRegister(AW32001_I2C_ADDR, AW3200_CHG_CURRENT); - // bits 5-0 set charge current - reg_value &= ~0b00111111; - reg_value |= ((current - 8) / 8) & 0b00111111; - writeRegister(AW32001_I2C_ADDR, AW3200_CHG_CURRENT, reg_value); -} - -void NessoBattery::setDischargeCurrent(uint16_t current) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - if (current < 200) { - current = 200; - } - if (current > 3200) { - current = 3200; - } - uint8_t reg_value = readRegister(AW32001_I2C_ADDR, AW3200_TERM_CURRENT); - // bits 7-4 set discharge current - reg_value &= ~0b11110000; - reg_value |= (((current - 200) / 200) & 0b00001111) << 4; - writeRegister(AW32001_I2C_ADDR, AW3200_TERM_CURRENT, reg_value); -} - -void NessoBattery::setChargeVoltage(uint16_t voltage) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - if (voltage < 3600) { - voltage = 3600; - } - if (voltage > 4545) { - voltage = 4545; - } - uint8_t reg_value = readRegister(AW32001_I2C_ADDR, AW3200_CHG_VOLTAGE); - // bits 7-2 set charge voltage - reg_value &= ~0b11111100; - reg_value |= ((voltage - 3600) / 15) << 2; - writeRegister(AW32001_I2C_ADDR, AW3200_CHG_VOLTAGE, reg_value); -} - -void NessoBattery::setWatchdogTimer(uint8_t sec) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - - uint8_t reg_value = readRegister(AW32001_I2C_ADDR, AW3200_TIMER_WD); - uint8_t bits = 0; - switch (sec) { - case 0: - bits = 0b00; // disable watchdog - break; - case 40: bits = 0b01; break; - case 80: bits = 0b10; break; - case 160: bits = 0b11; break; - default: bits = 0b11; break; - } - // bits 6-5 set watchdog timer - reg_value &= ~(0b11 << 5); - reg_value |= (bits << 5); - writeRegister(AW32001_I2C_ADDR, AW3200_TIMER_WD, reg_value); -} - -void NessoBattery::feedWatchdog() { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - // bit 6 set feed watchdog - writeBitRegister(AW32001_I2C_ADDR, AW3200_CHG_CURRENT, 6, true); -} - -void NessoBattery::setShipMode(bool en) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - // bit 5 set ship mode - writeBitRegister(AW32001_I2C_ADDR, AW3200_MAIN_CTRL, 5, en); -} - -NessoBattery::ChargeStatus NessoBattery::getChargeStatus() { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - uint8_t status = readRegister(AW32001_I2C_ADDR, AW3200_SYS_STATUS); - // bits 4-3 set charge status - uint8_t charge_status = (status >> 3) & 0b11; - return static_cast(charge_status); -} - -void NessoBattery::setHiZ(bool enable) { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - // bit 4 set Hi-Z mode - writeBitRegister(AW32001_I2C_ADDR, AW3200_POWER_ON_CFG, 4, enable); -} - -float NessoBattery::getVoltage() { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - uint16_t voltage = (readRegister(BQ27220_I2C_ADDR, BQ27220_VOLTAGE + 1) << 8) | readRegister(BQ27220_I2C_ADDR, BQ27220_VOLTAGE); - return (float)voltage / 1000.0f; -} - -float NessoBattery::getCurrent() { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - int16_t current = (readRegister(BQ27220_I2C_ADDR, BQ27220_CURRENT + 1) << 8) | readRegister(BQ27220_I2C_ADDR, BQ27220_CURRENT); - return (float)current / 1000.0f; -} - -uint16_t NessoBattery::getChargeLevel() { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - uint16_t current_capacity = readRegister(BQ27220_I2C_ADDR, BQ27220_REMAIN_CAPACITY + 1) << 8 | readRegister(BQ27220_I2C_ADDR, BQ27220_REMAIN_CAPACITY); - uint16_t total_capacity = readRegister(BQ27220_I2C_ADDR, BQ27220_FULL_CAPACITY + 1) << 8 | readRegister(BQ27220_I2C_ADDR, BQ27220_FULL_CAPACITY); - return (current_capacity * 100) / total_capacity; -} - -int16_t NessoBattery::getAvgPower() { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - int16_t avg_power = readRegister(BQ27220_I2C_ADDR, BQ27220_AVG_POWER + 1) << 8 | readRegister(BQ27220_I2C_ADDR, BQ27220_AVG_POWER); - return avg_power; -} - -float NessoBattery::getTemperature() { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - uint16_t temp = readRegister(BQ27220_I2C_ADDR, BQ27220_TEMPERATURE + 1) << 8 | readRegister(BQ27220_I2C_ADDR, BQ27220_TEMPERATURE); - return ((float)temp / 10.0f) - 273.15f; -} - -uint16_t NessoBattery::getCycleCount() { - if (!wireInitialized) { - WireInternal.begin(SDA, SCL); - wireInitialized = true; - } - uint16_t cycle_count = readRegister(BQ27220_I2C_ADDR, BQ27220_CYCLE_COUNT + 1) << 8 | readRegister(BQ27220_I2C_ADDR, BQ27220_CYCLE_COUNT); - return cycle_count; -} - -ExpanderPin LORA_LNA_ENABLE(5); -ExpanderPin LORA_ANTENNA_SWITCH(6); -ExpanderPin LORA_ENABLE(7); -ExpanderPin KEY1(0); -ExpanderPin KEY2(1); -ExpanderPin POWEROFF((1 << 8) | 0); -ExpanderPin LCD_RESET((1 << 8) | 1); -ExpanderPin GROVE_POWER_EN((1 << 8) | 2); -ExpanderPin VIN_DETECT((1 << 8) | 5); -ExpanderPin LCD_BACKLIGHT((1 << 8) | 6); -ExpanderPin LED_BUILTIN((1 << 8) | 7); diff --git a/variants/arduino_nesso_n1/pins_arduino.h b/variants/arduino_nesso_n1/pins_arduino.h index 30ccb527d33..b514876f336 100644 --- a/variants/arduino_nesso_n1/pins_arduino.h +++ b/variants/arduino_nesso_n1/pins_arduino.h @@ -40,106 +40,43 @@ static const uint8_t SYS_IRQ = 3; static const uint8_t LCD_CS = 17; static const uint8_t LCD_RS = 16; -#if !defined(MAIN_ESP32_HAL_GPIO_H_) && defined(__cplusplus) -/* address: 0x43/0x44 */ -class ExpanderPin { -public: - ExpanderPin(uint16_t _pin) : pin(_pin & 0xFF), address(_pin & 0x100 ? 0x44 : 0x43){}; - uint8_t pin; - uint8_t address; -}; +#if !defined(MAIN_ESP32_HAL_GPIO_H_) && defined(__cplusplus) /* && !defined(ARDUINO_CORE_BUILD) */ -class NessoBattery { +#define ATTRIBUTE_ERROR __attribute__((error("Please include Arduino_Nesso_N1.h"))) + +class ExpanderPinError { public: - static constexpr uint8_t AW32001_I2C_ADDR = 0x49; - static constexpr uint8_t BQ27220_I2C_ADDR = 0x55; - - enum AW32001Reg : uint8_t { - AW3200_INPUT_SRC = 0x00, - AW3200_POWER_ON_CFG = 0x01, - AW3200_CHG_CURRENT = 0x02, - AW3200_TERM_CURRENT = 0x03, - AW3200_CHG_VOLTAGE = 0x04, - AW3200_TIMER_WD = 0x05, - AW3200_MAIN_CTRL = 0x06, - AW3200_SYS_CTRL = 0x07, - AW3200_SYS_STATUS = 0x08, - AW3200_FAULT_STATUS = 0x09, - AW3200_CHIP_ID = 0x0A, - }; - - enum BQ27220Reg : uint8_t { - BQ27220_VOLTAGE = 0x08, - BQ27220_CURRENT = 0x0C, - BQ27220_REMAIN_CAPACITY = 0x10, - BQ27220_FULL_CAPACITY = 0x12, - BQ27220_AVG_POWER = 0x24, - BQ27220_TEMPERATURE = 0x28, - BQ27220_CYCLE_COUNT = 0x2A, - }; - - enum ChargeStatus { - NOT_CHARGING = 0, - PRE_CHARGE = 1, - CHARGING = 2, - FULL_CHARGE = 3, - }; - - enum UnderVoltageLockout { - UVLO_2430mV = 0, - UVLO_2490mV = 1, - UVLO_2580mV = 2, - UVLO_2670mV = 3, - UVLO_2760mV = 4, - UVLO_2850mV = 5, - UVLO_2940mV = 6, - UVLO_3030mV = 7, - }; - - NessoBattery(){}; - void begin( - uint16_t current = 256, uint16_t voltage = 4200, UnderVoltageLockout uvlo = UVLO_2580mV, uint16_t dpm_voltage = 4520, uint8_t timeout = 0 - ); // default: charge current 256mA, battery 4200mV, uvlo 2580mV, DMP 4520mV, disable watchdog - - // AW32001 functions - void enableCharge(); // enable charging - void setChargeEnable(bool enable); // charge control - void setVinDPMVoltage(uint16_t voltage); // set input voltage limit, 3880mV ~ 5080mV(step 80mV, default 4520mV) - void setIinLimitCurrent(uint16_t current); // set input current limit, 50mA ~ 500mA(step 30mA, default 500mA) - void setBatUVLO(UnderVoltageLockout uvlo); // set battery under voltage lockout(2430mV, 2490mV, 2580mV, 2670mV, 2760mV, 2850mV, 2940mV, 3030mV) - void setChargeCurrent(uint16_t current); // set charging current, 8mA ~ 456mA(step 8mA, default 128mA) - void setDischargeCurrent(uint16_t current); // set discharging current, 200mA ~ 3200mA(step 200mA, default 2000mA) - void setChargeVoltage(uint16_t voltage); // set charging voltage, 3600mV ~ 4545mV(step 15mV, default 4200mV) - void setWatchdogTimer(uint8_t sec); // set charge watchdog timeout(0s, 40s, 80s, 160s, default 160s, 0 to disable) - void feedWatchdog(); // feed watchdog timer - void setShipMode(bool en); // set ship mode - ChargeStatus getChargeStatus(); // get charge status - void setHiZ(bool enable); // set Hi-Z mode, true: USB -x-> SYS, false: USB -> SYS - - // BQ27220 functions - float getVoltage(); // get battery voltage in Volts - float getCurrent(); // get battery current in Amperes - uint16_t getChargeLevel(); // get battery charge level in percents - int16_t getAvgPower(); // get average power in mWatts, can be negative - float getTemperature(); // get battery temperature in Celsius - uint16_t getCycleCount(); // get battery cycle count + ExpanderPinError(uint16_t p) {}; }; -extern ExpanderPin LORA_LNA_ENABLE; -extern ExpanderPin LORA_ANTENNA_SWITCH; -extern ExpanderPin LORA_ENABLE; -extern ExpanderPin POWEROFF; -extern ExpanderPin GROVE_POWER_EN; -extern ExpanderPin VIN_DETECT; -extern ExpanderPin LCD_RESET; -extern ExpanderPin LCD_BACKLIGHT; -extern ExpanderPin LED_BUILTIN; -extern ExpanderPin KEY1; -extern ExpanderPin KEY2; - -void pinMode(ExpanderPin pin, uint8_t mode); -void digitalWrite(ExpanderPin pin, uint8_t val); -int digitalRead(ExpanderPin pin); +void ATTRIBUTE_ERROR pinMode(ExpanderPinError pin, uint8_t mode); +void ATTRIBUTE_ERROR digitalWrite(ExpanderPinError pin, uint8_t val); +int ATTRIBUTE_ERROR digitalRead(ExpanderPinError pin); + +extern ExpanderPinError _LORA_LNA_ENABLE; +extern ExpanderPinError _LORA_ANTENNA_SWITCH; +extern ExpanderPinError _LORA_ENABLE; +extern ExpanderPinError _POWEROFF; +extern ExpanderPinError _GROVE_POWER_EN; +extern ExpanderPinError _VIN_DETECT; +extern ExpanderPinError _LCD_RESET; +extern ExpanderPinError _LCD_BACKLIGHT; +extern ExpanderPinError _LED_BUILTIN; +extern ExpanderPinError _KEY1; +extern ExpanderPinError _KEY2; + +#define LORA_LNA_ENABLE _LORA_LNA_ENABLE +#define LORA_ANTENNA_SWITCH _LORA_ANTENNA_SWITCH +#define LORA_ENABLE _LORA_ENABLE +#define POWEROFF _POWEROFF +#define GROVE_POWER_EN _GROVE_POWER_EN +#define VIN_DETECT _VIN_DETECT +#define LCD_RESET _LCD_RESET +#define LCD_BACKLIGHT _LCD_BACKLIGHT +#define LED_BUILTIN _LED_BUILTIN +#define KEY1 _KEY1 +#define KEY2 _KEY2 + #endif #endif /* Pins_Arduino_h */ From 50918ab55d1b4990978dbf1b628ee0ed13636139 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 12:13:19 +0000 Subject: [PATCH 2/2] ci(pre-commit): Apply automatic fixes --- variants/arduino_nesso_n1/pins_arduino.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/variants/arduino_nesso_n1/pins_arduino.h b/variants/arduino_nesso_n1/pins_arduino.h index b514876f336..ce8a4db2900 100644 --- a/variants/arduino_nesso_n1/pins_arduino.h +++ b/variants/arduino_nesso_n1/pins_arduino.h @@ -46,7 +46,7 @@ static const uint8_t LCD_RS = 16; class ExpanderPinError { public: - ExpanderPinError(uint16_t p) {}; + ExpanderPinError(uint16_t p){}; }; void ATTRIBUTE_ERROR pinMode(ExpanderPinError pin, uint8_t mode); @@ -65,17 +65,17 @@ extern ExpanderPinError _LED_BUILTIN; extern ExpanderPinError _KEY1; extern ExpanderPinError _KEY2; -#define LORA_LNA_ENABLE _LORA_LNA_ENABLE +#define LORA_LNA_ENABLE _LORA_LNA_ENABLE #define LORA_ANTENNA_SWITCH _LORA_ANTENNA_SWITCH -#define LORA_ENABLE _LORA_ENABLE -#define POWEROFF _POWEROFF -#define GROVE_POWER_EN _GROVE_POWER_EN -#define VIN_DETECT _VIN_DETECT -#define LCD_RESET _LCD_RESET -#define LCD_BACKLIGHT _LCD_BACKLIGHT -#define LED_BUILTIN _LED_BUILTIN -#define KEY1 _KEY1 -#define KEY2 _KEY2 +#define LORA_ENABLE _LORA_ENABLE +#define POWEROFF _POWEROFF +#define GROVE_POWER_EN _GROVE_POWER_EN +#define VIN_DETECT _VIN_DETECT +#define LCD_RESET _LCD_RESET +#define LCD_BACKLIGHT _LCD_BACKLIGHT +#define LED_BUILTIN _LED_BUILTIN +#define KEY1 _KEY1 +#define KEY2 _KEY2 #endif