![](/media/cache/group/ST_logo_2020_blue_V_cmyk.jpg.50x50_q85.jpg)
Test application for the STMicroelectronics X-NUCLEO-LED61A1 LED Control Expansion Board showing several LED control modes, built against mbed OS.
Dependencies: X_NUCLEO_LED61A1
Fork of LedDimming_LED61A1 by
LED Control with the X-NUCLEO-LED61A1 Expansion Board
This application provides an example of usage of the X-NUCLEO-LED61A1 LED Control Expansion Board. It shows how to control a LED stripe load connected to the board through the following control modes:
- Manual PWM Dimming;
- Manual Analog Dimming;
- Sinusoidal PWM Dimming;
- Sinusoidal Analog Dimming;
- Photo-based Analog Dimming.
The button of the MCU board, when available, can be used in the following ways:
- Short Button Press [<0.5s] for Manual Dimming;
- Medium Button Press to Switch Demo;
- Long Button Press [>2s] to Switch Power ON/OFF.
The program starts in mode 1.
Diff: main.cpp
- Revision:
- 1:1c01b873ad45
- Parent:
- 0:f5a41692e1fb
- Child:
- 2:dbd596540d46
--- a/main.cpp Thu Dec 10 15:34:29 2015 +0000 +++ b/main.cpp Mon Dec 14 17:43:47 2015 +0000 @@ -42,9 +42,308 @@ /* mbed specific header files. */ #include "mbed.h" -/* Expansion Board specific header files. */ -#include "x_nucleo_led61a1_class.h" -#include "x_nucleo_led61a1_config.h" +/* Component specific header files. */ +#include "led6001_class.h" + + +/* Definitions ---------------------------------------------------------------*/ + +#define LOOP_PERIOD_us 1E6 + + +/* Variables -----------------------------------------------------------------*/ + +/* LED Control Component. */ +LED6001 *led; + +/* User Button. */ +static InterruptIn button(USER_BUTTON); + +/* Interrupt flags. */ +static volatile boolean button_irq_triggered = false; +static volatile boolean xfault_irq_triggered = false; +static volatile boolean timer_irq_triggered = false; + +/* Timer. */ +static Ticker ticker; + +/* MCU Board's Led which provides the user with a visual feedback on + the user button's status (ON = pressed, OFF = released). */ +DigitalOut button_pressed_led(LED1); + +/* Flags to control the demo. */ +static volatile boolean next_demo_state = false; +static volatile boolean next_demo = false; + + +/* Functions -----------------------------------------------------------------*/ + +/** + * @brief State machine initialization + * @param demo - selected demo + * p - reference to pwm dimming level + * a - reference to analog dimming level + * @retval None + */ +void SM_Init(LED_DRIVER_Demo* demo, uint8_t* p, uint8_t* a) +{ +ChangeDemoState = 0; +NextDemo = 0; +ReInit_LED_Driver = 0; + +*p = MAX_BRIGHT_PDIM; +*a = MAX_BRIGHT_ADIM; +*demo = PWM_DIMMING_STEPS; +} + +/** + * @brief Interrupt Request for the timer-related interrupt. + * @param None + * @retval None + */ +void TimerIRQ(void) +{ + timer_irq_triggered = true; + button.disable_irq(); +} + +/** +* @brief Handling the LED capabilities and executing several demos. +* @param None +* @retval None +*/ +void LEDHandler(void) +{ + static LED_DRIVER_Demo SM_Demo; + static uint8_t pDim; + static uint8_t aDim; + uint8_t pDim1,pDim2,pDim3; + uint8_t aDim1,aDim2,aDim3; + + /* If LED driver is not to be reinitialized */ + if (!ReInit_LED_Driver) + { + /* Update state machine parameters */ + SM_Update(&SM_Demo,&pDim,&aDim); + + /* Change running demo and transmit serial information */ + if (NextDemo == 1) + { + pDim = MAX_BRIGHT_PDIM; + aDim = MAX_BRIGHT_ADIM; + + if (SM_Demo == PWM_DIMMING_STEPS) + { + SM_Demo = ANALOG_DIMMING_STEPS; + disp.Len = strlen((char*)Msg_Demo2_Line1); + memcpy(disp.Data,Msg_Demo2_Line1,disp.Len); + UART_SendMsg(&disp); + } + else if (SM_Demo == ANALOG_DIMMING_STEPS) + { + SM_Demo = PWM_DIMMING_VARY; + disp.Len = strlen((char*)Msg_Demo3_Line1); + memcpy(disp.Data,Msg_Demo3_Line1,disp.Len); + UART_SendMsg(&disp); + } + else if (SM_Demo == PWM_DIMMING_VARY) + { + SM_Demo = ANALOG_DIMMING_VARY; + disp.Len = strlen((char*)Msg_Demo4_Line1); + memcpy(disp.Data,Msg_Demo4_Line1,disp.Len); + UART_SendMsg(&disp); + } + else if (SM_Demo == ANALOG_DIMMING_VARY) + { + SM_Demo = ANALOG_DIMMING_PHOTO; + disp.Len = strlen((char*)Msg_Demo5_Line1); + memcpy(disp.Data,Msg_Demo5_Line1,disp.Len); + UART_SendMsg(&disp); + } + else if (SM_Demo == ANALOG_DIMMING_PHOTO) + { + SM_Demo = PWM_DIMMING_STEPS; + disp.Len = strlen((char*)Msg_Demo1_Line1); + memcpy(disp.Data,Msg_Demo1_Line1,disp.Len); + UART_SendMsg(&disp); + } + } + + switch (SM_Demo) + { + /* PWM changes with PB action */ + case PWM_DIMMING_STEPS: + aDim = MAX_BRIGHT_ADIM; + if (ChangeDemoState) + { + pDim = pDim - 10; + if (pDim < MIN_BRIGHT_PDIM) + pDim = MAX_BRIGHT_PDIM; + + disp.Len = strlen((char*)Msg_Demo1_Line2); + memcpy(disp.Data,Msg_Demo1_Line2 ,disp.Len); + pDim1 = pDim/100; + if (pDim1 == 1) + { + pDim2 = 0; pDim3 = 0; + disp.Data[disp.Len] = pDim1+0x30; + disp.Data[disp.Len+1] = pDim2+0x30; + disp.Data[disp.Len+2] = pDim3+0x30; + disp.Data[disp.Len+3] = '%'; + disp.Len+=4; + } + else + { + pDim2 = pDim/10; pDim3 = pDim%10; + disp.Data[disp.Len] = pDim2+0x30; + disp.Data[disp.Len+1] = pDim3+0x30; + disp.Data[disp.Len+2] = '%'; + disp.Len+=3; + } + disp.Data[disp.Len] = '\n'; + disp.Data[disp.Len+1] = '\r'; + disp.Len += 2; + UART_SendMsg(&disp); + } + break; + /* Analog dimming changes with PB action */ + case ANALOG_DIMMING_STEPS: + pDim = MAX_BRIGHT_PDIM; + if (ChangeDemoState) + { + aDim = aDim - 5; + if (aDim < MIN_BRIGHT_ADIM) + aDim = MAX_BRIGHT_ADIM; + + disp.Len = strlen((char*)Msg_Demo2_Line2); + memcpy(disp.Data,Msg_Demo2_Line2 ,disp.Len); + aDim1 = aDim/100; + if (aDim1 == 1) + { + aDim2 = 0; aDim3 = 0; + disp.Data[disp.Len] = aDim1+0x30; + disp.Data[disp.Len+1] = aDim2+0x30; + disp.Data[disp.Len+2] = aDim3+0x30; + disp.Data[disp.Len+3] = '%'; + disp.Len+=4; + } + else + { + aDim2 = aDim/10; aDim3 = aDim%10; + disp.Data[disp.Len] = aDim2+0x30; + disp.Data[disp.Len+1] = aDim3+0x30; + disp.Data[disp.Len+2] = '%'; + disp.Len+=3; + } + disp.Data[disp.Len] = '\n'; + disp.Data[disp.Len+1] = '\r'; + disp.Len += 2; + UART_SendMsg(&disp); + } + break; + /* PWM dimming changes continuously */ + case PWM_DIMMING_VARY: + aDim = MAX_BRIGHT_ADIM; + pDim--; + if (pDim < MIN_BRIGHT_PDIM) + pDim = MAX_BRIGHT_PDIM; + HAL_Delay(50); + break; + /* Analog dimming changes continuously */ + case ANALOG_DIMMING_VARY: + pDim = MAX_BRIGHT_PDIM; + aDim-=3; + if (aDim < MIN_BRIGHT_ADIM) + aDim = MAX_BRIGHT_ADIM; + HAL_Delay(500); + break; + /* Analog dimming changes based on photo sensor value */ + case ANALOG_DIMMING_PHOTO: + pDim = MAX_BRIGHT_PDIM; + aDim = (uint8_t)(((BSP_Photo_Sensor_GetVal()>>3)+72)/9); + HAL_Delay(100); + break; + } + + BSP_SetPwmDim(pDim); + BSP_SetAnaDim(aDim); + + ChangeDemoState = 0; + NextDemo = 0; + } +} + +/** + * @brief Interrupt Request for the XFAULT interrupt. + * @param None + * @retval None + */ +void XFaultIRQ(void) +{ + xfault_irq_triggered = true; + led->DisableXFaultIRQ(); +} + +/** + * @brief Interrupt Handler for the XFAULT interrupt. + * @param None + * @retval None + */ +void XFaultHandler(void) +{ + printf("XFAULT Interrupt detected! Re-initializing LED driver...\r\n"); + +BSP_SetPwmDim(ZERO); +BSP_SetAnaDim(ZERO); + +SM_Init(&SM_Demo,&pDim,&aDim); +BSP_SetPwmDim(pDim); +BSP_SetAnaDim(aDim); + + led->EnableXFaultIRQ(); +} + +/** + * @brief Interrupt Request for the user button interrupt. + * @param None + * @retval None + */ +void ButtonIRQ(void) +{ + button_irq_triggered = true; + button.disable_irq(); +} + +/** + * @brief Interrupt Handler for the user button interrupt. + * @param None + * @retval None + */ +void ButtonHandler(void) +{ + bool button_pressed_flag = (button.read() == 0 ? true : false); + + if (button_pressed_flag) + { + button_pressed_led = 1; + button_pressed_timer.start(); + } + else + { + button_pressed_led = 0; + button_pressed_timer.stop(); + + /* Either changing current demo's state or switching to the next demo. */ + if (button_pressed_timer.read_ms() < 1000) + next_demo_state = true; + else + next_demo = true; + + button_pressed_timer.reset(); + } + + button.enable_irq(); +} /* Main ----------------------------------------------------------------------*/ @@ -53,12 +352,51 @@ { /*----- Initialization. -----*/ - /* Initializing LED Expansion Board. */ - X_NUCLEO_LED61A1 *x_nucleo_led61a1 = new X_NUCLEO_LED61A1(); + /* Initializing LED Control Component. */ + led = new LED6001(D4, A3); + + /********** NOT USED, TBC *********/ + LED_DRIVER_InitTypeDef init = + { + LED6001_PDIM_FULL, + LED6001_ADIM_FULL + }; + + if (led->Init(&init) != COMPONENT_OK) + exit(EXIT_FAILURE); + + /* Attaching interrupt request functions. */ + button.fall(ButtonIRQ); + button.rise(ButtonIRQ); + led->AttachXFaultIRQ(&XFaultIRQ); + ticker.attach_us(TimerIRQ, LOOP_PERIOD_us); + +SM_Init(&SM_Demo,&pDim,&aDim); /* Printing to the console. */ printf("LED Control Application Example\r\n\n"); /*----- LED Control. -----*/ -} \ No newline at end of file + + while (true) + { + if (timer_irq_triggered) + { + timer_irq_triggered = false; + LEDHandler(); + } else if (button_irq_triggered) + { + button_irq_triggered = false; + ButtonHandler(); + } else if(xfault_irq_triggered) + { + xfault_irq_triggered = false; + XFaultHandler(); + } else + { + /* It is recommended that SEVONPEND in the System Control Register is NOT set. */ + __WFE(); + } + } +}