GEX core repository.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
gex-core/units/neopixel/ws2812.c

83 lines
2.2 KiB

#include "platform.h"
#include "ws2812.h"
#define FREQ_STEP (PLAT_AHB_MHZ/20.0f)
#define NPX_DELAY_SHORT (uint32_t)(FREQ_STEP*1.5f)
#define NPX_DELAY_LONG (uint32_t)(FREQ_STEP*3.5f)
#define NPX_DELAY_SHOW (uint32_t)(FREQ_STEP*50)
static inline __attribute__((always_inline))
void ws2812_byte(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t b)
{
for (register volatile uint8_t i = 0; i < 8; i++) {
LL_GPIO_SetOutputPin(port, ll_pin);
// duty cycle determines bit value
if (b & 0x80) {
__asm_loop(NPX_DELAY_LONG);
LL_GPIO_ResetOutputPin(port, ll_pin);
__asm_loop(NPX_DELAY_SHORT);
} else {
__asm_loop(NPX_DELAY_SHORT);
LL_GPIO_ResetOutputPin(port, ll_pin);
__asm_loop(NPX_DELAY_LONG);
}
b <<= 1; // shift to next bit
}
}
/** Set many RGBs from packed stream */
void ws2812_load_raw(GPIO_TypeDef *port, uint32_t ll_pin, const uint8_t *rgbs, uint32_t count)
{
vPortEnterCritical();
uint8_t b, g, r;
for (uint32_t i = 0; i < count; i++) {
r = *rgbs++;
g = *rgbs++;
b = *rgbs++;
ws2812_byte(port, ll_pin, g);
ws2812_byte(port, ll_pin, r);
ws2812_byte(port, ll_pin, b);
}
vPortExitCritical();
__asm_loop(NPX_DELAY_SHOW);
}
/** Set many RGBs from uint32 stream */
void ws2812_load_sparse(GPIO_TypeDef *port, uint32_t ll_pin, const uint8_t *rgbs, uint32_t count,
bool order_bgr, bool zero_before)
{
vPortEnterCritical();
uint8_t b, g, r;
for (uint32_t i = 0; i < count; i++) {
if (zero_before) rgbs++; // skip
if (order_bgr) {
b = *rgbs++;
g = *rgbs++;
r = *rgbs++;
} else {
r = *rgbs++;
g = *rgbs++;
b = *rgbs++;
}
if (!zero_before) rgbs++; // skip
ws2812_byte(port, ll_pin, g);
ws2812_byte(port, ll_pin, r);
ws2812_byte(port, ll_pin, b);
}
vPortExitCritical();
__asm_loop(NPX_DELAY_SHOW);
}
/** Set many RGBs */
void ws2812_clear(GPIO_TypeDef *port, uint32_t ll_pin, uint32_t count)
{
vPortEnterCritical();
for (uint32_t i = 0; i < count*3; i++) {
ws2812_byte(port, ll_pin, 0);
}
vPortExitCritical();
__asm_loop(NPX_DELAY_SHOW);
}