1- // Waveshare LCD Touch 2 implementation
1+ // Waveshare S3 Touch LCD 2 implementation
22//
33#include < driver/gpio.h>
44#include < driver/ledc.h>
1818
1919#define BATTERY_ADC_CHANNEL ADC_CHANNEL_4
2020#define BATTERY_ADC_ATTEN ADC_ATTEN_DB_12
21- #define BATTERY_EMA_ALPHA 0.3 // estimated moving average smoothing factor
21+ #define BATTERY_EMA_ALPHA 0 .3f // estimated moving average smoothing factor
2222
2323#define LCD_BL_LEDC_TIMER LEDC_TIMER_0
2424#define LCD_BL_LEDC_MODE LEDC_LOW_SPEED_MODE
3131static adc_oneshot_unit_handle_t adc1_handle = NULL ;
3232static adc_cali_handle_t adc1_cali_chan0_handle = NULL ;
3333
34- static int ema_voltage = 0 ;
34+ static float ema_voltage = 0 . 0f ;
3535
3636static void button_shutdown (void * arg, void * ctx)
3737{
@@ -48,21 +48,17 @@ static esp_err_t boot_button_init(void)
4848 .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
4949 .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
5050 };
51-
5251 const button_gpio_config_t btn_gpio_cfg = {
5352 .gpio_num = 0 ,
5453 .active_level = 0 ,
5554 };
56-
5755 button_handle_t btn_handle = NULL ;
5856 ESP_ERROR_CHECK (iot_button_new_gpio_device (&btn_cfg, &btn_gpio_cfg, &btn_handle));
5957 ESP_ERROR_CHECK (iot_button_register_cb (btn_handle, BUTTON_LONG_PRESS_HOLD, NULL , button_shutdown, NULL ));
60-
6158 esp_sleep_disable_wakeup_source (ESP_SLEEP_WAKEUP_ALL);
6259 gpio_hold_en (GPIO_NUM_0);
6360 gpio_deep_sleep_hold_en ();
6461 esp_sleep_enable_ext0_wakeup (GPIO_NUM_0, 0 );
65-
6662 return ESP_OK;
6763}
6864
@@ -71,14 +67,12 @@ static esp_err_t brightness_init(void)
7167 gpio_reset_pin (CONFIG_DISPLAY_PIN_BL);
7268 gpio_set_direction (CONFIG_DISPLAY_PIN_BL, GPIO_MODE_OUTPUT);
7369 gpio_set_level (CONFIG_DISPLAY_PIN_BL, 1 );
74-
7570 ledc_timer_config_t ledc_timer = { .speed_mode = LCD_BL_LEDC_MODE,
7671 .timer_num = LCD_BL_LEDC_TIMER,
7772 .duty_resolution = LCD_BL_LEDC_DUTY_RES,
7873 .freq_hz = LCD_BL_LEDC_FREQUENCY, // Set output frequency at 5 kHz
7974 .clk_cfg = LEDC_AUTO_CLK };
8075 ESP_ERROR_CHECK (ledc_timer_config (&ledc_timer));
81-
8276 ledc_channel_config_t ledc_channel = { .speed_mode = LCD_BL_LEDC_MODE,
8377 .channel = LCD_BL_LEDC_CHANNEL,
8478 .timer_sel = LCD_BL_LEDC_TIMER,
@@ -87,31 +81,27 @@ static esp_err_t brightness_init(void)
8781 .duty = 0 , // Set duty to 0%
8882 .hpoint = 0 };
8983 ESP_ERROR_CHECK (ledc_channel_config (&ledc_channel));
90-
9184 return ESP_OK;
9285}
9386
9487esp_err_t power_init (void )
9588{
9689 // Use the BOOT button as a sleep/wakeup button
9790 ESP_ERROR_CHECK (boot_button_init ());
98-
9991 // Initialise backlight brightness
10092 ESP_ERROR_CHECK (brightness_init ());
101-
10293 // Initialise the ADC to measure battery level
10394 adc_oneshot_unit_init_cfg_t init_config1 = {
10495 .unit_id = ADC_UNIT_1,
10596 };
10697 ESP_ERROR_CHECK (adc_oneshot_new_unit (&init_config1, &adc1_handle));
10798 JADE_ASSERT (adc1_handle);
108-
99+ // ADC Config
109100 adc_oneshot_chan_cfg_t config = {
110- .bitwidth = ADC_BITWIDTH_DEFAULT,
111101 .atten = BATTERY_ADC_ATTEN,
102+ .bitwidth = ADC_BITWIDTH_DEFAULT,
112103 };
113104 ESP_ERROR_CHECK (adc_oneshot_config_channel (adc1_handle, BATTERY_ADC_CHANNEL, &config));
114-
115105 // Use voltage calibration
116106 adc_cali_curve_fitting_config_t cali_config = {
117107 .unit_id = ADC_UNIT_1,
@@ -122,57 +112,47 @@ esp_err_t power_init(void)
122112 JADE_LOGW (" ADC calibration not available, continuing without it" );
123113 adc1_cali_chan0_handle = NULL ;
124114 }
125-
126115 return ESP_OK;
127116}
128117
129118esp_err_t power_shutdown (void ) { esp_deep_sleep_start (); }
130-
131119esp_err_t power_screen_on (void ) { return ESP_OK; }
132120esp_err_t power_screen_off (void ) { return ESP_OK; }
133-
134121esp_err_t power_backlight_on (uint8_t brightness)
135122{
136123 if (brightness < BACKLIGHT_MIN) {
137124 brightness = BACKLIGHT_MIN;
138125 } else if (brightness > BACKLIGHT_MAX) {
139126 brightness = BACKLIGHT_MAX;
140127 }
141-
142128 uint32_t duty = (brightness * (LCD_BL_LEDC_DUTY - 1 )) / 5 ;
143129 ESP_ERROR_CHECK (ledc_set_duty (LCD_BL_LEDC_MODE, LCD_BL_LEDC_CHANNEL, duty));
144130 ESP_ERROR_CHECK (ledc_update_duty (LCD_BL_LEDC_MODE, LCD_BL_LEDC_CHANNEL));
145-
146131 return ESP_OK;
147132}
148-
149133esp_err_t power_backlight_off (void )
150134{
151135 ESP_ERROR_CHECK (ledc_set_duty (LCD_BL_LEDC_MODE, LCD_BL_LEDC_CHANNEL, 0 ));
152136 ESP_ERROR_CHECK (ledc_update_duty (LCD_BL_LEDC_MODE, LCD_BL_LEDC_CHANNEL));
153137
154138 return ESP_OK;
155139}
156-
157140esp_err_t power_camera_on (void ) { return ESP_OK; }
158141esp_err_t power_camera_off (void ) { return ESP_OK; }
159142
160143uint16_t power_get_vbat (void )
161144{
162145 JADE_ASSERT (adc1_handle);
163-
164146 int raw_adc, voltage;
165147 ESP_ERROR_CHECK (adc_oneshot_read (adc1_handle, BATTERY_ADC_CHANNEL, &raw_adc));
166-
167148 if (adc1_cali_chan0_handle) {
168149 adc_cali_raw_to_voltage (adc1_cali_chan0_handle, raw_adc, &voltage);
169150 } else {
170- voltage = (raw_adc * 3300 ) / 4095 ; // mV
151+ voltage = (raw_adc * 3300 ) / 4095 ;
171152 }
172-
173- // apply Estimated Moving Average since the ADC seems to have a lot of noise
174- ema_voltage = BATTERY_EMA_ALPHA * voltage + (1 - BATTERY_EMA_ALPHA) * (ema_voltage == 0 ? voltage : ema_voltage);
175- /* JADE_LOGI("Raw: %.2dmV, Smoothed: %.2d mV", voltage, ema_voltage); */
153+ // Apply Estimated Moving Average (EMA)
154+ const float ema_v = (ema_voltage > 0 ) ? ema_voltage : (float )voltage;
155+ ema_voltage = (BATTERY_EMA_ALPHA * voltage) + ((1 .0f - BATTERY_EMA_ALPHA) * ema_v);
176156 return (uint16_t )ema_voltage;
177157}
178158
@@ -193,10 +173,13 @@ uint8_t power_get_battery_status(void)
193173 return 0 ;
194174}
195175
196- // The STAT pin on the charging IC isn't exposed to a GPIO so we cannot read it
197- // and can't easily tap it with a wire. There is a charging LED though so you
198- // can see if the battery is being charged.
199- bool power_get_battery_charging (void ) { return 0 ; }
176+ bool power_get_battery_charging (void )
177+ {
178+ // The charging IC STAT pin is not connected to GPIO.
179+ // Return USB status as a proxy for charging (Dummy status)
180+ return usb_is_powered ();
181+ }
182+
200183uint16_t power_get_ibat_charge (void ) { return 0 ; }
201184uint16_t power_get_ibat_discharge (void ) { return 0 ; }
202185uint16_t power_get_vusb (void ) { return 0 ; }
@@ -212,12 +195,10 @@ bool usb_is_powered(void)
212195 if (tud_mounted () && !tud_suspended ()) {
213196 return true ;
214197 }
215-
216198 // Fallback: If voltage is near zero (<1V) but chip is on,
217199 // we must be running on USB power without a battery.
218200 if (power_get_vbat () < 1000 ) {
219201 return true ;
220202 }
221-
222203 return false ;
223- }
204+ }
0 commit comments