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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /**
00002  ******************************************************************************
00003  * @file    main.cpp
00004  * @author  Davide Aliprandi, STMicroelectronics
00005  * @version V1.0.0
00006  * @date    February 4h, 2016
00007  * @brief   mbed test application for the STMicroelectronics X-NUCLEO-LED61A1
00008  *          LED Control Expansion Board showing several LED control modes.
00009  ******************************************************************************
00010  * @attention
00011  *
00012  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00013  *
00014  * Redistribution and use in source and binary forms, with or without modification,
00015  * are permitted provided that the following conditions are met:
00016  *   1. Redistributions of source code must retain the above copyright notice,
00017  *      this list of conditions and the following disclaimer.
00018  *   2. Redistributions in binary form must reproduce the above copyright notice,
00019  *      this list of conditions and the following disclaimer in the documentation
00020  *      and/or other materials provided with the distribution.
00021  *   3. Neither the name of STMicroelectronics nor the names of its contributors
00022  *      may be used to endorse or promote products derived from this software
00023  *      without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00028  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00033  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  ******************************************************************************
00037  */
00038 
00039 
00040 /* Includes ------------------------------------------------------------------*/
00041 
00042 /* mbed specific header files. */
00043 #include "mbed.h"
00044 #include "rtos.h"
00045 
00046 /* Component specific header files. */
00047 #include "Led6001.h"
00048 
00049 
00050 /* Definitions ---------------------------------------------------------------*/
00051 
00052 /* PI. */
00053 #ifndef M_PI
00054     #define M_PI                          (3.14159265358979323846f)
00055 #endif
00056 
00057 /* Loop period in micro-seconds. */
00058 #define LOOP_PERIOD_us                    (1E5)
00059 
00060 /* Sin period in micro-seconds. */
00061 #define PWM_SIN_PERIOD_us                 (1E7)
00062 #define ANALOG_SIN_PERIOD_us              (1E7)
00063 
00064 /* Duration of button press in milli-seconds. */
00065 #define SWITCH_DEMO_BUTTON_PRESS_ms       (500)
00066 #define SWITCH_POWER_BUTTON_PRESS_ms      (2000)
00067 
00068 /* Dimming Step. */
00069 #define DIMMING_STEP                      (0.05f)
00070 
00071 
00072 /* Types ---------------------------------------------------------------------*/
00073 
00074 /* Demos. */
00075 typedef enum
00076 {
00077   MANUAL_PWM_DIMMING = 0,
00078   MANUAL_ANALOG_DIMMING,
00079   AUTOMATIC_PWM_DIMMING,
00080   AUTOMATIC_ANALOG_DIMMING,
00081   PHOTO_BASED_ANALOG_DIMMING,
00082   LED_DEMO_SIZE
00083 } led_demo_t;
00084 
00085 /* Actions. */
00086 typedef enum
00087 {
00088   SWITCH_POWER = 0,
00089   SWITCH_DEMO,
00090   SWITCH_STATE,
00091   NO_ACTION
00092 } led_action_t;
00093 
00094 
00095 /* Variables -----------------------------------------------------------------*/
00096 
00097 /* Main loop's ticker. */
00098 static Ticker ticker;
00099 
00100 /* User Button's interrupt. */
00101 static InterruptIn button(USER_BUTTON);
00102 
00103 /* MCU Board's Led which provides the user with a visual feedback on
00104    the user button's status (ON = pressed, OFF = released). */
00105 DigitalOut button_pressed_led(LED1);
00106 
00107 /* LED Control Component. */
00108 Led6001 *led;
00109 
00110 /* Interrupt flags. */
00111 static volatile bool ticker_irq_triggered = false;
00112 static volatile bool button_irq_triggered = false;
00113 static volatile bool xfault_irq_triggered = false;
00114 
00115 /* Demo State. */
00116 static volatile led_demo_t demo;
00117 static volatile led_action_t action;
00118 static volatile bool power_on;
00119 
00120 /* Demos' Names. */
00121 static char* demos[] =
00122 {
00123     "Manual PWM Dimming",
00124     "Manual Analog Dimming",
00125     "Sinusoidal PWM Dimming",
00126     "Sinusoidal Analog Dimming",
00127     "Photo-based Analog Dimming"
00128 };
00129 
00130 
00131 /* Functions -----------------------------------------------------------------*/
00132 
00133 /**
00134  * @brief  Initializing the demo.
00135  * @param  None.
00136  * @retval None.
00137  */
00138 void init_demo(void)
00139 {
00140     power_on = true;
00141     action = SWITCH_DEMO;
00142     demo = (led_demo_t) (LED_DEMO_SIZE - 1);
00143 }
00144 
00145 /**
00146  * @brief  Handling the LED capabilities and executing several demos.
00147  * @param  None.
00148  * @retval None.
00149  */
00150 void led_handler(void)
00151 {
00152     static int tick = 0;
00153     static float pwm_dimming;
00154     static float analog_dimming;
00155 
00156     /* Handling the power switch. */
00157     if (action == SWITCH_POWER)
00158     {
00159         /* Switching the LED power ON/OFF. */
00160         power_on = !power_on;
00161 
00162         if (power_on)
00163         {
00164             /* Initializing PWM and Analog dimming to maximum values. */
00165             pwm_dimming = 1.0f;
00166             analog_dimming = 1.0f;
00167         }
00168         else
00169         {
00170             /* Printing to the console. */
00171             printf("%-56s\r", "Power OFF");
00172 
00173             /* Powering OFF the LED. */
00174             led->power_off();
00175         }
00176     }
00177 
00178     /* Handling the LED dimming when powered ON. */
00179     if (power_on)
00180     {
00181         /* Switching to the next demo. */
00182         if (action == SWITCH_DEMO)
00183         {
00184             pwm_dimming = 1.0f;
00185             analog_dimming = 1.0f;
00186             tick = 0;
00187             demo = (led_demo_t) ((demo + 1) % LED_DEMO_SIZE);
00188         }
00189 
00190         /* Setting the LED dimming depending on the selected demo. */
00191         switch (demo)
00192         {
00193             /* Changing PWM dimming according to the user button. */
00194             case MANUAL_PWM_DIMMING:
00195                 if (action == SWITCH_STATE)
00196                 {
00197                     pwm_dimming -= DIMMING_STEP;
00198                     pwm_dimming = (pwm_dimming < 0.0f ? 1.0f : pwm_dimming);
00199                 }
00200                 break;
00201 
00202             /* Changing Analog dimming according to the user button. */
00203             case MANUAL_ANALOG_DIMMING:
00204                 if (action == SWITCH_STATE)
00205                 {
00206                     analog_dimming -= DIMMING_STEP;
00207                     analog_dimming = (analog_dimming < 0.0f ? 1.0f : analog_dimming);
00208                 }
00209                 break;
00210 
00211             /* Changing PWM dimming continuously. */
00212             case AUTOMATIC_PWM_DIMMING:
00213                 pwm_dimming = 0.5f * sin(2 * M_PI * (tick++ * LOOP_PERIOD_us) / PWM_SIN_PERIOD_us) + 0.5f;
00214                 tick %= (int) (PWM_SIN_PERIOD_us / LOOP_PERIOD_us);
00215                 action = SWITCH_STATE;
00216                 break;
00217 
00218             /* Changing Analog dimming continuously. */
00219             case AUTOMATIC_ANALOG_DIMMING:
00220                 analog_dimming = 0.5f * sin(2 * M_PI * (tick++ * LOOP_PERIOD_us) / ANALOG_SIN_PERIOD_us) + 0.5f;
00221                 tick %= (int) (ANALOG_SIN_PERIOD_us / LOOP_PERIOD_us);
00222                 action = SWITCH_STATE;
00223                 break;
00224 
00225             /* Setting Analog dimming according to the photo sensor. */
00226             case PHOTO_BASED_ANALOG_DIMMING:
00227                 analog_dimming = 1.0f - led->get_current();
00228                 action = SWITCH_STATE;
00229                 break;
00230         }
00231 
00232         /* Writing PWM and Analog dimming values to the LED. */
00233         if (action != NO_ACTION)
00234         {
00235             /* Printing to the console. */
00236             printf("%d) %-26s --> Dimming: %0.2f\r", demo + 1, demos[demo], demo == MANUAL_PWM_DIMMING || demo == AUTOMATIC_PWM_DIMMING ? pwm_dimming : analog_dimming);
00237 
00238             /* Writing PWM and Analog dimming values to the LED. */
00239             led->set_pwm_dimming(pwm_dimming);
00240             led->set_analog_dimming(analog_dimming);
00241         }
00242     }
00243     
00244     /* Resetting the action. */
00245     action = NO_ACTION;
00246 }
00247 
00248 /**
00249  * @brief  Interrupt Request for the main loop's ticker related interrupt.
00250  * @param  None.
00251  * @retval None.
00252  */
00253 void ticker_irq(void)
00254 {
00255     ticker_irq_triggered = true;
00256 }
00257 
00258 /**
00259  * @brief  Interrupt Request for the user button's interrupt.
00260  * @param  None.
00261  * @retval None.
00262  */
00263 void button_irq(void)
00264 {
00265     button_irq_triggered = true;
00266     button.disable_irq();
00267 }
00268 
00269 /**
00270  * @brief  Interrupt Request for the component's XFAULT interrupt.
00271  * @param  None.
00272  * @retval None.
00273  */
00274 void xfault_irq(void)
00275 {
00276     xfault_irq_triggered = true;
00277     led->disable_xfault_irq();
00278 }
00279 
00280 /**
00281  * @brief  Interrupt Handler for the user button's interrupt.
00282  * @param  None.
00283  * @retval None.
00284  */
00285 void button_handler(void)
00286 {
00287     /* User Button's timer to measure the time the button remains pressed. */
00288     static Timer button_pressed_timer;
00289 
00290     bool button_pressed_flag = (button.read() == 0 ? true : false);
00291 
00292     if (button_pressed_flag)
00293     {
00294         button_pressed_led = 1;
00295         button_pressed_timer.start();
00296     }
00297     else
00298     {
00299         button_pressed_led = 0;
00300         button_pressed_timer.stop();
00301 
00302         /* Either changing current demo's state or switching to the next demo. */
00303         int time_pressed = button_pressed_timer.read_ms();
00304         if (time_pressed < SWITCH_DEMO_BUTTON_PRESS_ms)
00305             action = SWITCH_STATE;
00306         else if (time_pressed < SWITCH_POWER_BUTTON_PRESS_ms)
00307             action = SWITCH_DEMO;
00308         else
00309             action = SWITCH_POWER;
00310 
00311         button_pressed_timer.reset();
00312     }
00313 
00314     button.enable_irq();
00315 }
00316 
00317 /**
00318  * @brief  Interrupt Handler for the component's XFAULT interrupt.
00319  * @param  None.
00320  * @retval None.
00321  */
00322 void xfault_handler(void)
00323 {
00324     /* Printing to the console. */
00325     printf("XFAULT Interrupt detected! Re-initializing LED driver...");
00326 
00327     /* Re-starting-up LED Control Component. */
00328     led->start_up();
00329 
00330     /* Printing to the console. */
00331     printf("Done.\r\n\n");
00332 
00333     /* Re-initializing the demo. */
00334     init_demo();
00335 
00336     led->enable_xfault_irq();
00337 }
00338 
00339 
00340 /* Main ----------------------------------------------------------------------*/
00341 
00342 int main()
00343 {
00344     /*----- Initialization. -----*/
00345 
00346     /* Printing to the console. */
00347     printf("LED Control Application Example\r\n\n" \
00348            "Demos:\r\n");
00349     int demo = 0;
00350     for (demo = 0; demo < LED_DEMO_SIZE; demo++)
00351         printf("%d) %-26s\r\n", demo + 1, demos[demo]);
00352     printf("\r\nActions:\r\n" \
00353            "+ Short Button Press [<%.1fs]  --> Manual Dimming\r\n" \
00354            "+ Medium Button Press         --> Switch Demo\r\n" \
00355            "+ Long Button Press  [>%.1fs]  --> Switch Power ON/OFF\r\n\n" \
00356            , SWITCH_DEMO_BUTTON_PRESS_ms / 1000.0f, SWITCH_POWER_BUTTON_PRESS_ms / 1000.0f);
00357 
00358     /* Initializing LED Control Component. */
00359     led = new Led6001(D4, A3, D6, D5);
00360     if (led->init() != COMPONENT_OK)
00361         exit(EXIT_FAILURE);
00362 
00363     /* Attaching interrupt request functions. */
00364     button.fall(button_irq);
00365     button.rise(button_irq);
00366     led->attach_xfault_irq(&xfault_irq);
00367     led->enable_xfault_irq();
00368     ticker.attach_us(ticker_irq, LOOP_PERIOD_us);
00369 
00370     /* Starting-up LED Control Component. */
00371     led->start_up();
00372 
00373     /* Initializing the demo. */
00374     init_demo();
00375 
00376 
00377     /*----- LED Control. -----*/
00378 
00379     /* Either performing the component handler, interrupt handlers, or waiting for events. */
00380     while (true)
00381     {
00382         if (ticker_irq_triggered)
00383         {
00384             ticker_irq_triggered = false;
00385             led_handler();
00386         } else if (button_irq_triggered)
00387         {
00388             button_irq_triggered = false;
00389             button_handler();
00390         } else if (xfault_irq_triggered)
00391         {
00392             xfault_irq_triggered = false;
00393             xfault_handler();
00394         } else {
00395             /* It is recommended that SEVONPEND in the System Control Register is NOT set. */
00396             __WFE();
00397         }
00398     }
00399 }