v1.7: blanking signal. Reset remaining leds.

This commit is contained in:
Derek Jamison 2023-12-06 13:57:06 -06:00
parent 6b817ad23e
commit 774b228856
3 changed files with 20 additions and 8 deletions

View File

@ -23,6 +23,10 @@ This application has three submenu items:
The "About" menu item contains information about the application. The "About" menu item contains information about the application.
# Updates # Updates
- Version 1.7
- Added blanking TRESET (LOW) signal before sending data to LEDs.
- Increased timer_buffer to uint16 to support blanking signal duration. Maybe there is a better way to do the initial low & save memory?
- Bug fix: Turn off remaining LEDs when reducing the number of LEDs.
- Version 1.6 - Version 1.6
- Added support for up to 1000 LEDs (max set in led_driver.h) - Added support for up to 1000 LEDs (max set in led_driver.h)
- Added "dirty flag" to get rid of flicker when not updating the LEDs - Added "dirty flag" to get rid of flicker when not updating the LEDs

View File

@ -333,6 +333,7 @@ static bool led_tester_custom_event_callback(void* context, uint32_t event) {
rgb[i] = (((rgb[i] >> 16) & 0xFF) * app->model->led_max_brightness / 100) << 16 | rgb[i] = (((rgb[i] >> 16) & 0xFF) * app->model->led_max_brightness / 100) << 16 |
(((rgb[i] >> 8) & 0xFF) * app->model->led_max_brightness / 100) << 8 | (((rgb[i] >> 8) & 0xFF) * app->model->led_max_brightness / 100) << 8 |
((rgb[i] & 0xFF) * app->model->led_max_brightness / 100); ((rgb[i] & 0xFF) * app->model->led_max_brightness / 100);
// rgb[i] = (rgb[i] & 0x0F0F0F); // For Debugging, just use lower 4-bits.
} }
led_driver_set_pin(app->led_driver, pin); led_driver_set_pin(app->led_driver, pin);
@ -341,6 +342,10 @@ static bool led_tester_custom_event_callback(void* context, uint32_t event) {
for(size_t i = 0; i < app->model->led_count; i++) { for(size_t i = 0; i < app->model->led_count; i++) {
led_driver_set_led(app->led_driver, i, rgb[i % 4]); led_driver_set_led(app->led_driver, i, rgb[i % 4]);
} }
// Turn off any remaining LEDs
for(size_t i = app->model->led_count; i < MAX_LED_COUNT; i++) {
led_driver_set_led(app->led_driver, i, 0);
}
led_driver_transmit(app->led_driver, false); led_driver_transmit(app->led_driver, false);
@ -515,7 +520,7 @@ static LedTesterApp* led_tester_app_alloc() {
0, 0,
128, 128,
64, 64,
"This is a WS2812B LED tester\nVersion 1.6\nConnect WS2812B LED data\nwire to GPIO pin on Flipper.\n\nThe 3V3 pin has a 1200mA\nmax current (~4 watts). The\n5V pin has a 1000mA max\ncurrent (5 watts).\n\nauthors: @codeallnight and\nZ3BRO!\n\nhttps://discord.com/invite/NsjCvqwPAd\nhttps://youtube.com/@MrDerekJamison\n\n"); "This is a WS2812B LED tester\nVersion 1.7\nConnect WS2812B LED data\nwire to GPIO pin on Flipper.\n\nThe 3V3 pin has a 1200mA\nmax current (~4 watts). The\n5V pin has a 1000mA max\ncurrent (5 watts).\n\nauthors: @codeallnight and\nZ3BRO!\n\nhttps://discord.com/invite/NsjCvqwPAd\nhttps://youtube.com/@MrDerekJamison\n\n");
view_set_previous_callback( view_set_previous_callback(
widget_get_view(app->widget_about), led_tester_navigation_submenu_callback); widget_get_view(app->widget_about), led_tester_navigation_submenu_callback);
view_dispatcher_add_view( view_dispatcher_add_view(

View File

@ -13,7 +13,7 @@
// We store the HIGH/LOW durations (2 values) for each color bit (24 bits per LED) // We store the HIGH/LOW durations (2 values) for each color bit (24 bits per LED)
#define LED_DRIVER_BUFFER_SIZE (MAX_LED_COUNT * 2 * 24) #define LED_DRIVER_BUFFER_SIZE (MAX_LED_COUNT * 2 * 24)
// We use a setinel value to figure out when the timer is complete. // We use a setinel value to figure out when the timer is complete.
#define LED_DRIVER_TIMER_SETINEL 0xFFU #define LED_DRIVER_TIMER_SETINEL 0xFFFFU
/** 64 transitions per us @ 64MHz. Our timing is in NANO_SECONDS */ /** 64 transitions per us @ 64MHz. Our timing is in NANO_SECONDS */
#define LED_DRIVER_TIMER_NANOSECOND (1000U / (SystemCoreClock / 1000000U)) #define LED_DRIVER_TIMER_NANOSECOND (1000U / (SystemCoreClock / 1000000U))
@ -22,6 +22,7 @@
#define LED_DRIVER_T1H 800U #define LED_DRIVER_T1H 800U
#define LED_DRIVER_T0L 850U #define LED_DRIVER_T0L 850U
#define LED_DRIVER_T1L 450U #define LED_DRIVER_T1L 450U
#define LED_DRIVER_TRESETL 55 * 1000U
// Wait for 35ms for the DMA to complete. NOTE: 1000 leds*(850ns+450ns)*24 = 32ms // Wait for 35ms for the DMA to complete. NOTE: 1000 leds*(850ns+450ns)*24 = 32ms
#define LED_DRIVER_SETINEL_WAIT_MS 35 #define LED_DRIVER_SETINEL_WAIT_MS 35
@ -33,7 +34,7 @@ struct LedDriver {
const GpioPin* gpio; const GpioPin* gpio;
uint32_t gpio_buf[2]; // On/Off for GPIO uint32_t gpio_buf[2]; // On/Off for GPIO
uint8_t timer_buffer[LED_DRIVER_BUFFER_SIZE + 2]; uint16_t timer_buffer[LED_DRIVER_BUFFER_SIZE + 2];
uint32_t write_pos; uint32_t write_pos;
uint32_t read_pos; uint32_t read_pos;
bool dirty; bool dirty;
@ -74,7 +75,7 @@ static void led_driver_init_dma_led_transition_timer(LedDriver* led_driver) {
led_driver->dma_led_transition_timer.MemoryOrM2MDstAddress = led_driver->dma_led_transition_timer.MemoryOrM2MDstAddress =
(uint32_t)led_driver->timer_buffer; (uint32_t)led_driver->timer_buffer;
led_driver->dma_led_transition_timer.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; led_driver->dma_led_transition_timer.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
led_driver->dma_led_transition_timer.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; led_driver->dma_led_transition_timer.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD;
// Data // Data
led_driver->dma_led_transition_timer.Mode = LL_DMA_MODE_NORMAL; led_driver->dma_led_transition_timer.Mode = LL_DMA_MODE_NORMAL;
led_driver->dma_led_transition_timer.NbData = LED_DRIVER_BUFFER_SIZE; led_driver->dma_led_transition_timer.NbData = LED_DRIVER_BUFFER_SIZE;
@ -210,7 +211,7 @@ static void led_driver_add_period(LedDriver* led_driver, uint16_t duration_ns) {
FURI_LOG_E("Demo", "reload_value: %ld", reload_value); FURI_LOG_E("Demo", "reload_value: %ld", reload_value);
} }
furi_check(reload_value > 0); furi_check(reload_value > 0);
furi_check(reload_value < 256); furi_check(reload_value < 256 * 256);
led_driver_add_period_length(led_driver, reload_value - 1); led_driver_add_period_length(led_driver, reload_value - 1);
} }
@ -249,13 +250,15 @@ void led_driver_transmit(LedDriver* led_driver, bool transmit_if_clean) {
const uint32_t bit_set = led_driver->gpio->pin << GPIO_BSRR_BS0_Pos; const uint32_t bit_set = led_driver->gpio->pin << GPIO_BSRR_BS0_Pos;
const uint32_t bit_reset = led_driver->gpio->pin << GPIO_BSRR_BR0_Pos; const uint32_t bit_reset = led_driver->gpio->pin << GPIO_BSRR_BR0_Pos;
// Always start with HIGH // Always start with LOW (reset)
led_driver->gpio_buf[0] = bit_set; led_driver->gpio_buf[0] = bit_reset;
led_driver->gpio_buf[1] = bit_reset; led_driver->gpio_buf[1] = bit_set;
for(size_t i = 0; i < LED_DRIVER_BUFFER_SIZE; i++) { for(size_t i = 0; i < LED_DRIVER_BUFFER_SIZE; i++) {
led_driver->timer_buffer[i] = LED_DRIVER_TIMER_SETINEL; led_driver->timer_buffer[i] = LED_DRIVER_TIMER_SETINEL;
} }
led_driver_add_period(led_driver, LED_DRIVER_TRESETL);
for(size_t i = 0; i < led_driver->count_leds; i++) { for(size_t i = 0; i < led_driver->count_leds; i++) {
led_driver_add_color(led_driver, led_driver->led_data[i]); led_driver_add_color(led_driver, led_driver->led_data[i]);
} }