Skip to content

Commit 8f37b11

Browse files
committed
Add LED flash and rewake cancel
1 parent 4eafce3 commit 8f37b11

File tree

5 files changed

+115
-12
lines changed

5 files changed

+115
-12
lines changed

app/app_config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

33
#define VERSION_MAJOR 3
4-
#define VERSION_MINOR 4
4+
#define VERSION_MINOR 5
55

66
#define KEY_FIFO_SIZE 31 // number of keys in the public FIFO

app/pi.c

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
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+
1121
enum 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

6878
void 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

7390
static 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

8097
void 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

85124
void 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+
}

app/pi.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ enum power_on_reason
66
{
77
POWER_ON_FW_INIT = 0x1, // RP2040 initialized
88
POWER_ON_BUTTON = 0x2, // Power button held after Pi was shut down
9-
POWER_ON_REWAKE = 0x3 // 0x2 = Pi was reawakened from a scheduled timer
9+
POWER_ON_REWAKE = 0x3, // Pi was reawakened from a scheduled timer
10+
POWER_ON_REWAKE_CANCELED = 0x4 // Rewake timer was canceled
1011
};
1112

1213
#define MINIMUM_SHUTDOWN_GRACE_MS 5000
@@ -17,6 +18,8 @@ void pi_power_off(void);
1718

1819
void pi_schedule_power_on(uint32_t ms);
1920
void pi_schedule_power_off(uint32_t ms);
21+
void pi_cancel_power_alarms();
2022

21-
void led_sync(void);
23+
void led_sync(uint8_t enable);
2224
void led_init(void);
25+
void led_flash(uint8_t enable);

app/reg.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,22 +156,23 @@ void reg_process_packet(uint8_t in_reg, uint8_t in_data, uint8_t *out_buffer, ui
156156
case REG_ID_LED_R:
157157
case REG_ID_LED_G:
158158
case REG_ID_LED_B:
159+
case REG_ID_LED:
159160
{
160161
if (is_write) {
161162
reg_set_value(reg, in_data);
162-
led_sync();
163+
led_sync(reg_get_value(REG_ID_LED));
163164
} else {
164165
out_buffer[0] = reg_get_value(reg);
165166
*out_len = sizeof(uint8_t);
166167
}
167168
break;
168169
}
169170

170-
case REG_ID_LED: // gpio value
171+
case REG_ID_LED_FLASH:
171172
{
172173
if (is_write) {
173174
reg_set_value(reg, in_data);
174-
led_sync();
175+
led_flash(reg_get_value(REG_ID_LED_FLASH));
175176
} else {
176177
out_buffer[0] = reg_get_value(reg);
177178
*out_len = sizeof(uint8_t);
@@ -182,6 +183,18 @@ void reg_process_packet(uint8_t in_reg, uint8_t in_data, uint8_t *out_buffer, ui
182183
// Rewake on timer
183184
case REG_ID_REWAKE_MINS:
184185
{
186+
// Value of zero will cancel alarms
187+
if (in_data == 0) {
188+
pi_cancel_power_alarms();
189+
190+
// Reset startup reason if in rewake
191+
if (reg_get_value(REG_ID_STARTUP_REASON) == POWER_ON_REWAKE) {
192+
reg_set_value(REG_ID_STARTUP_REASON, POWER_ON_REWAKE_CANCELED);
193+
}
194+
195+
break;
196+
}
197+
185198
// Only run this if driver was loaded
186199
// Otherwise, OS won't get the power key event
187200
if (reg_get_value(REG_ID_DRIVER_STATE) == 0) {

app/reg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ enum reg_id
3333
REG_ID_LED_R = 0x21,
3434
REG_ID_LED_G = 0x22,
3535
REG_ID_LED_B = 0x23,
36+
REG_ID_LED_FLASH = 0x2F, // Write to flash LED
3637

3738
REG_ID_REWAKE_MINS = 0x24, // Write to turn off Pi, power on in this many mins
3839
REG_ID_SHUTDOWN_GRACE = 0x25, // Seconds to wait between shutdown signal and power off

0 commit comments

Comments
 (0)