diff options
Diffstat (limited to 'drivers/chibios/ws2812_spi.c')
-rw-r--r-- | drivers/chibios/ws2812_spi.c | 45 |
1 files changed, 39 insertions, 6 deletions
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 | } |