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 | } |
