ST / Mbed 2 deprecated LedDimming_LED61A1

Dependencies:   X_NUCLEO_LED61A1 mbed

Fork of LedDimming_LED61A1 by ST Expansion SW Team

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 
00045 /* Component specific header files. */
00046 #include "Led6001.h"
00047 
00048 
00049 /* Definitions ---------------------------------------------------------------*/
00050 
00051 /* PI. */
00052 #ifndef M_PI
00053     #define M_PI                          (3.14159265358979323846f)
00054 #endif
00055 
00056 /* Loop period in micro-seconds. */
00057 #define LOOP_PERIOD_us                    (1E5)
00058 
00059 /* Sin period in micro-seconds. */
00060 #define PWM_SIN_PERIOD_us                 (1E7)
00061 #define ANALOG_SIN_PERIOD_us              (1E7)
00062 
00063 /* Duration of button press in milli-seconds. */
00064 #define SWITCH_DEMO_BUTTON_PRESS_ms       (500)
00065 #define SWITCH_POWER_BUTTON_PRESS_ms      (2000)
00066 
00067 /* Dimming Step. */
00068 #define DIMMING_STEP                      (0.05f)
00069 
00070 
00071 /* Types ---------------------------------------------------------------------*/
00072 
00073 /* Demos. */
00074 typedef enum
00075 {
00076   MANUAL_PWM_DIMMING = 0,
00077   MANUAL_ANALOG_DIMMING,
00078   AUTOMATIC_PWM_DIMMING,
00079   AUTOMATIC_ANALOG_DIMMING,
00080   PHOTO_BASED_ANALOG_DIMMING,
00081   LED_DEMO_SIZE
00082 } LED_Demo_t;
00083 
00084 /* Actions. */
00085 typedef enum
00086 {
00087   SWITCH_POWER = 0,
00088   SWITCH_DEMO,
00089   SWITCH_STATE,
00090   NO_ACTION
00091 } LED_Action_t;
00092 
00093 
00094 /* Variables -----------------------------------------------------------------*/
00095 
00096 /* Main loop's ticker. */
00097 static Ticker ticker;
00098 
00099 /* User Button's interrupt. */
00100 static InterruptIn button(USER_BUTTON);
00101 
00102 /* MCU Board's Led which provides the user with a visual feedback on
00103    the user button's status (ON = pressed, OFF = released). */
00104 DigitalOut button_pressed_led(LED1);
00105 
00106 /* LED Control Component. */
00107 Led6001 *led;
00108 
00109 /* Interrupt flags. */
00110 static volatile bool ticker_irq_triggered = false;
00111 static volatile bool button_irq_triggered = false;
00112 static volatile bool xfault_irq_triggered = false;
00113 
00114 /* Demo State. */
00115 static volatile LED_Demo_t demo;
00116 static volatile LED_Action_t action;
00117 static volatile bool power_on;
00118 
00119 /* Demos' Names. */
00120 static char* demos[] =
00121 {
00122     "Manual PWM Dimming",
00123     "Manual Analog Dimming",
00124     "Sinusoidal PWM Dimming",
00125     "Sinusoidal Analog Dimming",
00126     "Photo-based Analog Dimming"
00127 };
00128 
00129 
00130 /* Functions -----------------------------------------------------------------*/
00131 
00132 /**
00133  * @brief  Initializing the demo.
00134  * @param  None.
00135  * @retval None.
00136  */
00137 void init_demo(void)
00138 {
00139     power_on = true;
00140     action = SWITCH_DEMO;
00141     demo = (LED_Demo_t) (LED_DEMO_SIZE - 1);
00142 }
00143 
00144 /**
00145  * @brief  Handling the LED capabilities and executing several demos.
00146  * @param  None.
00147  * @retval None.
00148  */
00149 void led_handler(void)
00150 {
00151     static int tick = 0;
00152     static float pwm_dimming;
00153     static float analog_dimming;
00154 
00155     /* Handling the power switch. */
00156     if (action == SWITCH_POWER) {
00157         /* Switching the LED power ON/OFF. */
00158         power_on = !power_on;
00159 
00160         if (power_on) {
00161             /* Initializing PWM and Analog dimming to maximum values. */
00162             pwm_dimming = 1.0f;
00163             analog_dimming = 1.0f;
00164         } else {
00165             /* Printing to the console. */
00166             printf("%-56s\r", "Power OFF");
00167 
00168             /* Powering OFF the LED. */
00169             led->power_off();
00170         }
00171     }
00172 
00173     /* Handling the LED dimming when powered ON. */
00174     if (power_on) {
00175         /* Switching to the next demo. */
00176         if (action == SWITCH_DEMO) {
00177             pwm_dimming = 1.0f;
00178             analog_dimming = 1.0f;
00179             tick = 0;
00180             demo = (LED_Demo_t) ((demo + 1) % LED_DEMO_SIZE);
00181         }
00182 
00183         /* Setting the LED dimming depending on the selected demo. */
00184         switch (demo) {
00185             /* Changing PWM dimming according to the user button. */
00186             case MANUAL_PWM_DIMMING:
00187                 if (action == SWITCH_STATE) {
00188                     pwm_dimming -= DIMMING_STEP;
00189                     pwm_dimming = (pwm_dimming < 0.0f ? 1.0f : pwm_dimming);
00190                 }
00191                 break;
00192 
00193             /* Changing Analog dimming according to the user button. */
00194             case MANUAL_ANALOG_DIMMING:
00195                 if (action == SWITCH_STATE) {
00196                     analog_dimming -= DIMMING_STEP;
00197                     analog_dimming = (analog_dimming < 0.0f ? 1.0f : analog_dimming);
00198                 }
00199                 break;
00200 
00201             /* Changing PWM dimming continuously. */
00202             case AUTOMATIC_PWM_DIMMING:
00203                 pwm_dimming = 0.5f * sin(2 * M_PI * (tick++ * LOOP_PERIOD_us) / PWM_SIN_PERIOD_us) + 0.5f;
00204                 tick %= (int) (PWM_SIN_PERIOD_us / LOOP_PERIOD_us);
00205                 action = SWITCH_STATE;
00206                 break;
00207 
00208             /* Changing Analog dimming continuously. */
00209             case AUTOMATIC_ANALOG_DIMMING:
00210                 analog_dimming = 0.5f * sin(2 * M_PI * (tick++ * LOOP_PERIOD_us) / ANALOG_SIN_PERIOD_us) + 0.5f;
00211                 tick %= (int) (ANALOG_SIN_PERIOD_us / LOOP_PERIOD_us);
00212                 action = SWITCH_STATE;
00213                 break;
00214 
00215             /* Setting Analog dimming according to the photo sensor. */
00216             case PHOTO_BASED_ANALOG_DIMMING:
00217                 analog_dimming = 1.0f - led->get_current();
00218                 action = SWITCH_STATE;
00219                 break;
00220         }
00221 
00222         /* Writing PWM and Analog dimming values to the LED. */
00223         if (action != NO_ACTION) {
00224             /* Printing to the console. */
00225             printf("%d) %-26s --> Dimming: %0.2f\r", demo + 1, demos[demo], demo == MANUAL_PWM_DIMMING || demo == AUTOMATIC_PWM_DIMMING ? pwm_dimming : analog_dimming);
00226 
00227             /* Writing PWM and Analog dimming values to the LED. */
00228             led->set_pwm_dimming(pwm_dimming);
00229             led->set_analog_dimming(analog_dimming);
00230         }
00231     }
00232     
00233     /* Resetting the action. */
00234     action = NO_ACTION;
00235 }
00236 
00237 /**
00238  * @brief  Interrupt Request for the main loop's ticker related interrupt.
00239  * @param  None.
00240  * @retval None.
00241  */
00242 void ticker_irq(void)
00243 {
00244     ticker_irq_triggered = true;
00245 }
00246 
00247 /**
00248  * @brief  Interrupt Request for the user button's interrupt.
00249  * @param  None.
00250  * @retval None.
00251  */
00252 void button_irq(void)
00253 {
00254     button_irq_triggered = true;
00255     button.disable_irq();
00256 }
00257 
00258 /**
00259  * @brief  Interrupt Request for the component's XFAULT interrupt.
00260  * @param  None.
00261  * @retval None.
00262  */
00263 void xfault_irq(void)
00264 {
00265     xfault_irq_triggered = true;
00266     led->disable_xfault_irq();
00267 }
00268 
00269 /**
00270  * @brief  Interrupt Handler for the user button's interrupt.
00271  * @param  None.
00272  * @retval None.
00273  */
00274 void button_handler(void)
00275 {
00276     /* User Button's timer to measure the time the button remains pressed. */
00277     static Timer button_pressed_timer;
00278 
00279     bool button_pressed_flag = (button.read() == 0 ? true : false);
00280 
00281     if (button_pressed_flag) {
00282         button_pressed_led = 1;
00283         button_pressed_timer.start();
00284     } else {
00285         button_pressed_led = 0;
00286         button_pressed_timer.stop();
00287 
00288         /* Either changing current demo's state or switching to the next demo. */
00289         int time_pressed = button_pressed_timer.read_ms();
00290         if (time_pressed < SWITCH_DEMO_BUTTON_PRESS_ms) {
00291             action = SWITCH_STATE;
00292         } else if (time_pressed < SWITCH_POWER_BUTTON_PRESS_ms) {
00293             action = SWITCH_DEMO;
00294         } else {
00295             action = SWITCH_POWER;
00296         }
00297 
00298         button_pressed_timer.reset();
00299     }
00300 
00301     button.enable_irq();
00302 }
00303 
00304 /**
00305  * @brief  Interrupt Handler for the component's XFAULT interrupt.
00306  * @param  None.
00307  * @retval None.
00308  */
00309 void xfault_handler(void)
00310 {
00311     /* Printing to the console. */
00312     printf("XFAULT Interrupt detected! Re-initializing LED driver...");
00313 
00314     /* Re-starting-up LED Control Component. */
00315     led->start_up();
00316 
00317     /* Printing to the console. */
00318     printf("Done.\r\n\n");
00319 
00320     /* Re-initializing the demo. */
00321     init_demo();
00322 
00323     led->enable_xfault_irq();
00324 }
00325 
00326 
00327 /* Main ----------------------------------------------------------------------*/
00328 
00329 int main()
00330 {
00331     /*----- Initialization. -----*/
00332 
00333     /* Printing to the console. */
00334     printf("LED Control Application Example\r\n\n" \
00335            "Demos:\r\n");
00336     int demo = 0;
00337     for (demo = 0; demo < LED_DEMO_SIZE; demo++) {
00338         printf("%d) %-26s\r\n", demo + 1, demos[demo]);
00339     }
00340     printf("\r\nActions:\r\n" \
00341            "+ Short Button Press [<%.1fs]  --> Manual Dimming\r\n" \
00342            "+ Medium Button Press         --> Switch Demo\r\n" \
00343            "+ Long Button Press  [>%.1fs]  --> Switch Power ON/OFF\r\n\n" \
00344            , SWITCH_DEMO_BUTTON_PRESS_ms / 1000.0f, SWITCH_POWER_BUTTON_PRESS_ms / 1000.0f);
00345 
00346     /* Initializing LED Control Component. */
00347     led = new Led6001(D4, A3, D6, D5);
00348     if (led->init() != COMPONENT_OK) {
00349         exit(EXIT_FAILURE);
00350     }
00351 
00352     /* Attaching interrupt request functions. */
00353     button.fall(button_irq);
00354     button.rise(button_irq);
00355     led->attach_xfault_irq(&xfault_irq);
00356     led->enable_xfault_irq();
00357     ticker.attach_us(ticker_irq, LOOP_PERIOD_us);
00358 
00359     /* Starting-up LED Control Component. */
00360     led->start_up();
00361 
00362     /* Initializing the demo. */
00363     init_demo();
00364 
00365 
00366     /*----- LED Control. -----*/
00367 
00368     /* Either performing the component handler, interrupt handlers, or waiting for events. */
00369     while (true) {
00370         if (ticker_irq_triggered) {
00371             ticker_irq_triggered = false;
00372             led_handler();
00373         } else if (button_irq_triggered) {
00374             button_irq_triggered = false;
00375             button_handler();
00376         } else if (xfault_irq_triggered) {
00377             xfault_irq_triggered = false;
00378             xfault_handler();
00379         } else {
00380             /* It is recommended that SEVONPEND in the System Control Register is NOT set. */
00381             __WFE();
00382         }
00383     }
00384 }