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 ST

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:

  1. Manual PWM Dimming;
  2. Manual Analog Dimming;
  3. Sinusoidal PWM Dimming;
  4. Sinusoidal Analog Dimming;
  5. 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.

Revision:
2:dbd596540d46
Parent:
1:1c01b873ad45
Child:
3:ed347127fc38
--- a/main.cpp	Mon Dec 14 17:43:47 2015 +0000
+++ b/main.cpp	Thu Dec 17 18:13:57 2015 +0000
@@ -48,235 +48,235 @@
 
 /* Definitions ---------------------------------------------------------------*/
 
-#define LOOP_PERIOD_us 1E6
+/* Loop period in micro-seconds. */
+#define LOOP_PERIOD_us                1E6
+
+/* Duration of button press in milli-seconds. */
+#define SWITCH_DEMO_BUTTON_PRESS_ms   500
+#define SWITCH_POWER_BUTTON_PRESS_ms  2000
+
+/* Dimming Step. */
+#define DIMMING_STEP                  0.1f
+
+
+/* Types ---------------------------------------------------------------------*/
+
+/* Demos. */
+typedef enum
+{
+  PWM_DIMMING_STEPS = 0,
+  ANALOG_DIMMING_STEPS,
+  PWM_DIMMING_VARY,
+  ANALOG_DIMMING_VARY,
+  ANALOG_DIMMING_PHOTO,
+  LED_DEMO_SIZE
+} LED_Demo_t;
+
+/* Actions. */
+typedef enum
+{
+  SWITCH_POWER = 0,
+  SWITCH_DEMO,
+  SWITCH_STATE,
+  NO_ACTION
+} LED_Action_t;
 
 
 /* Variables -----------------------------------------------------------------*/
 
-/* LED Control Component. */
-LED6001 *led;
-
-/* User Button. */
-static InterruptIn button(USER_BUTTON);
+/* Main loop's ticker. */
+static Ticker ticker;
 
-/* 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;
+/* User Button's interrupt. */
+static InterruptIn button(USER_BUTTON);
 
 /* 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;
+/* LED Control Component. */
+LED6001 *led;
+
+/* Interrupt flags. */
+static volatile bool ticker_irq_triggered;
+static volatile bool button_irq_triggered;
+static volatile bool xfault_irq_triggered;
+
+/* Demo State. */
+static volatile LED_Demo_t demo;
+static volatile LED_Action_t action;
+static volatile bool power_on;
+
+/* PWM and Analog dimming values. */
+static float pwm_dimming;
+static float analog_dimming;
+
+/* Demos' Names. */
+static char* demos[] =
+{
+    "Manual PWM Dimming",
+    "Manual Analog Dimming",
+    "Cyclic PWM Dimming",
+    "Cyclic Analog Dimming",
+    "Photo-based PWM Dimming"
+};
 
 
 /* Functions -----------------------------------------------------------------*/
 
 /**
- * @brief  State machine initialization
- * @param  demo - selected demo
- *         p - reference to pwm dimming level
- *         a - reference to analog dimming level
- * @retval None
+ * @brief  Initilizing the demo.
+ * @param  None.
+ * @retval None.
  */
-void SM_Init(LED_DRIVER_Demo* demo, uint8_t* p, uint8_t* a)
+void LEDInit(void)
 {
-ChangeDemoState = 0;
-NextDemo = 0;
-ReInit_LED_Driver = 0;
+    /* Initializing Interrupt flags. */
+    button_irq_triggered = false;
+    xfault_irq_triggered = false;
+    ticker_irq_triggered = false;
 
-*p = MAX_BRIGHT_PDIM;
-*a = MAX_BRIGHT_ADIM;
-*demo = PWM_DIMMING_STEPS;
+    /* Initializing Demo. */
+    power_on = true;
+    action = SWITCH_DEMO;
+    demo = (LED_Demo_t) (LED_DEMO_SIZE - 1);
+
+    /* Initializing PWM and Analog dimming to maximum values. */
+    pwm_dimming = 1.0f;
+    analog_dimming = 1.0f;
 }
 
 /**
- * @brief  Interrupt Request for the timer-related interrupt.
- * @param  None
- * @retval None
+ * @brief  Handling the LED capabilities and executing several demos.
+ * @param  None.
+ * @retval None.
  */
-void TimerIRQ(void)
+void LEDHandler(void)
 {
-    timer_irq_triggered = true;
+    /* Switching LED power ON/OFF. */
+    if (action == SWITCH_POWER)
+        power_on = !power_on;
+
+    /* Handling the LED when powered ON. */
+    if (power_on)
+    {
+        /* Switching to the next demo. */
+        if (action == SWITCH_DEMO)
+        {
+            pwm_dimming = 1.0f;
+            analog_dimming = 1.0f;
+            demo = (LED_Demo_t) ((demo + 1) % LED_DEMO_SIZE);
+        }
+
+        /* Setting the LED depending on the selected demo. */
+        switch (demo)
+        {
+            /* Changing PWM dimming according to the user button. */
+            case PWM_DIMMING_STEPS:
+                if (action == SWITCH_STATE)
+                {
+                    pwm_dimming -= DIMMING_STEP;
+                    pwm_dimming = (pwm_dimming <= 0.0f ? 1.0f : pwm_dimming);
+                }
+                break;
+    
+            /* Changing Analog dimming according to the user button. */
+            case ANALOG_DIMMING_STEPS:
+                if (action == SWITCH_STATE)
+                {
+                    analog_dimming -= DIMMING_STEP;
+                    analog_dimming = (analog_dimming <= 0.0f ? 1.0f : analog_dimming);
+                }
+                break;
+    
+            /* Changing PWM dimming continuously. */
+            case PWM_DIMMING_VARY:
+                pwm_dimming -= DIMMING_STEP;
+                pwm_dimming = (pwm_dimming <= 0.0f ? 1.0f : pwm_dimming);
+                //wait_ms(50);
+                action = SWITCH_STATE;
+                break;
+    
+            /* Changing Analog dimming continuously. */
+            case ANALOG_DIMMING_VARY:
+                analog_dimming -= DIMMING_STEP;
+                analog_dimming = (analog_dimming <= 0.0f ? 1.0f : analog_dimming);
+                //wait_ms(500);
+                action = SWITCH_STATE;
+                break;
+    
+            /* Setting Analog dimming according to the photo sensor. */
+            case ANALOG_DIMMING_PHOTO:
+                //analog_dimming = (uint8_t) (led->GetCurrent() * ADC_RANGE / 72 + 8);
+                analog_dimming = ((1.0f - led->GetCurrent()) * (1.0f - DIMMING_STEP) + DIMMING_STEP);
+                //wait_ms(100);
+                action = SWITCH_STATE;
+                break;
+        }
+    }
+
+    /* Writing PWM and Analog dimming values to the LED and printing to the console. */
+    if (action != NO_ACTION)
+    {
+        if (action == SWITCH_POWER)
+            if (power_on)
+            {
+                /* Initializing PWM and Analog dimming to maximum values. */
+                pwm_dimming = 1.0f;
+                analog_dimming = 1.0f;
+
+                /* Printing to the console. */
+                printf("Power ON\r\n");
+            }
+            else
+            {
+                /* Powering OFF the LED. */
+                led->PowerOFF();
+
+                /* Printing to the console. */
+                printf("Power OFF\r\n");
+            }
+
+        if (power_on)
+        {
+            /* Writing PWM and Analog dimming values to the LED. */
+            led->SetPWMDimming(pwm_dimming);
+            led->SetAnalogDimming(analog_dimming);
+
+            /* Printing to the console. */
+            printf("%-24s PWM/Analog: %.3f %.3f\r\n", demos[demo], pwm_dimming, analog_dimming);
+        }
+    
+        /* Resetting action. */
+        action = NO_ACTION;
+    }
+}
+
+/**
+ * @brief  Interrupt Request for the main loop's ticker related interrupt.
+ * @param  None.
+ * @retval None.
+ */
+void TickerIRQ(void)
+{
+    ticker_irq_triggered = true;
+}
+
+/**
+ * @brief  Interrupt Request for the user button's interrupt.
+ * @param  None.
+ * @retval None.
+ */
+void ButtonIRQ(void)
+{
+    button_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
+ * @brief  Interrupt Request for the component's XFAULT interrupt.
+ * @param  None.
+ * @retval None.
  */
 void XFaultIRQ(void)
 {
@@ -285,42 +285,15 @@
 }
 
 /**
- * @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
+ * @brief  Interrupt Handler for the user button's interrupt.
+ * @param  None.
+ * @retval None.
  */
 void ButtonHandler(void)
 {
+    /* User Button's timer to measure the time the button remains pressed. */
+    static Timer button_pressed_timer;
+
     bool button_pressed_flag = (button.read() == 0 ? true : false);
 
     if (button_pressed_flag)
@@ -334,10 +307,13 @@
         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;
+        int time_pressed = button_pressed_timer.read_ms();
+        if (time_pressed < SWITCH_DEMO_BUTTON_PRESS_ms)
+            action = SWITCH_STATE;
+        else if (time_pressed < SWITCH_POWER_BUTTON_PRESS_ms)
+            action = SWITCH_DEMO;
         else
-            next_demo = true;
+            action = SWITCH_POWER;
 
         button_pressed_timer.reset();
     }
@@ -345,6 +321,22 @@
     button.enable_irq();
 }
 
+/**
+ * @brief  Interrupt Handler for the component's XFAULT interrupt.
+ * @param  None.
+ * @retval None.
+ */
+void XFaultHandler(void)
+{
+    /* Printing to the console. */
+    printf("XFAULT Interrupt detected! Re-initializing LED driver...\r\n");
+
+    /* Re-initializing the demo. */
+    LEDInit();
+
+    led->EnableXFaultIRQ();
+}
+
 
 /* Main ----------------------------------------------------------------------*/
 
@@ -352,38 +344,32 @@
 {
     /*----- Initialization. -----*/
 
+    /* Printing to the console. */
+    printf("LED Control Application Example\r\n\n");
+
     /* 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)
+    led = new LED6001(D4, A3, D6, D5);
+    if (led->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);
+    ticker.attach_us(TickerIRQ, LOOP_PERIOD_us);
 
-SM_Init(&SM_Demo,&pDim,&aDim);
-
-    /* Printing to the console. */
-    printf("LED Control Application Example\r\n\n");
+    /* Initializing the demo. */
+    LEDInit();
 
 
     /*----- LED Control. -----*/
 
+    /* Either performing the component handler, interrupt handlers, or waiting for events. */
     while (true)
     {
-        if (timer_irq_triggered)
+        if (ticker_irq_triggered)
         {
-            timer_irq_triggered = false;
+            ticker_irq_triggered = false;
             LEDHandler();
         } else if (button_irq_triggered)
         {