parent
2093a48bed
commit
85590593ce
@ -0,0 +1,64 @@ |
|||||||
|
#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
|
||||||
|
} |
@ -0,0 +1,92 @@ |
|||||||
|
#ifndef MPORK_WS2812_H |
||||||
|
#define MPORK_WS2812_H |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
|
||||||
|
#include <common.h> |
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/ |
||||||
|
/* Exported constants --------------------------------------------------------*/ |
||||||
|
|
||||||
|
// PB8 - WS2812B data line
|
||||||
|
#define COLORLED_GPIO GPIOC |
||||||
|
#define COLORLED_PIN GPIO15 |
||||||
|
|
||||||
|
#define RGB_RED rgb(255, 0, 0) |
||||||
|
#define RGB_ORANGE rgb(255, 110, 0) |
||||||
|
#define RGB_YELLOW rgb(255, 255, 0) |
||||||
|
#define RGB_LIME rgb(160, 255, 0) |
||||||
|
#define RGB_GREEN rgb( 0, 255, 0) |
||||||
|
#define RGB_CYAN rgb( 0, 255, 120) |
||||||
|
#define RGB_BLUE rgb( 0, 0, 255) |
||||||
|
#define RGB_MAGENTA rgb(255, 0, 255) |
||||||
|
#define RGB_WHITE rgb(255, 255, 255) |
||||||
|
#define RGB_BLACK rgb( 0, 0, 0) |
||||||
|
|
||||||
|
/* Exported macros -----------------------------------------------------------*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compose an RGB color. |
||||||
|
* @param r, g, b - components 0xFF |
||||||
|
* @returns integer 0xRRGGBB |
||||||
|
*/ |
||||||
|
#define rgb(r, g, b) (((0xFF & (r)) << 16) | ((0xFF & (g)) << 8) | (0xFF & (b))) |
||||||
|
|
||||||
|
/* Get components */ |
||||||
|
#define rgb_r(rgb) (((rgb) >> 16) & 0xFF) |
||||||
|
#define rgb_g(rgb) (((rgb) >> 8) & 0xFF) |
||||||
|
#define rgb_b(rgb) ((rgb) & 0xFF) |
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Struct for easy manipulation of RGB colors. |
||||||
|
* |
||||||
|
* Set components in the xrgb.r (etc.) and you will get |
||||||
|
* the hex in xrgb.num. |
||||||
|
*/ |
||||||
|
typedef union { |
||||||
|
|
||||||
|
/** Struct for access to individual color components */ |
||||||
|
struct __attribute__((packed)) { |
||||||
|
uint8_t b; |
||||||
|
uint8_t g; |
||||||
|
uint8_t r; |
||||||
|
}; |
||||||
|
|
||||||
|
/** RGB color as a single uint32_t */ |
||||||
|
uint32_t num; |
||||||
|
|
||||||
|
} ws2812_rgb_t; |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Macro to compose the RGB struct. |
||||||
|
* |
||||||
|
* You can also use {.num = 0xFF0000} to set the hex directly. |
||||||
|
*/ |
||||||
|
#define WS2812_RGB(r, g, b) {.num = (((r) & 0xFF) << 16) | (((g) & 0xFF) << 8) | ((b) & 0xFF)} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a sequence of colors, then display it. |
||||||
|
* @param GPIOx |
||||||
|
* @param pin |
||||||
|
* @param rgbs : array of colors |
||||||
|
* @param count : array length |
||||||
|
*/ |
||||||
|
void ws2812_send(GPIO_TypeDef *GPIOx, uint16_t pin, uint32_t *rgbs, uint32_t count); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a single color. |
||||||
|
* @param GPIOx |
||||||
|
* @param pin |
||||||
|
* @param rgb : color to show |
||||||
|
*/ |
||||||
|
void ws2812_single(GPIO_TypeDef *GPIOx, uint16_t pin, uint32_t rgb); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wait the necessary time for the colors sent using ws2812_single() to show. |
||||||
|
*/ |
||||||
|
void ws2812_flip(); |
||||||
|
|
||||||
|
#endif //MPORK_WS2812_H
|
Loading…
Reference in new issue