diff --git a/lib/led_ws2812b.c b/lib/led_ws2812b.c index 8515e3d..7f737a3 100644 --- a/lib/led_ws2812b.c +++ b/lib/led_ws2812b.c @@ -13,10 +13,10 @@ * */ /** @brief library to drive a WS2812b LED chain (code) - * @file led_ws2812b.c + * @file led_led_ws2812b.c * @author King Kévin * @date 2016 - * @note peripherals used: SPI @ref led_ws2812b_spi, timer @ref led_ws2812b_timer, DMA @ref led_ws2812b_dma + * @note peripherals used: SPI @ref led_led_ws2812b_spi, timer @ref led_led_ws2812b_timer, DMA @ref led_led_ws2812b_dma */ /* standard libraries */ @@ -35,37 +35,6 @@ #include "led_ws2812b.h" // LED WS2812b library API #include "global.h" // common methods -/** peripheral configuration */ -/** @defgroup led_ws2812b_spi SPI peripheral used to control the WS2812b LEDs - * @{ - */ -#define WS2812B_SPI SPI1 /**< SPI peripheral */ -#define WS2812B_SPI_DR SPI1_DR /**< SPI data register for the DMA */ -#define WS2812B_SPI_RCC RCC_SPI1 /**< SPI peripheral clock */ -#define WS2812B_SPI_PORT GPIOA /**< SPI port */ -#define WS2812B_SPI_CLK GPIO_SPI1_SCK /**< SPI clock pin (PA5), connect to PWM output */ -#define 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 - * @{ - */ -#define WS2812B_TIMER TIM3 /**< timer peripheral */ -#define WS2812B_TIMER_RCC RCC_TIM3 /**< timer peripheral clock */ -#define WS2812B_TIMER_OC TIM_OC3 /**< timer output compare used to set PWM frequency */ -#define WS2812B_CLK_RCC RCC_GPIOB /**< timer port peripheral clock */ -#define WS2812B_CLK_PORT GPIOB /**< timer port */ -#define WS2812B_CLK_PIN GPIO_TIM3_CH3 /**< timer pin to output PWM (PB0), connect to SPI clock input */ -/** @} */ -/** @defgroup led_ws2812b_dma DMA peripheral used to send the data - * @{ - */ -#define WS2812B_DMA DMA1 /**< DMA peripheral to put data for WS2812b LED in SPI queue (only DMA1 supports SPI1_TX interrupt) */ -#define WS2812B_DMA_RCC RCC_DMA1 /**< DMA peripheral clock */ -#define WS2812B_DMA_CH DMA_CHANNEL3 /**< DMA channel (only DMA1 channel 3 supports SPI1_TX interrupt) */ -#define WS2812B_DMA_IRQ NVIC_DMA1_CHANNEL3_IRQ /**< DMA channel interrupt signal */ -#define WS2812B_DMA_ISR dma1_channel3_isr /**< DMA channel interrupt service routine */ -/** @} */ - /** @brief 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. @@ -73,15 +42,15 @@ * The third SPI bit is the last part of the WS2812b bit frame, which is always low. * The binary pattern is 0b100100100100100100100100 */ -#define WS2812B_SPI_TEMPLATE 0x924924 +#define LED_WS2812B_SPI_TEMPLATE 0x924924 -uint8_t ws2812b_data[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 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) { // verify the led exists - if (led>=WS2812B_LEDS) { + if (led>=LED_WS2812B_LEDS) { return; } // wait for transmission to complete before changing the color @@ -96,99 +65,99 @@ void ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue) // fill the middle bit (fixed is faster than calculating it) for (uint8_t bit=0; bit<8; bit++) { // bit from the color to set/clear if (colors[color]&(1<>16); - ws2812b_data[i*3+1] = (uint8_t)(WS2812B_SPI_TEMPLATE>>8); - ws2812b_data[i*3+2] = (uint8_t)(WS2812B_SPI_TEMPLATE>>0); + for (uint16_t i=0; i>16); + led_ws2812b_data[i*3+1] = (uint8_t)(LED_WS2812B_SPI_TEMPLATE>>8); + led_ws2812b_data[i*3+2] = (uint8_t)(LED_WS2812B_SPI_TEMPLATE>>0); } // fill remaining with with 0 to encode the reset code - for (uint16_t i=WS2812B_LEDS*3*3; i=WS2812B_LEDS*256 || led_minute>=WS2812B_LEDS*256) { // a calculation error occurred + uint32_t led_hour = (LED_WS2812B_LEDS*(256*(uint64_t)(time%ticks_midday)))/ticks_midday; // scale to LED brightnesses for hours + uint32_t led_minute = (LED_WS2812B_LEDS*(256*(uint64_t)(time%ticks_hour)))/ticks_hour; // scale to LED brightnesses for minutes + if (led_hour>=LED_WS2812B_LEDS*256 || led_minute>=LED_WS2812B_LEDS*256) { // a calculation error occurred return; } // show hours and minutes on LEDs if (led_hour>led_minute) { // show hours in blue (and clear other LEDs) - for (uint16_t led=0; led=0xff) { // full hours @@ -190,7 +190,7 @@ static void clock_show_time(uint32_t time) led_hour -= clock_leds[led*3+2]; } // show minutes in green (override hours) - for (uint16_t led=0; led0; led++) { + for (uint16_t led=0; led0; led++) { clock_leds[led*3+0] = 0; if (led_minute>=0xff) { // full minutes clock_leds[led*3+1] = 0xff; @@ -202,7 +202,7 @@ static void clock_show_time(uint32_t time) } } else { // show minutes in green (and clear other LEDs) - for (uint16_t led=0; led=0xff) { // full minutes clock_leds[led*3+1] = 0xff; @@ -213,7 +213,7 @@ static void clock_show_time(uint32_t time) clock_leds[led*3+2] = 0; } // show hours in blue (override minutes) - for (uint16_t led=0; led0; led++) { + for (uint16_t led=0; led0; led++) { clock_leds[led*3+0] = 0; clock_leds[led*3+1] = 0; if (led_hour>=0xff) { // full hours @@ -228,15 +228,15 @@ static void clock_show_time(uint32_t time) if (time%ticks_minute==0) { return; } - uint32_t led_second = (WS2812B_LEDS*(256*(uint64_t)(time%ticks_minute)))/ticks_minute; // scale to LED brightnesses for seconds + uint32_t led_second = (LED_WS2812B_LEDS*(256*(uint64_t)(time%ticks_minute)))/ticks_minute; // scale to LED brightnesses for seconds uint8_t brightness_second = led_second%256; // get brightness for seconds for last LED - uint16_t second_led = (WS2812B_LEDS*(time%ticks_minute))/ticks_minute; // get LED for seconds (we only use the last LED as runner instead of all LEDs as arc) + uint16_t second_led = (LED_WS2812B_LEDS*(time%ticks_minute))/ticks_minute; // get LED for seconds (we only use the last LED as runner instead of all LEDs as arc) // set seconds LED clock_leds[second_led*3+0] = brightness_second; //clock_leds[second_led*3+1] = 0; // clear other colors (minutes/hours indication) //clock_leds[second_led*3+2] = 0; // clear other colors (minutes/hours indication) // set previous seconds LED - second_led = ((second_led==0) ? WS2812B_LEDS-1 : second_led-1); // previous LED + second_led = ((second_led==0) ? LED_WS2812B_LEDS-1 : second_led-1); // previous LED clock_leds[second_led*3+0] = 0xff-brightness_second; //clock_leds[second_led*3+1] = 0; // clear other colors (minutes/hours indication) //clock_leds[second_led*3+2] = 0; // clear other colors (minutes/hours indication) @@ -249,7 +249,7 @@ static void clock_show_time(uint32_t time) static void clock_leds_set(void) { for (uint16_t i=0; i255 ? 512-i-1 : i); // get fade brightness for (uint8_t hour=0; hour<12; hour++) { // set all hour colors - uint16_t led = WS2812B_LEDS/12*hour; // get LED four hour mark + uint16_t led = LED_WS2812B_LEDS/12*hour; // get LED four hour mark clock_leds[led*3+0] = brightness; // set brightness clock_leds[led*3+1] = brightness; // set brightness clock_leds[led*3+2] = brightness; // set brightness } clock_leds_set(); // set the colors of all LEDs - ws2812b_transmit(); // transmit set color + led_ws2812b_transmit(); // transmit set color // delay some time for the animation for (uint32_t j=0; j<40000; j++) { __asm__("nop"); @@ -383,10 +383,10 @@ int main(void) } // setup WS2812b LEDs - ws2812b_setup(); // setup WS2812b LEDs + led_ws2812b_setup(); // setup WS2812b LEDs clock_clear(); // clear all LEDs clock_leds_set(); // set the colors of all LEDs - ws2812b_transmit(); // transmit set color + led_ws2812b_transmit(); // transmit set color // setup ADC to photo-resistor voltage rcc_periph_clock_enable(PHOTORESISTOR_PORT_RCC); // enable clock for photo-resistor GPIO peripheral @@ -487,7 +487,7 @@ int main(void) adc_start_conversion_regular(ADC1); // start measuring ambient luminosity } if ((rtc_ticks%ticks_second)==0) { // one second passed - //led_toggle(); // don't use the LED, this confuses the 32.768 kHz oscillator + led_toggle(); // don't use the LED, this confuses the 32.768 kHz oscillator } if ((rtc_ticks%ticks_minute)==0) { // one minute passed printf("%02lu:%02lu:%02lu\n", rtc_get_counter_val()/ticks_hour, (rtc_get_counter_val()%ticks_hour)/ticks_minute, (rtc_get_counter_val()%ticks_minute)/ticks_second); // display time