@ -12,7 +12,7 @@
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*
*/
/** library to drive a WS2812b LED chain (code)
/** library to drive a WS2812B LED chain (code)
* @ file led_ws2812b . c
* @ author King Kévin < kingkevin @ cuvoodoo . info >
* @ date 2016
@ -32,19 +32,19 @@
# include <libopencm3/cm3/nvic.h> // interrupt handler
# include <libopencmsis/core_cm3.h> // Cortex M3 utilities
# include "led_ws2812b.h" // LED WS2812b library API
# include "led_ws2812b.h" // LED WS2812B library API
# include "global.h" // common methods
/** bit template to encode one byte to be shifted out by SPI to the WS2812b LEDs
* @ details For each WS2812b bit which needs to be transfered we require to transfer 3 SPI bits .
* The first SPI bit is the high start of the WS2812b bit frame .
* The second SPI bit determines if the WS2812b bit is a 0 or 1.
* The third SPI bit is the last part of the WS2812b bit frame , which is always low .
/** bit template to encode one byte to be shifted out by SPI to the WS2812B LEDs
* @ details For each WS2812B bit which needs to be transfered we require to transfer 3 SPI bits .
* The first SPI bit is the high start of the WS2812B bit frame .
* The second SPI bit determines if the WS2812B bit is a 0 or 1.
* The third SPI bit is the last part of the WS2812B bit frame , which is always low .
* The binary pattern is 0 b100100100100100100100100
*/
# define LED_WS2812B_SPI_TEMPLATE 0x924924
uint8_t led_ws2812b_data [ LED_WS2812B_LEDS * 3 * 3 + 40 * 3 / 8 + 1 ] = { 0 } ; /**< data encoded to be shifted out by SPI for the WS2812b , plus the 50us reset (~40 data bits) */
uint8_t led_ws2812b_data [ LED_WS2812B_LEDS * 3 * 3 + 40 * 3 / 8 + 1 ] = { 0 } ; /**< data encoded to be shifted out by SPI for the WS2812B , plus the 50us reset (~40 data bits) */
static volatile bool transmit_flag = false ; /**< flag set in software when transmission started, clear by interrupt when transmission completed */
void led_ws2812b_set_rgb ( uint16_t led , uint8_t red , uint8_t green , uint8_t blue )
@ -58,7 +58,7 @@ void led_ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue)
__WFI ( ) ;
}
const uint8_t colors [ ] = { green , red , blue } ; // color order for the WS2812b
const uint8_t colors [ ] = { green , red , blue } ; // color order for the WS2812B
const uint8_t pattern_bit [ ] = { 0x02 , 0x10 , 0x80 , 0x04 , 0x20 , 0x01 , 0x08 , 0x40 } ; // which bit to change in the pattern
const uint8_t pattern_byte [ ] = { 2 , 2 , 2 , 1 , 1 , 0 , 0 , 0 } ; // in which byte in the pattern to write the pattern bit
for ( uint8_t color = 0 ; color < LENGTH ( colors ) ; color + + ) { // colors are encoded similarly
@ -106,7 +106,7 @@ void led_ws2812b_setup(void)
timer_set_oc_mode ( LED_WS2812B_TIMER , LED_WS2812B_TIMER_OC , TIM_OCM_PWM1 ) ; // set timer to generate PWM (used as clock)
timer_enable_oc_output ( LED_WS2812B_TIMER , LED_WS2812B_TIMER_OC ) ; // enable output to generate the clock
// setup SPI to transmit data (we are slave and the clock comes from the above PWM): 3 SPI bits for 1 WS2812b bit
// setup SPI to transmit data (we are slave and the clock comes from the above PWM): 3 SPI bits for 1 WS2812B bit
rcc_periph_clock_enable ( LED_WS2812B_SPI_PORT_RCC ) ; // enable clock for SPI IO peripheral
gpio_set_mode ( LED_WS2812B_SPI_PORT , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , LED_WS2812B_SPI_CLK ) ; // set clock as input
gpio_set_mode ( LED_WS2812B_SPI_PORT , GPIO_MODE_OUTPUT_10_MHZ , GPIO_CNF_OUTPUT_ALTFN_PUSHPULL , LED_WS2812B_SPI_DOUT ) ; // set MISO as output
@ -125,7 +125,7 @@ void led_ws2812b_setup(void)
spi_enable ( LED_WS2812B_SPI ) ; // enable SPI
// do not disable SPI or set NSS high since it will put MISO high, breaking the beginning of the next transmission
// configure DMA to provide the pattern to be shifted out from SPI to the WS2812b LEDs
// configure DMA to provide the pattern to be shifted out from SPI to the WS2812B LEDs
rcc_periph_clock_enable ( LED_WS2812B_DMA_RCC ) ; // enable clock for DMA peripheral
dma_channel_reset ( LED_WS2812B_DMA , LED_WS2812B_DMA_CH ) ; // start with fresh channel configuration
dma_set_memory_address ( LED_WS2812B_DMA , LED_WS2812B_DMA_CH , ( uint32_t ) led_ws2812b_data ) ; // set bit pattern as source address