fix name to WS2812B
This commit is contained in:
parent
53235e5394
commit
2d26686233
|
@ -12,7 +12,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* 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
|
* @file led_ws2812b.c
|
||||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||||
* @date 2016
|
* @date 2016
|
||||||
|
@ -32,19 +32,19 @@
|
||||||
#include <libopencm3/cm3/nvic.h> // interrupt handler
|
#include <libopencm3/cm3/nvic.h> // interrupt handler
|
||||||
#include <libopencmsis/core_cm3.h> // Cortex M3 utilities
|
#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
|
#include "global.h" // common methods
|
||||||
|
|
||||||
/** bit template to encode one byte to be shifted out by SPI to the WS2812b LEDs
|
/** 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.
|
* @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 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 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 third SPI bit is the last part of the WS2812B bit frame, which is always low.
|
||||||
* The binary pattern is 0b100100100100100100100100
|
* The binary pattern is 0b100100100100100100100100
|
||||||
*/
|
*/
|
||||||
#define LED_WS2812B_SPI_TEMPLATE 0x924924
|
#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 */
|
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)
|
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();
|
__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_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
|
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
|
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_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
|
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
|
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_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
|
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
|
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
|
// 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
|
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_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
|
dma_set_memory_address(LED_WS2812B_DMA, LED_WS2812B_DMA_CH, (uint32_t)led_ws2812b_data); // set bit pattern as source address
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/** library to drive a WS2812b LED chain (API)
|
/** library to drive a WS2812B LED chain (API)
|
||||||
* @file led_ws2812b.h
|
* @file led_ws2812b.h
|
||||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||||
* @date 2016
|
* @date 2016
|
||||||
|
@ -20,11 +20,11 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/** number of LEDs on the WS2812b strip */
|
/** number of LEDs on the WS2812B strip */
|
||||||
#define LED_WS2812B_LEDS 48
|
#define LED_WS2812B_LEDS 48
|
||||||
|
|
||||||
/** peripheral configuration */
|
/** peripheral configuration */
|
||||||
/** @defgroup led_ws2812b_spi SPI peripheral used to control the WS2812b LEDs
|
/** @defgroup led_ws2812b_spi SPI peripheral used to control the WS2812B LEDs
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define LED_WS2812B_SPI SPI1 /**< SPI peripheral */
|
#define LED_WS2812B_SPI SPI1 /**< SPI peripheral */
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
#define LED_WS2812B_SPI_PORT_RCC RCC_GPIOA /**< SPI I/O peripheral clock */
|
#define LED_WS2812B_SPI_PORT_RCC RCC_GPIOA /**< SPI I/O peripheral clock */
|
||||||
#define LED_WS2812B_SPI_PORT GPIOA /**< SPI port */
|
#define LED_WS2812B_SPI_PORT GPIOA /**< SPI port */
|
||||||
#define LED_WS2812B_SPI_CLK GPIO_SPI1_SCK /**< SPI clock pin (PA5), connect to PWM output */
|
#define LED_WS2812B_SPI_CLK GPIO_SPI1_SCK /**< SPI clock pin (PA5), connect to PWM output */
|
||||||
#define LED_WS2812B_SPI_DOUT GPIO_SPI1_MISO /**< SPI data pin (PA6), connect to WS2812b DIN */
|
#define LED_WS2812B_SPI_DOUT GPIO_SPI1_MISO /**< SPI data pin (PA6), connect to WS2812B DIN */
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @defgroup led_ws2812b_timer timer peripheral used to generate SPI clock
|
/** @defgroup led_ws2812b_timer timer peripheral used to generate SPI clock
|
||||||
* @{
|
* @{
|
||||||
|
@ -48,14 +48,14 @@
|
||||||
/** @defgroup led_ws2812b_dma DMA peripheral used to send the data
|
/** @defgroup led_ws2812b_dma DMA peripheral used to send the data
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define LED_WS2812B_DMA DMA1 /**< DMA peripheral to put data for WS2812b LED in SPI queue (only DMA1 supports SPI1_TX interrupt) */
|
#define LED_WS2812B_DMA DMA1 /**< DMA peripheral to put data for WS2812B LED in SPI queue (only DMA1 supports SPI1_TX interrupt) */
|
||||||
#define LED_WS2812B_DMA_RCC RCC_DMA1 /**< DMA peripheral clock */
|
#define LED_WS2812B_DMA_RCC RCC_DMA1 /**< DMA peripheral clock */
|
||||||
#define LED_WS2812B_DMA_CH DMA_CHANNEL3 /**< DMA channel (only DMA1 channel 3 supports SPI1_TX interrupt) */
|
#define LED_WS2812B_DMA_CH DMA_CHANNEL3 /**< DMA channel (only DMA1 channel 3 supports SPI1_TX interrupt) */
|
||||||
#define LED_WS2812B_DMA_IRQ NVIC_DMA1_CHANNEL3_IRQ /**< DMA channel interrupt signal */
|
#define LED_WS2812B_DMA_IRQ NVIC_DMA1_CHANNEL3_IRQ /**< DMA channel interrupt signal */
|
||||||
#define LED_WS2812B_DMA_ISR dma1_channel3_isr /**< DMA channel interrupt service routine */
|
#define LED_WS2812B_DMA_ISR dma1_channel3_isr /**< DMA channel interrupt service routine */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** setup WS2812b LED driver */
|
/** setup WS2812B LED driver */
|
||||||
void led_ws2812b_setup(void);
|
void led_ws2812b_setup(void);
|
||||||
/** set color of a single LED
|
/** set color of a single LED
|
||||||
* @param[in] led the LED number to set the color
|
* @param[in] led the LED number to set the color
|
||||||
|
@ -65,7 +65,7 @@ void led_ws2812b_setup(void);
|
||||||
* @note transmission needs to be done separately
|
* @note transmission needs to be done separately
|
||||||
*/
|
*/
|
||||||
void led_ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue);
|
void led_ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue);
|
||||||
/** transmit color values to WS2812b LEDs
|
/** transmit color values to WS2812B LEDs
|
||||||
* @return true if transmission started, false if another transmission is already ongoing
|
* @return true if transmission started, false if another transmission is already ongoing
|
||||||
*/
|
*/
|
||||||
bool led_ws2812b_transmit(void);
|
bool led_ws2812b_transmit(void);
|
||||||
|
|
12
main.c
12
main.c
|
@ -41,7 +41,7 @@
|
||||||
#include "global.h" // board definitions
|
#include "global.h" // board definitions
|
||||||
#include "usart.h" // USART utilities
|
#include "usart.h" // USART utilities
|
||||||
#include "usb_cdcacm.h" // USB CDC ACM utilities
|
#include "usb_cdcacm.h" // USB CDC ACM utilities
|
||||||
#include "led_ws2812b.h" // WS2812b LEDs utilities
|
#include "led_ws2812b.h" // WS2812B LEDs utilities
|
||||||
#include "rtc_ds1307.h" // Real Time Clock DS1307 utilities
|
#include "rtc_ds1307.h" // Real Time Clock DS1307 utilities
|
||||||
#include "rtc_dcf77.h" // DCF77 time receiver utilities
|
#include "rtc_dcf77.h" // DCF77 time receiver utilities
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ const uint32_t ticks_midday = 12*60*60*TICKS_PER_SECOND;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
/** RGB values for the WS2812b clock LEDs */
|
/** RGB values for the WS2812B clock LEDs */
|
||||||
uint8_t clock_leds[LED_WS2812B_LEDS*3] = {0};
|
uint8_t clock_leds[LED_WS2812B_LEDS*3] = {0};
|
||||||
/** user input command */
|
/** user input command */
|
||||||
char command[32] = {0};
|
char command[32] = {0};
|
||||||
|
@ -255,8 +255,8 @@ static void clock_show_time(uint32_t time)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** set the LEDs
|
/** set the LEDs
|
||||||
* @details set the LED colors on WS2812b LEDs
|
* @details set the LED colors on WS2812B LEDs
|
||||||
* @note WS2812b LED color values need to be transmitted separately
|
* @note WS2812B LED color values need to be transmitted separately
|
||||||
*/
|
*/
|
||||||
static void clock_leds_set(void)
|
static void clock_leds_set(void)
|
||||||
{
|
{
|
||||||
|
@ -442,12 +442,12 @@ int main(void)
|
||||||
rtc_dcf77_on(); // switch on DCF77 module to get correct time
|
rtc_dcf77_on(); // switch on DCF77 module to get correct time
|
||||||
printf("OK\n");
|
printf("OK\n");
|
||||||
|
|
||||||
// setup WS2812b LEDs
|
// setup WS2812B LEDs
|
||||||
printf("setup LEDs: ");
|
printf("setup LEDs: ");
|
||||||
for (uint16_t i=0; i<LENGTH(gamma_correction_lut); i++) { // generate gamma correction table
|
for (uint16_t i=0; i<LENGTH(gamma_correction_lut); i++) { // generate gamma correction table
|
||||||
gamma_correction_lut[i] = powf((float)i / (float)LENGTH(gamma_correction_lut), 2.2)*LENGTH(gamma_correction_lut); // calculate using fixed gamma value
|
gamma_correction_lut[i] = powf((float)i / (float)LENGTH(gamma_correction_lut), 2.2)*LENGTH(gamma_correction_lut); // calculate using fixed gamma value
|
||||||
}
|
}
|
||||||
led_ws2812b_setup(); // setup WS2812b LEDs
|
led_ws2812b_setup(); // setup WS2812B LEDs
|
||||||
clock_clear(); // clear all LEDs
|
clock_clear(); // clear all LEDs
|
||||||
clock_leds_set(); // set the colors of all LEDs
|
clock_leds_set(); // set the colors of all LEDs
|
||||||
led_ws2812b_transmit(); // transmit set color
|
led_ws2812b_transmit(); // transmit set color
|
||||||
|
|
Loading…
Reference in New Issue