Simple test application for the STMicroelectronics X-NUCLEO-LED61A1 LED Control Expansion Board.
Dependencies: X_NUCLEO_LED61A1 mbed
Fork of HelloWorld_LED61A1 by
LED Control with the X-NUCLEO-LED61A1 Expansion Board
This application provides a simple 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 by means of a sinusoidal wave form injected into the PWM dimming control pin.
main.cpp
- Committer:
- Davidroid
- Date:
- 2015-12-18
- Revision:
- 3:ed347127fc38
- Parent:
- 2:dbd596540d46
- Child:
- 4:aeeb361d0227
File content as of revision 3:ed347127fc38:
/** ****************************************************************************** * @file main.cpp * @author Davide Aliprandi, STMicrolectronics * @version V1.0.0 * @date December 9th, 2015 * @brief mbed test application for the STMicrolectronics X-NUCLEO-LED61A1 * LED expansion board. ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ /* mbed specific header files. */ #include "mbed.h" /* Component specific header files. */ #include "led6001_class.h" /* Definitions ---------------------------------------------------------------*/ /* PI. */ #ifndef M_PI #define M_PI 3.14159265358979323846f #endif /* Loop period in micro-seconds. */ #define LOOP_PERIOD_us 1E5 /* Sin period in micro-seconds. */ #define PWM_SIN_PERIOD_us 1E7 #define ANALOG_SIN_PERIOD_us 1E7 /* 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 -----------------------------------------------------------------*/ /* Main loop's ticker. */ 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); /* 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", "Sinusoidal PWM Dimming", "Sinusoidal Analog Dimming", "Photo-based PWM Dimming" }; /* Functions -----------------------------------------------------------------*/ /** * @brief Initilizing the demo. * @param None. * @retval None. */ void LEDInit(void) { /* Initializing Interrupt flags. */ button_irq_triggered = false; xfault_irq_triggered = false; ticker_irq_triggered = false; /* 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 Handling the LED capabilities and executing several demos. * @param None. * @retval None. */ void LEDHandler(void) { static int tick = 0; /* Handling the power switch. */ if (action == SWITCH_POWER) { /* Switching the LED power ON/OFF. */ power_on = !power_on; if (power_on) { /* Initializing PWM and Analog dimming to maximum values. */ pwm_dimming = 1.0f; analog_dimming = 1.0f; } else { /* Printing to the console. */ printf("%-56s\r", "Power OFF"); /* Powering OFF the LED. */ led->PowerOFF(); } } /* Handling the LED dimming when powered ON. */ if (power_on) { /* Switching to the next demo. */ if (action == SWITCH_DEMO) { pwm_dimming = 1.0f; analog_dimming = 1.0f; tick = 0; demo = (LED_Demo_t) ((demo + 1) % LED_DEMO_SIZE); } /* Setting the LED dimming 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 = 0.5f * sin(2 * M_PI * (tick++ * LOOP_PERIOD_us) / PWM_SIN_PERIOD_us) + 0.5f; tick %= (int) (PWM_SIN_PERIOD_us / LOOP_PERIOD_us) + 1; action = SWITCH_STATE; break; /* Changing Analog dimming continuously. */ case ANALOG_DIMMING_VARY: analog_dimming = 0.5f * sin(2 * M_PI * (tick++ * LOOP_PERIOD_us) / ANALOG_SIN_PERIOD_us) + 0.5f; tick %= (int) (ANALOG_SIN_PERIOD_us / LOOP_PERIOD_us) + 1; 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(); action = SWITCH_STATE; break; } /* Writing PWM and Analog dimming values to the LED. */ if (action != NO_ACTION) { /* Printing to the console. */ printf("%d) %-26s PWM/Analog: %.3f %.3f\r", demo + 1, demos[demo], pwm_dimming, analog_dimming); /* Writing PWM and Analog dimming values to the LED. */ led->SetPWMDimming(pwm_dimming); led->SetAnalogDimming(analog_dimming); } } /* Resetting the 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 Interrupt Request for the component's XFAULT interrupt. * @param None. * @retval None. */ void XFaultIRQ(void) { xfault_irq_triggered = true; led->DisableXFaultIRQ(); } /** * @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) { 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. */ 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 action = SWITCH_POWER; button_pressed_timer.reset(); } 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 ----------------------------------------------------------------------*/ int main() { /*----- Initialization. -----*/ /* Printing to the console. */ printf("LED Control Application Example\r\n\n"); /* Initializing LED Control Component. */ 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(TickerIRQ, LOOP_PERIOD_us); /* Initializing the demo. */ LEDInit(); /*----- LED Control. -----*/ /* Either performing the component handler, interrupt handlers, or waiting for events. */ while (true) { if (ticker_irq_triggered) { ticker_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(); } } }