diff --git a/src/led/led.c b/src/led/led.c index 1f12c65..fb216c0 100644 --- a/src/led/led.c +++ b/src/led/led.c @@ -27,7 +27,7 @@ #endif extern void led_driver_init(); -extern void led_driver_color(uint8_t); +extern void led_driver_color(uint8_t, float); static uint32_t led_mode = MODE_NOT_MOUNTED; @@ -38,35 +38,43 @@ void led_set_mode(uint32_t mode) { void led_blinking_task() { #ifndef ENABLE_EMULATION static uint32_t start_ms = 0; + static uint32_t stop_ms = 0; static uint8_t led_state = false; uint8_t state = led_state; #ifdef PICO_DEFAULT_LED_PIN_INVERTED state = !state; #endif + uint32_t led_max_brightness = (led_mode & LED_BTNESS_MASK) >> LED_BTNESS_SHIFT; uint32_t led_color = (led_mode & LED_COLOR_MASK) >> LED_COLOR_SHIFT; uint32_t led_off = (led_mode & LED_OFF_MASK) >> LED_OFF_SHIFT; uint32_t led_on = (led_mode & LED_ON_MASK) >> LED_ON_SHIFT; - uint32_t led_interval = led_state ? led_on : led_off; - // Blink every interval ms - if (board_millis() - start_ms < led_interval) { - return; // not enough time - } - start_ms += led_interval; + // how far in the current state from 0 - 1 + float progress = (board_millis() - start_ms) / (stop_ms - start_ms); - if (state == false) { - led_driver_color(LED_COLOR_OFF); + if (!state){ + // fading down so 1 -> 0 + progress = 1 - progress; } - else { - led_driver_color(led_color); + + // maybe quick return if progress didn't changed much ? + + // current one from 0 - 1 + float led_brightness = (led_max_brightness / MAX_BTNESS) * progress; + + led_driver_color(led_color, led_brightness); + + if (board_millis() >= stop_ms){ + start_ms = stop_ms; + led_state ^= 1; // toggle + stop_ms = start_ms + (led_state ? led_on : led_off); } - led_state ^= 1; // toggle #endif } void led_off_all() { #ifndef ENABLE_EMULATION - led_driver_color(LED_COLOR_OFF); + led_driver_color(LED_COLOR_OFF, 0); #endif } diff --git a/src/led/led.h b/src/led/led.h index baeadf3..179b274 100644 --- a/src/led/led.h +++ b/src/led/led.h @@ -31,22 +31,31 @@ enum { LED_COLOR_WHITE }; -#define LED_OFF_BITS 14 +#define LED_OFF_BITS 12 #define LED_OFF_SHIFT 0 #define LED_OFF_MASK (((1 << LED_OFF_BITS) - 1) << LED_OFF_SHIFT) -#define LED_ON_BITS 14 +#define LED_ON_BITS 12 #define LED_ON_SHIFT LED_OFF_BITS #define LED_ON_MASK (((1 << LED_ON_BITS) - 1) << LED_ON_SHIFT) #define LED_COLOR_BITS 3 #define LED_COLOR_SHIFT (LED_ON_BITS + LED_OFF_BITS) #define LED_COLOR_MASK (((1 << LED_COLOR_BITS) - 1) << LED_COLOR_SHIFT) +#define LED_BTNESS_BITS 4 +#define LED_BTNESS_SHIFT (LED_ON_BITS + LED_OFF_BITS + LED_COLOR_BITS) +#define LED_BTNESS_MASK (((1 << LED_BTNESS_BITS) - 1 ) << LED_BTNESS_SHIFT) + +#define MAX_BTNESS ((1 << LED_BTNESS_BITS) - 1) +#define HALF_BTNESS ((1 << (LED_BTNESS_BITS - 1)) - 1) + +// steady on +#define LED_ON_NO_BLINK ((1000 << LED_ON_SHIFT) | (0 << LED_OFF_SHIFT)) enum { - MODE_NOT_MOUNTED = (LED_COLOR_RED << LED_COLOR_SHIFT) | (250 << LED_ON_SHIFT) | (250 << LED_OFF_SHIFT), - MODE_MOUNTED = (LED_COLOR_GREEN << LED_COLOR_SHIFT) | (250 << LED_ON_SHIFT) | (250 << LED_OFF_SHIFT), - MODE_SUSPENDED = (LED_COLOR_BLUE << LED_COLOR_SHIFT) | (500 << LED_ON_SHIFT) | (1000 << LED_OFF_SHIFT), - MODE_PROCESSING = (LED_COLOR_GREEN << LED_COLOR_SHIFT) | (50 << LED_ON_SHIFT) | (50 << LED_OFF_SHIFT), - MODE_BUTTON = (LED_COLOR_YELLOW << LED_COLOR_SHIFT) | (1000 << LED_ON_SHIFT) | (100 << LED_OFF_SHIFT), + MODE_NOT_MOUNTED = (HALF_BTNESS << LED_BTNESS_BITS) | (LED_COLOR_CYAN << LED_COLOR_SHIFT) | LED_ON_NO_BLINK, + MODE_MOUNTED = (HALF_BTNESS << LED_BTNESS_BITS) | (LED_COLOR_GREEN << LED_COLOR_SHIFT) | LED_ON_NO_BLINK, + MODE_SUSPENDED = (HALF_BTNESS << LED_BTNESS_BITS) | (LED_COLOR_BLUE << LED_COLOR_SHIFT) | (1000 << LED_ON_SHIFT) | (2000 << LED_OFF_SHIFT), + MODE_PROCESSING = (MAX_BTNESS << LED_BTNESS_SHIFT) | (LED_COLOR_RED << LED_COLOR_SHIFT) | (50 << LED_ON_SHIFT) | (50 << LED_OFF_SHIFT), + MODE_BUTTON = (MAX_BTNESS << LED_BTNESS_SHIFT) | (LED_COLOR_YELLOW << LED_COLOR_SHIFT) | (1000 << LED_ON_SHIFT) | (100 << LED_OFF_SHIFT), MODE_ALWAYS_ON = UINT32_MAX, MODE_ALWAYS_OFF = 0 diff --git a/src/led/led_cyw43.c b/src/led/led_cyw43.c index 7023bb0..6049dc5 100644 --- a/src/led/led_cyw43.c +++ b/src/led/led_cyw43.c @@ -25,7 +25,7 @@ void led_driver_init() { cyw43_arch_init(); } -void led_driver_color(uint8_t color) { +void led_driver_color(uint8_t color, float brightness) { cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, color != LED_COLOR_OFF); } diff --git a/src/led/led_neopixel.c b/src/led/led_neopixel.c index c865b9e..83322a5 100644 --- a/src/led/led_neopixel.c +++ b/src/led/led_neopixel.c @@ -45,7 +45,7 @@ void led_driver_init() { neopixel = neopixel_Init(1, gpio); } -void led_driver_color(int color) { +void led_driver_color(uint8_t color, float brightness) { neopixel_SetPixel(neopixel, &pixel[color], 1); } diff --git a/src/led/led_pico.c b/src/led/led_pico.c index 5ff7c9b..8d8a308 100644 --- a/src/led/led_pico.c +++ b/src/led/led_pico.c @@ -24,7 +24,7 @@ void led_driver_init() { gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); } -void led_driver_color(uint8_t color) { +void led_driver_color(uint8_t color, float brightness) { gpio_put(PICO_DEFAULT_LED_PIN, color != LED_COLOR_OFF); } diff --git a/src/led/led_pimoroni.c b/src/led/led_pimoroni.c index ffa87d3..3938f16 100644 --- a/src/led/led_pimoroni.c +++ b/src/led/led_pimoroni.c @@ -49,7 +49,7 @@ void led_driver_init() { gpio_set_dir(LED_B_PIN, GPIO_OUT); } -void led_driver_color(uint8_t color) { +void led_driver_color(uint8_t color, float brightness) { gpio_put(LED_R_PIN, pixel[color][0]); gpio_put(LED_G_PIN, pixel[color][1]); gpio_put(LED_B_PIN, pixel[color][2]); diff --git a/src/led/led_ws2812.c b/src/led/led_ws2812.c index 80042b4..b388f55 100644 --- a/src/led/led_ws2812.c +++ b/src/led/led_ws2812.c @@ -79,8 +79,17 @@ uint32_t pixel[] = { 0xffffff00 // 7: white }; -void led_driver_color(uint8_t color) { - pio_sm_put_blocking(pio0, 0, pixel[color]); +void led_driver_color(uint8_t color, float brightness) { + uint32_t pixel_color = pixel[color]; + uint8_t r = (pixel_color >> 16) & 0xFF; + uint8_t g = (pixel_color >> 24) & 0xFF; + uint8_t b = (pixel_color >> 8) & 0xFF; + + r = (uint8_t)(r * brightness); + g = (uint8_t)(g * brightness); + b = (uint8_t)(b * brightness); + + pio_sm_put_blocking(pio0, 0, (g << 24) | (r << 16) | (b << 8)); } #endif