diff options
Diffstat (limited to 'drivers/chibios')
-rw-r--r-- | drivers/chibios/ws2812_pwm.c | 11 | ||||
-rw-r--r-- | drivers/chibios/ws2812_spi.c | 45 |
2 files changed, 49 insertions, 7 deletions
diff --git a/drivers/chibios/ws2812_pwm.c b/drivers/chibios/ws2812_pwm.c index 140120d48..e6af55b6b 100644 --- a/drivers/chibios/ws2812_pwm.c +++ b/drivers/chibios/ws2812_pwm.c | |||
@@ -27,6 +27,15 @@ | |||
27 | # error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM?_UP" | 27 | # error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM?_UP" |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | #ifndef WS2812_PWM_COMPLEMENTARY_OUTPUT | ||
31 | # define WS2812_PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_HIGH | ||
32 | #else | ||
33 | # if !STM32_PWM_USE_ADVANCED | ||
34 | # error "WS2812_PWM_COMPLEMENTARY_OUTPUT requires STM32_PWM_USE_ADVANCED == TRUE" | ||
35 | # endif | ||
36 | # define WS2812_PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH | ||
37 | #endif | ||
38 | |||
30 | // Push Pull or Open Drain Configuration | 39 | // Push Pull or Open Drain Configuration |
31 | // Default Push Pull | 40 | // Default Push Pull |
32 | #ifndef WS2812_EXTERNAL_PULLUP | 41 | #ifndef WS2812_EXTERNAL_PULLUP |
@@ -247,7 +256,7 @@ void ws2812_init(void) { | |||
247 | .channels = | 256 | .channels = |
248 | { | 257 | { |
249 | [0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled | 258 | [0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled |
250 | [WS2812_PWM_CHANNEL - 1] = {.mode = PWM_OUTPUT_ACTIVE_HIGH, .callback = NULL}, // Turn on the channel we care about | 259 | [WS2812_PWM_CHANNEL - 1] = {.mode = WS2812_PWM_OUTPUT_MODE, .callback = NULL}, // Turn on the channel we care about |
251 | }, | 260 | }, |
252 | .cr2 = 0, | 261 | .cr2 = 0, |
253 | .dier = TIM_DIER_UDE, // DMA on update event for next period | 262 | .dier = TIM_DIER_UDE, // DMA on update event for next period |
diff --git a/drivers/chibios/ws2812_spi.c b/drivers/chibios/ws2812_spi.c index 89df2987b..e02cbabc0 100644 --- a/drivers/chibios/ws2812_spi.c +++ b/drivers/chibios/ws2812_spi.c | |||
@@ -32,6 +32,37 @@ | |||
32 | # endif | 32 | # endif |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | // Define SPI config speed | ||
36 | // baudrate should target 3.2MHz | ||
37 | // F072 fpclk = 48MHz | ||
38 | // 48/16 = 3Mhz | ||
39 | #if WS2812_SPI_DIVISOR == 2 | ||
40 | # define WS2812_SPI_DIVISOR (0) | ||
41 | #elif WS2812_SPI_DIVISOR == 4 | ||
42 | # define WS2812_SPI_DIVISOR (SPI_CR1_BR_0) | ||
43 | #elif WS2812_SPI_DIVISOR == 8 | ||
44 | # define WS2812_SPI_DIVISOR (SPI_CR1_BR_1) | ||
45 | #elif WS2812_SPI_DIVISOR == 16 // same as default | ||
46 | # define WS2812_SPI_DIVISOR (SPI_CR1_BR_1 | SPI_CR1_BR_0) | ||
47 | #elif WS2812_SPI_DIVISOR == 32 | ||
48 | # define WS2812_SPI_DIVISOR (SPI_CR1_BR_2) | ||
49 | #elif WS2812_SPI_DIVISOR == 64 | ||
50 | # define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_0) | ||
51 | #elif WS2812_SPI_DIVISOR == 128 | ||
52 | # define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_1) | ||
53 | #elif WS2812_SPI_DIVISOR == 256 | ||
54 | # define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0) | ||
55 | #else | ||
56 | # define WS2812_SPI_DIVISOR (SPI_CR1_BR_1 | SPI_CR1_BR_0) // default | ||
57 | #endif | ||
58 | |||
59 | // Use SPI circular buffer | ||
60 | #ifdef WS2812_SPI_USE_CIRCULAR_BUFFER | ||
61 | # define WS2812_SPI_BUFFER_MODE 1 // circular buffer | ||
62 | #else | ||
63 | # define WS2812_SPI_BUFFER_MODE 0 // normal buffer | ||
64 | #endif | ||
65 | |||
35 | #define BYTES_FOR_LED_BYTE 4 | 66 | #define BYTES_FOR_LED_BYTE 4 |
36 | #define NB_COLORS 3 | 67 | #define NB_COLORS 3 |
37 | #define BYTES_FOR_LED (BYTES_FOR_LED_BYTE * NB_COLORS) | 68 | #define BYTES_FOR_LED (BYTES_FOR_LED_BYTE * NB_COLORS) |
@@ -81,14 +112,14 @@ void ws2812_init(void) { | |||
81 | palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); | 112 | palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); |
82 | 113 | ||
83 | // TODO: more dynamic baudrate | 114 | // TODO: more dynamic baudrate |
84 | static const SPIConfig spicfg = { | 115 | static const SPIConfig spicfg = {WS2812_SPI_BUFFER_MODE, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN), WS2812_SPI_DIVISOR}; |
85 | 0, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN), | ||
86 | SPI_CR1_BR_1 | SPI_CR1_BR_0 // baudrate : fpclk / 8 => 1tick is 0.32us (2.25 MHz) | ||
87 | }; | ||
88 | 116 | ||
89 | spiAcquireBus(&WS2812_SPI); /* Acquire ownership of the bus. */ | 117 | spiAcquireBus(&WS2812_SPI); /* Acquire ownership of the bus. */ |
90 | spiStart(&WS2812_SPI, &spicfg); /* Setup transfer parameters. */ | 118 | spiStart(&WS2812_SPI, &spicfg); /* Setup transfer parameters. */ |
91 | spiSelect(&WS2812_SPI); /* Slave Select assertion. */ | 119 | spiSelect(&WS2812_SPI); /* Slave Select assertion. */ |
120 | #ifdef WS2812_SPI_USE_CIRCULAR_BUFFER | ||
121 | spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); | ||
122 | #endif | ||
92 | } | 123 | } |
93 | 124 | ||
94 | void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) { | 125 | void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) { |
@@ -104,9 +135,11 @@ void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) { | |||
104 | 135 | ||
105 | // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues. | 136 | // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues. |
106 | // Instead spiSend can be used to send synchronously (or the thread logic can be added back). | 137 | // Instead spiSend can be used to send synchronously (or the thread logic can be added back). |
107 | #ifdef WS2812_SPI_SYNC | 138 | #ifndef WS2812_SPI_USE_CIRCULAR_BUFFER |
139 | # ifdef WS2812_SPI_SYNC | ||
108 | spiSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); | 140 | spiSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); |
109 | #else | 141 | # else |
110 | spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); | 142 | spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); |
143 | # endif | ||
111 | #endif | 144 | #endif |
112 | } | 145 | } |