1+ #include < stdint.h>
2+ #include " Wire.h"
3+ #include < M5GFX.h>
4+ #include < lgfx/v1/panel/Panel_ST7789.hpp>
5+ // #include "Arduino_BMI270_BMM150.h"
6+
7+ #if defined(__cplusplus)
8+
9+ /* address: 0x43/0x44 */
10+ class ExpanderPin {
11+ public:
12+ ExpanderPin (uint16_t _pin) : pin(_pin & 0xFF ), address(_pin & 0x100 ? 0x44 : 0x43 ){};
13+ uint8_t pin;
14+ uint8_t address;
15+ bool initialized () {
16+ return _initialized[address - 0x43 ];
17+ }
18+ void initialize () {
19+ _initialized[address - 0x43 ] = true ;
20+ }
21+ private:
22+ static bool _initialized[2 ];
23+ };
24+
25+ class NessoBattery {
26+ public:
27+ static constexpr uint8_t AW32001_I2C_ADDR = 0x49 ;
28+ static constexpr uint8_t BQ27220_I2C_ADDR = 0x55 ;
29+
30+ enum AW32001Reg : uint8_t {
31+ AW3200_INPUT_SRC = 0x00 ,
32+ AW3200_POWER_ON_CFG = 0x01 ,
33+ AW3200_CHG_CURRENT = 0x02 ,
34+ AW3200_TERM_CURRENT = 0x03 ,
35+ AW3200_CHG_VOLTAGE = 0x04 ,
36+ AW3200_TIMER_WD = 0x05 ,
37+ AW3200_MAIN_CTRL = 0x06 ,
38+ AW3200_SYS_CTRL = 0x07 ,
39+ AW3200_SYS_STATUS = 0x08 ,
40+ AW3200_FAULT_STATUS = 0x09 ,
41+ AW3200_CHIP_ID = 0x0A ,
42+ };
43+
44+ enum BQ27220Reg : uint8_t {
45+ BQ27220_VOLTAGE = 0x08 ,
46+ BQ27220_CURRENT = 0x0C ,
47+ BQ27220_REMAIN_CAPACITY = 0x10 ,
48+ BQ27220_FULL_CAPACITY = 0x12 ,
49+ BQ27220_AVG_POWER = 0x24 ,
50+ BQ27220_TEMPERATURE = 0x28 ,
51+ BQ27220_CYCLE_COUNT = 0x2A ,
52+ };
53+
54+ enum ChargeStatus {
55+ NOT_CHARGING = 0 ,
56+ PRE_CHARGE = 1 ,
57+ CHARGING = 2 ,
58+ FULL_CHARGE = 3 ,
59+ };
60+
61+ enum UnderVoltageLockout {
62+ UVLO_2430mV = 0 ,
63+ UVLO_2490mV = 1 ,
64+ UVLO_2580mV = 2 ,
65+ UVLO_2670mV = 3 ,
66+ UVLO_2760mV = 4 ,
67+ UVLO_2850mV = 5 ,
68+ UVLO_2940mV = 6 ,
69+ UVLO_3030mV = 7 ,
70+ };
71+
72+ NessoBattery (){};
73+ void begin (
74+ uint16_t current = 256 , uint16_t voltage = 4200 , UnderVoltageLockout uvlo = UVLO_2580mV, uint16_t dpm_voltage = 4520 , uint8_t timeout = 0
75+ ); // default: charge current 256mA, battery 4200mV, uvlo 2580mV, DMP 4520mV, disable watchdog
76+
77+ // AW32001 functions
78+ void enableCharge (); // enable charging
79+ void setChargeEnable (bool enable); // charge control
80+ void setVinDPMVoltage (uint16_t voltage); // set input voltage limit, 3880mV ~ 5080mV(step 80mV, default 4520mV)
81+ void setIinLimitCurrent (uint16_t current); // set input current limit, 50mA ~ 500mA(step 30mA, default 500mA)
82+ void setBatUVLO (UnderVoltageLockout uvlo); // set battery under voltage lockout(2430mV, 2490mV, 2580mV, 2670mV, 2760mV, 2850mV, 2940mV, 3030mV)
83+ void setChargeCurrent (uint16_t current); // set charging current, 8mA ~ 456mA(step 8mA, default 128mA)
84+ void setDischargeCurrent (uint16_t current); // set discharging current, 200mA ~ 3200mA(step 200mA, default 2000mA)
85+ void setChargeVoltage (uint16_t voltage); // set charging voltage, 3600mV ~ 4545mV(step 15mV, default 4200mV)
86+ void setWatchdogTimer (uint8_t sec); // set charge watchdog timeout(0s, 40s, 80s, 160s, default 160s, 0 to disable)
87+ void feedWatchdog (); // feed watchdog timer
88+ void setShipMode (bool en); // set ship mode
89+ ChargeStatus getChargeStatus (); // get charge status
90+ void setHiZ (bool enable); // set Hi-Z mode, true: USB -x-> SYS, false: USB -> SYS
91+
92+ // BQ27220 functions
93+ float getVoltage (); // get battery voltage in Volts
94+ float getCurrent (); // get battery current in Amperes
95+ uint16_t getChargeLevel (); // get battery charge level in percents
96+ int16_t getAvgPower (); // get average power in mWatts, can be negative
97+ float getTemperature (); // get battery temperature in Celsius
98+ uint16_t getCycleCount (); // get battery cycle count
99+ };
100+
101+ extern ExpanderPin LORA_LNA_ENABLE;
102+ extern ExpanderPin LORA_ANTENNA_SWITCH;
103+ extern ExpanderPin LORA_ENABLE;
104+ extern ExpanderPin POWEROFF;
105+ extern ExpanderPin GROVE_POWER_EN;
106+ extern ExpanderPin VIN_DETECT;
107+ extern ExpanderPin LCD_RESET;
108+ extern ExpanderPin LCD_BACKLIGHT;
109+ extern ExpanderPin LED_BUILTIN;
110+ extern ExpanderPin KEY1;
111+ extern ExpanderPin KEY2;
112+
113+ void pinMode (ExpanderPin pin, uint8_t mode);
114+ void digitalWrite (ExpanderPin pin, uint8_t val);
115+ int digitalRead (ExpanderPin pin);
116+
117+ class NessoDisplay : public lgfx ::LGFX_Device {
118+ lgfx::Panel_ST7789 _panel_instance;
119+ lgfx::Bus_SPI _bus_instance;
120+
121+ public:
122+ NessoDisplay (void ) {
123+ {
124+ auto cfg = _bus_instance.config ();
125+
126+ cfg.pin_mosi = 21 ;
127+ cfg.pin_miso = 22 ;
128+ cfg.pin_sclk = 20 ;
129+ cfg.pin_dc = 16 ;
130+ cfg.freq_write = 40000000 ;
131+
132+ _bus_instance.config (cfg);
133+ _panel_instance.setBus (&_bus_instance);
134+ }
135+ {
136+ auto cfg = _panel_instance.config ();
137+
138+ cfg.invert = true ;
139+ cfg.pin_cs = 17 ;
140+ cfg.pin_rst = -1 ;
141+ cfg.pin_busy = -1 ;
142+ cfg.panel_width = 135 ;
143+ cfg.panel_height = 240 ;
144+ cfg.offset_x = 52 ;
145+ cfg.offset_y = 40 ;
146+
147+ _panel_instance.config (cfg);
148+ }
149+
150+ setPanel (&_panel_instance);
151+ }
152+ bool begin () {
153+ pinMode (LED_BUILTIN, OUTPUT);
154+ pinMode (LCD_BACKLIGHT, OUTPUT);
155+ pinMode (LCD_RESET, OUTPUT);
156+ pinMode (KEY1, INPUT_PULLUP);
157+ pinMode (KEY2, INPUT_PULLUP);
158+ digitalWrite (LCD_BACKLIGHT, HIGH);
159+ digitalWrite (LCD_RESET, LOW);
160+ delay (100 );
161+ digitalWrite (LCD_RESET, HIGH);
162+ return lgfx::LGFX_Device::begin ();
163+ }
164+ };
165+
166+ class NessoTouch {
167+ private:
168+ TwoWire *_wire;
169+ uint8_t _addr;
170+ bool _inited;
171+
172+ // FT6x36 register definitions
173+ static const uint8_t FT6X36_ADDR = 0x38 ;
174+ static const uint8_t FT6X36_TD_STAT_REG = 0x02 ;
175+ static const uint8_t FT6X36_P1_XH_REG = 0x03 ;
176+
177+ uint8_t readRegister (uint8_t reg) {
178+ _wire->beginTransmission (_addr);
179+ _wire->write (reg);
180+ _wire->endTransmission ();
181+ _wire->requestFrom (_addr, (uint8_t )1 );
182+ return _wire->read ();
183+ }
184+
185+ void readRegisters (uint8_t reg, uint8_t *buf, uint8_t len) {
186+ _wire->beginTransmission (_addr);
187+ _wire->write (reg);
188+ _wire->endTransmission ();
189+ _wire->requestFrom (_addr, len);
190+ for (uint8_t i = 0 ; i < len; i++) {
191+ buf[i] = _wire->read ();
192+ }
193+ }
194+
195+ public:
196+ NessoTouch (TwoWire &wire = Wire)
197+ : _wire(&wire), _addr(FT6X36_ADDR), _inited(false ) {}
198+
199+ bool begin () {
200+ if (_inited) return true ;
201+
202+ _wire->beginTransmission (_addr);
203+ if (_wire->endTransmission () == 0 ) {
204+ _inited = true ;
205+ return true ;
206+ }
207+ return false ;
208+ }
209+
210+ // Check if touch is detected
211+ bool isTouched () {
212+ if (!_inited) return false ;
213+ uint8_t touchPoints = readRegister (FT6X36_TD_STAT_REG) & 0x0F ;
214+ return (touchPoints == 1 ); // Only handle single touch
215+ }
216+
217+ // Read touch coordinates
218+ bool read (int16_t &x, int16_t &y) {
219+ if (!_inited) return false ;
220+
221+ uint8_t data[4 ];
222+ readRegisters (FT6X36_P1_XH_REG, data, 4 );
223+
224+ uint8_t touchPoints = readRegister (FT6X36_TD_STAT_REG) & 0x0F ;
225+ if (touchPoints != 1 ) {
226+ return false ;
227+ }
228+
229+ x = ((data[0 ] & 0x0F ) << 8 ) | data[1 ];
230+ y = ((data[2 ] & 0x0F ) << 8 ) | data[3 ];
231+
232+ return true ;
233+ }
234+ };
235+
236+ #endif
0 commit comments