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.
65 lines
1.4 KiB
65 lines
1.4 KiB
9 years ago
|
#include "ws2812.h"
|
||
|
#include "utils/timebase.h"
|
||
|
|
||
|
#define LONG_DELAY() for (volatile uint32_t __j = 4; __j > 0; __j--)
|
||
|
#define SHORT_DELAY() for (volatile uint32_t __j = 1; __j > 0; __j--)
|
||
|
|
||
|
static inline
|
||
|
__attribute__((always_inline))
|
||
|
void ws2812_byte(GPIO_TypeDef *GPIOx, uint16_t pin, uint8_t b)
|
||
|
{
|
||
|
for (register volatile uint8_t i = 0; i < 8; i++) {
|
||
|
GPIOx->BSRR = pin; // set pin high
|
||
|
|
||
|
// duty cycle determines bit value
|
||
|
if (b & 0x80) {
|
||
|
LONG_DELAY();
|
||
|
GPIOx->BRR = pin; // set pin low
|
||
|
SHORT_DELAY();
|
||
|
} else {
|
||
|
SHORT_DELAY();
|
||
|
GPIOx->BRR = pin; // set pin low
|
||
|
LONG_DELAY();
|
||
|
}
|
||
|
|
||
|
b <<= 1; // shift to next bit
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Set many RGBs */
|
||
|
void ws2812_send(GPIO_TypeDef *GPIOx, uint16_t pin, uint32_t *rgbs, uint32_t count)
|
||
|
{
|
||
|
__disable_irq();
|
||
|
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
uint32_t rgb = *rgbs++;
|
||
|
ws2812_byte(GPIOx, pin, rgb_g(rgb));
|
||
|
ws2812_byte(GPIOx, pin, rgb_r(rgb));
|
||
|
ws2812_byte(GPIOx, pin, rgb_b(rgb));
|
||
|
}
|
||
|
|
||
|
__enable_irq();
|
||
|
|
||
|
ws2812_flip(); // show
|
||
|
}
|
||
|
|
||
|
/** Send a single color. */
|
||
|
void ws2812_single(GPIO_TypeDef *GPIOx, uint16_t pin, uint32_t rgb)
|
||
|
{
|
||
|
__disable_irq();
|
||
|
|
||
|
ws2812_byte(GPIOx, pin, rgb_g(rgb));
|
||
|
ws2812_byte(GPIOx, pin, rgb_r(rgb));
|
||
|
ws2812_byte(GPIOx, pin, rgb_b(rgb));
|
||
|
|
||
|
__enable_irq();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Wait the necessary time for the colors sent using ws2812_single() to show.
|
||
|
*/
|
||
|
void ws2812_flip()
|
||
|
{
|
||
|
delay_us(50); // show
|
||
|
}
|