From bdeb8ef38a2e866907debdc47d35f797990dce70 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Tue, 4 May 2021 18:37:09 +1000 Subject: [PATCH] Move WS2812 driver to template class --- source/Core/BSP/MHP30/BSP.cpp | 16 +++-- source/Core/Drivers/WS2812.cpp | 107 ----------------------------- source/Core/Drivers/WS2812.h | 119 ++++++++++++++++++++++++++++++--- 3 files changed, 117 insertions(+), 125 deletions(-) delete mode 100644 source/Core/Drivers/WS2812.cpp diff --git a/source/Core/BSP/MHP30/BSP.cpp b/source/Core/BSP/MHP30/BSP.cpp index a134d6cd..1722c1c3 100644 --- a/source/Core/BSP/MHP30/BSP.cpp +++ b/source/Core/BSP/MHP30/BSP.cpp @@ -12,6 +12,8 @@ #include "history.hpp" #include "main.hpp" #include + +WS2812 ws2812; volatile uint16_t PWMSafetyTimer = 0; volatile uint8_t pendingPWM = 0; uint16_t totalPWM = 255; @@ -325,7 +327,7 @@ void unstick_I2C() { uint8_t getButtonA() { return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ? 1 : 0; } uint8_t getButtonB() { return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ? 1 : 0; } -void BSPInit(void) { WS2812::init(); } +void BSPInit(void) { ws2812.init(); } void reboot() { NVIC_SystemReset(); } @@ -418,23 +420,23 @@ void setStatusLED(const enum StatusLED state) { default: case LED_UNKNOWN: case LED_OFF: - WS2812::led_set_color(0, 0, 0, 0); + ws2812.led_set_color(0, 0, 0, 0); break; case LED_STANDBY: - WS2812::led_set_color(0, 0, 0xFF, 0); // green + ws2812.led_set_color(0, 0, 0xFF, 0); // green break; case LED_HEATING: { - WS2812::led_set_color(0, ((HAL_GetTick() / 10) % 192) + 64, 0, + ws2812.led_set_color(0, ((HAL_GetTick() / 10) % 192) + 64, 0, 0); // Red fade } break; case LED_HOT: - WS2812::led_set_color(0, 0xFF, 0, 0); // red + ws2812.led_set_color(0, 0xFF, 0, 0); // red break; case LED_COOLING_STILL_HOT: - WS2812::led_set_color(0, 0xFF, 0x8C, 0x00); // Orange + ws2812.led_set_color(0, 0xFF, 0x8C, 0x00); // Orange break; } - WS2812::led_update(); + ws2812.led_update(); lastState = state; } } diff --git a/source/Core/Drivers/WS2812.cpp b/source/Core/Drivers/WS2812.cpp deleted file mode 100644 index faca4b83..00000000 --- a/source/Core/Drivers/WS2812.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * WS2812.cpp - * - * Created on: 2 May 2021 - * Author: Ralim - */ - -#include "Pins.h" -#include -#include -uint8_t WS2812::leds_colors[WS2812_LED_CHANNEL_COUNT * WS2812_LED_COUNT]; - -void WS2812::init(void) { memset(leds_colors, 0, sizeof(leds_colors)); } - -void WS2812::led_update() { - __disable_irq(); - // Bitbang it out as our cpu irq latency is too high - for (unsigned int i = 0; i < sizeof(leds_colors); i++) { - // Shove out MSB first - for (int x = 0; x < 8; x++) { - WS2812_GPIO_Port->BSRR = WS2812_Pin; - if ((leds_colors[i] & (1 << (7 - x))) == (1 << (7 - x))) { - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - } else { - - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - } - WS2812_GPIO_Port->BSRR = (uint32_t)WS2812_Pin << 16u; - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - __asm__ __volatile__("nop"); - } - } - __enable_irq(); -} - -void WS2812::led_set_color(size_t index, uint8_t r, uint8_t g, uint8_t b) { - leds_colors[index * WS2812_LED_CHANNEL_COUNT + 0] = g; - leds_colors[index * WS2812_LED_CHANNEL_COUNT + 1] = r; - leds_colors[index * WS2812_LED_CHANNEL_COUNT + 2] = b; -} - -void WS2812::led_set_color_all(uint8_t r, uint8_t g, uint8_t b) { - for (int index = 0; index < WS2812_LED_COUNT; index++) { - leds_colors[index * WS2812_LED_CHANNEL_COUNT + 0] = g; - leds_colors[index * WS2812_LED_CHANNEL_COUNT + 1] = r; - leds_colors[index * WS2812_LED_CHANNEL_COUNT + 2] = b; - } -} diff --git a/source/Core/Drivers/WS2812.h b/source/Core/Drivers/WS2812.h index 12897798..c40b9d8b 100644 --- a/source/Core/Drivers/WS2812.h +++ b/source/Core/Drivers/WS2812.h @@ -6,26 +6,123 @@ */ #include "Setup.h" #include +#include #include +#include "Pins.h" #ifndef CORE_DRIVERS_WS2812_H_ #define CORE_DRIVERS_WS2812_H_ -#ifndef WS2812_LED_COUNT -#define WS2812_LED_COUNT 2 -#endif + #ifndef WS2812_LED_CHANNEL_COUNT #define WS2812_LED_CHANNEL_COUNT 3 #endif -#define WS2812_RAW_BYTES_PER_LED (WS2812_LED_CHANNEL_COUNT * 8) -class WS2812 { -public: - static void init(void); - static void led_update(); - static void led_set_color(size_t index, uint8_t r, uint8_t g, uint8_t b); - static void led_set_color_all(uint8_t r, uint8_t g, uint8_t b); +#define WS2812_RAW_BYTES_PER_LED (WS2812_LED_CHANNEL_COUNT * 8) + +template class WS2812 { private: - static uint8_t leds_colors[WS2812_LED_CHANNEL_COUNT * WS2812_LED_COUNT]; + uint8_t leds_colors[WS2812_LED_CHANNEL_COUNT * LED_COUNT]; +public: + + void led_update() { + __disable_irq(); + // Bitbang it out as our cpu irq latency is too high + for (unsigned int i = 0; i < sizeof(leds_colors); i++) { + // Shove out MSB first + for (int x = 0; x < 8; x++) { + ((GPIO_TypeDef*) WS2812_GPIO_Port)->BSRR = WS2812_Pin; + if ((leds_colors[i] & (1 << (7 - x))) == (1 << (7 - x))) { + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + } else { + + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + } + ((GPIO_TypeDef*) WS2812_GPIO_Port)->BSRR = (uint32_t) WS2812_Pin + << 16u; + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + __asm__ __volatile__("nop"); + } + } + __enable_irq(); + } + + void init(void) { + memset(leds_colors, 0, sizeof(leds_colors)); + } + + void led_set_color(size_t index, uint8_t r, uint8_t g, uint8_t b) { + leds_colors[index * WS2812_LED_CHANNEL_COUNT + 0] = g; + leds_colors[index * WS2812_LED_CHANNEL_COUNT + 1] = r; + leds_colors[index * WS2812_LED_CHANNEL_COUNT + 2] = b; + } + + void led_set_color_all(uint8_t r, uint8_t g, uint8_t b) { + for (int index = 0; index < LED_COUNT; index++) { + leds_colors[index * WS2812_LED_CHANNEL_COUNT + 0] = g; + leds_colors[index * WS2812_LED_CHANNEL_COUNT + 1] = r; + leds_colors[index * WS2812_LED_CHANNEL_COUNT + 2] = b; + } + } + }; #endif /* CORE_DRIVERS_WS2812_H_ */