Test application for the STMicroelectronics X-NUCLEO-LED61A1 LED Control Expansion Board showing several LED control modes.
Dependencies: X_NUCLEO_LED61A1 mbed
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
diff -r f5a41692e1fb -r 1c01b873ad45 main.cpp
--- 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();
+ }
+ }
+}
