diff options
| author | Xelus22 <17491233+Xelus22@users.noreply.github.com> | 2021-03-19 08:29:18 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-19 19:29:18 +1100 |
| commit | 6f7466b6dd72e161b61683e26b7720421d8cc9bd (patch) | |
| tree | 7cbe7eb4a049fc57eb3c3e71e6c8f5397d49e2fc /drivers | |
| parent | f2715a05939b749771d9826f9ad23b4cab280e82 (diff) | |
| download | qmk_firmware-6f7466b6dd72e161b61683e26b7720421d8cc9bd.tar.gz qmk_firmware-6f7466b6dd72e161b61683e26b7720421d8cc9bd.zip | |
ARM WS2812 SPI config (baudrate and circular buffer) (#12216)
* initial commit
* include circular buffer command
* add endif
* circular buffer mode
* remove untrue comment
* revamp and add documentation
* do not allow WS2812_SPI_SYNC & CIRCULAR_BUFFER
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/chibios/ws2812_spi.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/drivers/chibios/ws2812_spi.c b/drivers/chibios/ws2812_spi.c index 89df2987b..bc0a54acc 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) |
| @@ -82,13 +113,16 @@ void ws2812_init(void) { | |||
| 82 | 113 | ||
| 83 | // TODO: more dynamic baudrate | 114 | // TODO: more dynamic baudrate |
| 84 | static const SPIConfig spicfg = { | 115 | static const SPIConfig spicfg = { |
| 85 | 0, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN), | 116 | WS2812_SPI_BUFFER_MODE, 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) | 117 | WS2812_SPI_DIVISOR |
| 87 | }; | 118 | }; |
| 88 | 119 | ||
| 89 | spiAcquireBus(&WS2812_SPI); /* Acquire ownership of the bus. */ | 120 | spiAcquireBus(&WS2812_SPI); /* Acquire ownership of the bus. */ |
| 90 | spiStart(&WS2812_SPI, &spicfg); /* Setup transfer parameters. */ | 121 | spiStart(&WS2812_SPI, &spicfg); /* Setup transfer parameters. */ |
| 91 | spiSelect(&WS2812_SPI); /* Slave Select assertion. */ | 122 | spiSelect(&WS2812_SPI); /* Slave Select assertion. */ |
| 123 | #ifdef WS2812_SPI_USE_CIRCULAR_BUFFER | ||
| 124 | spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); | ||
| 125 | #endif | ||
| 92 | } | 126 | } |
| 93 | 127 | ||
| 94 | void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) { | 128 | void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) { |
| @@ -104,9 +138,11 @@ void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) { | |||
| 104 | 138 | ||
| 105 | // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues. | 139 | // 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). | 140 | // Instead spiSend can be used to send synchronously (or the thread logic can be added back). |
| 107 | #ifdef WS2812_SPI_SYNC | 141 | #ifndef WS2812_SPI_USE_CIRCULAR_BUFFER |
| 142 | # ifdef WS2812_SPI_SYNC | ||
| 108 | spiSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); | 143 | spiSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); |
| 109 | #else | 144 | # else |
| 110 | spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); | 145 | spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf); |
| 146 | # endif | ||
| 111 | #endif | 147 | #endif |
| 112 | } | 148 | } |
