mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Move WS2812 driver to template class
This commit is contained in:
@@ -12,6 +12,8 @@
|
|||||||
#include "history.hpp"
|
#include "history.hpp"
|
||||||
#include "main.hpp"
|
#include "main.hpp"
|
||||||
#include <IRQ.h>
|
#include <IRQ.h>
|
||||||
|
|
||||||
|
WS2812<GPIOA_BASE,WS2812_Pin,1> ws2812;
|
||||||
volatile uint16_t PWMSafetyTimer = 0;
|
volatile uint16_t PWMSafetyTimer = 0;
|
||||||
volatile uint8_t pendingPWM = 0;
|
volatile uint8_t pendingPWM = 0;
|
||||||
uint16_t totalPWM = 255;
|
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 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; }
|
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(); }
|
void reboot() { NVIC_SystemReset(); }
|
||||||
|
|
||||||
@@ -418,23 +420,23 @@ void setStatusLED(const enum StatusLED state) {
|
|||||||
default:
|
default:
|
||||||
case LED_UNKNOWN:
|
case LED_UNKNOWN:
|
||||||
case LED_OFF:
|
case LED_OFF:
|
||||||
WS2812::led_set_color(0, 0, 0, 0);
|
ws2812.led_set_color(0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case LED_STANDBY:
|
case LED_STANDBY:
|
||||||
WS2812::led_set_color(0, 0, 0xFF, 0); // green
|
ws2812.led_set_color(0, 0, 0xFF, 0); // green
|
||||||
break;
|
break;
|
||||||
case LED_HEATING: {
|
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
|
0); // Red fade
|
||||||
} break;
|
} break;
|
||||||
case LED_HOT:
|
case LED_HOT:
|
||||||
WS2812::led_set_color(0, 0xFF, 0, 0); // red
|
ws2812.led_set_color(0, 0xFF, 0, 0); // red
|
||||||
break;
|
break;
|
||||||
case LED_COOLING_STILL_HOT:
|
case LED_COOLING_STILL_HOT:
|
||||||
WS2812::led_set_color(0, 0xFF, 0x8C, 0x00); // Orange
|
ws2812.led_set_color(0, 0xFF, 0x8C, 0x00); // Orange
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
WS2812::led_update();
|
ws2812.led_update();
|
||||||
lastState = state;
|
lastState = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* WS2812.cpp
|
|
||||||
*
|
|
||||||
* Created on: 2 May 2021
|
|
||||||
* Author: Ralim
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Pins.h"
|
|
||||||
#include <WS2812.h>
|
|
||||||
#include <string.h>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,26 +6,123 @@
|
|||||||
*/
|
*/
|
||||||
#include "Setup.h"
|
#include "Setup.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "Pins.h"
|
||||||
|
|
||||||
#ifndef CORE_DRIVERS_WS2812_H_
|
#ifndef CORE_DRIVERS_WS2812_H_
|
||||||
#define CORE_DRIVERS_WS2812_H_
|
#define CORE_DRIVERS_WS2812_H_
|
||||||
#ifndef WS2812_LED_COUNT
|
|
||||||
#define WS2812_LED_COUNT 2
|
|
||||||
#endif
|
|
||||||
#ifndef WS2812_LED_CHANNEL_COUNT
|
#ifndef WS2812_LED_CHANNEL_COUNT
|
||||||
#define WS2812_LED_CHANNEL_COUNT 3
|
#define WS2812_LED_CHANNEL_COUNT 3
|
||||||
#endif
|
#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<uint32_t LED_GPIO, uint16_t LED_PIN, int LED_COUNT> class WS2812 {
|
||||||
private:
|
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_ */
|
#endif /* CORE_DRIVERS_WS2812_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user