88
99#include <pico/stdlib.h>
1010
11+ #define LED_FLASH_CYCLE_MS 3000
12+ #define LED_FLASH_ON_MS 200
13+
14+ // Globals
15+ alarm_id_t g_power_on_alarm = -1 ;
16+ alarm_id_t g_power_off_alarm = -1 ;
17+
18+ uint8_t g_led_flash_enabled = 0 ;
19+ alarm_id_t g_led_flash_alarm = -1 ;
20+
1121enum pi_state
1222{
1323 PI_STATE_OFF = 0 ,
@@ -42,7 +52,7 @@ void pi_power_on(enum power_on_reason reason)
4252 reg_set_value (REG_ID_LED_R , 0 );
4353 reg_set_value (REG_ID_LED_G , 128 );
4454 reg_set_value (REG_ID_LED_B , 0 );
45- led_sync ();
55+ led_sync (1 );
4656
4757 // Update startup reason
4858 reg_set_value (REG_ID_STARTUP_REASON , reason );
@@ -67,7 +77,14 @@ static int64_t pi_power_on_alarm_callback(alarm_id_t _, void* __)
6777
6878void pi_schedule_power_on (uint32_t ms )
6979{
70- add_alarm_in_ms (ms , pi_power_on_alarm_callback , NULL , true);
80+ // Cancel existing alarm if scheduled
81+ if (g_power_on_alarm >= 0 ) {
82+ cancel_alarm (g_power_on_alarm );
83+ g_power_on_alarm = -1 ;
84+ }
85+
86+ // Schedule new alarm
87+ g_power_on_alarm = add_alarm_in_ms (ms , pi_power_on_alarm_callback , NULL , true);
7188}
7289
7390static int64_t pi_power_off_alarm_callback (alarm_id_t _ , void * __ )
@@ -79,7 +96,29 @@ static int64_t pi_power_off_alarm_callback(alarm_id_t _, void* __)
7996
8097void pi_schedule_power_off (uint32_t ms )
8198{
82- add_alarm_in_ms (ms , pi_power_off_alarm_callback , NULL , true);
99+ // Cancel existing alarm if scheduled
100+ if (g_power_off_alarm >= 0 ) {
101+ cancel_alarm (g_power_off_alarm );
102+ g_power_off_alarm = -1 ;
103+ }
104+
105+ // Schedule new alarm
106+ g_power_off_alarm = add_alarm_in_ms (ms , pi_power_off_alarm_callback , NULL , true);
107+ }
108+
109+ void pi_cancel_power_alarms ()
110+ {
111+ // Cancel power on alarm
112+ if (g_power_on_alarm >= 0 ) {
113+ cancel_alarm (g_power_on_alarm );
114+ g_power_on_alarm = -1 ;
115+ }
116+
117+ // Cancel power off alarm
118+ if (g_power_off_alarm >= 0 ) {
119+ cancel_alarm (g_power_off_alarm );
120+ g_power_off_alarm = -1 ;
121+ }
83122}
84123
85124void led_init (void )
@@ -92,10 +131,11 @@ void led_init(void)
92131 //default off
93132 reg_set_value (REG_ID_LED , 0 );
94133
95- led_sync ();
134+ led_sync (0 );
96135}
97136
98- void led_sync (void ){
137+ void led_sync (uint8_t enable )
138+ {
99139 // Set the PWM slice for each channel
100140 uint slice_r = pwm_gpio_to_slice_num (PIN_LED_R );
101141 uint slice_g = pwm_gpio_to_slice_num (PIN_LED_G );
@@ -107,10 +147,11 @@ void led_sync(void){
107147 uint16_t pwm_b = (0xFF - reg_get_value (REG_ID_LED_B )) * 0x101 ;
108148
109149 // Set the PWM duty cycle for each channel
110- if ( reg_get_value ( REG_ID_LED ) == 0 ){
150+ if ( enable == 0 ){
111151 pwm_set_gpio_level (PIN_LED_R , 0xFFFF );
112152 pwm_set_gpio_level (PIN_LED_G , 0xFFFF );
113153 pwm_set_gpio_level (PIN_LED_B , 0xFFFF );
154+
114155 } else {
115156 pwm_set_gpio_level (PIN_LED_R , pwm_r );
116157 pwm_set_gpio_level (PIN_LED_G , pwm_g );
@@ -122,3 +163,48 @@ void led_sync(void){
122163 pwm_set_enabled (slice_g , true);
123164 pwm_set_enabled (slice_b , true);
124165}
166+
167+ static int64_t pi_led_flash_alarm_callback (alarm_id_t _ , void * __ )
168+ {
169+ static uint8_t led_enabled = 0 ;
170+ uint32_t alarm_ms ;
171+
172+ // Exit if flash canceled
173+ if (reg_get_value (REG_ID_LED_FLASH ) == 0 ) {
174+ return 0 ;
175+ }
176+
177+ // Toggle LED
178+ led_enabled = !led_enabled ;
179+ led_sync (led_enabled );
180+
181+ // Reschedule timer
182+ alarm_ms = (led_enabled )
183+ ? LED_FLASH_ON_MS
184+ : (LED_FLASH_CYCLE_MS - LED_FLASH_ON_MS );
185+ g_led_flash_alarm = add_alarm_in_ms (alarm_ms , pi_led_flash_alarm_callback , NULL , true);
186+
187+ return 0 ;
188+ }
189+
190+ void led_flash (uint8_t enable )
191+ {
192+ if (enable ) {
193+
194+ // Schedule flash timer
195+ if (g_led_flash_alarm < 0 ) {
196+ g_led_flash_alarm = add_alarm_in_ms (700 , pi_led_flash_alarm_callback , NULL , true);
197+ }
198+
199+ } else {
200+
201+ // Cancel flash timer
202+ if (g_led_flash_alarm >= 0 ) {
203+ cancel_alarm (g_led_flash_alarm );
204+ g_led_flash_alarm = -1 ;
205+ }
206+
207+ // Restore LED to original state
208+ led_sync (reg_get_value (REG_ID_LED ));
209+ }
210+ }
0 commit comments