1 /* 2 * Copyright (c) 2016-2019, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /*!***************************************************************************** 34 * @file LED.h 35 * 36 * @brief LED driver 37 * 38 * The LED driver is provided for easy access to common LED functionality. 39 * All functionality can be replicated using the GPIO.h and PWM.h APIs. 40 * 41 * @anchor ti_drivers_LED_Synopsis 42 * # Synopsis # 43 * 44 * @code 45 * #include <ti/drivers/apps/LED.h> 46 * 47 * LED_Handle handle; 48 * LED_Params ledParams; 49 * 50 * // Assume our LED is configured to be a PWM LED 51 * LED_Params_init(&ledParams); 52 * ledHandle = LED_open(CONFIG_LED0, &ledParams); 53 * 54 * // Turn on, set brightness, and blink 55 * LED_setOn(handle, 80); 56 * LED_startBlinking(handle, 500, LED_BLINK_FOREVER); 57 * 58 * LED_setOff(handle); 59 * LED_close(handle); 60 * 61 * @endcode 62 * 63 * @anchor ti_drivers_LED_Examples 64 * ## Examples # 65 * 66 * * @ref ti_drivers_LED_Examples_config_array "Generic Configuration" 67 * * @ref ti_drivers_LED_Examples_gpio_config "GPIO Configuration" 68 * * @ref ti_drivers_LED_Examples_pwm_led "PWM Mode" 69 * 70 * # Operation # 71 * LED driver simplifies using an LED (may be GPIO or PWM controlled) 72 * available on board and supports following operations - 73 * 74 * 1. To Turn ON/OFF 75 * 2. Blink with requested delay, stop when requested 76 * 3. Vary brightness (can only be done to a PWM controlled LED) 77 * 4. Toggle 78 * 79 * There are also APIs to open and close an LED handle and also one to get 80 * current state of a LED. User can request to set a LED into particular state 81 * while opening itself i.e. to start blink as part of LED_open() call. 82 * 83 * LED_init() must be called before using LED_open(). 84 * 85 * ## Defining #LED_Config, #LED_Object and #LED_HWAttrs # 86 * To use the LED driver, an application has to indicate how many LEDs it 87 * wants to operate, of what type (PWM or GPIO controlled), and which GPIO or 88 * PWM to index for each LED. 89 * 90 * Each structure must be defined by the application. The following 91 * example is for an MSP432P401R platform in which four LEDs are available 92 * on board. 93 * The following declarations are placed in "ti_drivers_config.c". 94 * How the gpio indices are defined is detailed in the next section. 95 * 96 * ### LED_config structures # 97 * @anchor ti_drivers_LED_Examples_config_array 98 * "ti_drivers_config.c" 99 * @code 100 * #include <ti/drivers/apps/LED.h> 101 * 102 * LED_Object LED_object[4]; 103 * 104 * const LED_HWAttrs LED_hwAttrs[4] = { 105 * { 106 * .index = CONFIG_LED1, 107 * .type = LED_GPIO_CONTROLLED 108 * }, 109 * { 110 * .index = CONFIG_LED_RED, 111 * .type = LED_GPIO_CONTROLLED 112 * }, 113 * { 114 * .index = CONFIG_NA_GPIO_PWMLED, 115 * .type = LED_PWM_CONTROLLED 116 * }, 117 * { 118 * .index = CONFIG_NA_GPIO_PWMLED, 119 * .type = LED_PWM_CONTROLLED 120 * } 121 * }; 122 * 123 * const LED_Config LED_config[] = { 124 * { 125 * .object = &LED_object[0], 126 * .hwAttrs = &LED_hwAttrs[0], 127 * }, 128 * { 129 * .object = &LED_object[1], 130 * .hwAttrs = &LED_hwAttrs[1], 131 * }, 132 * { 133 * .object = &LED_object[2], 134 * .hwAttrs = &LED_hwAttrs[2], 135 * }, 136 * { 137 * .object = &LED_object[3], 138 * .hwAttrs = &LED_hwAttrs[3], 139 * } 140 * }; 141 * 142 * uint32_t LED_count = 4; 143 * 144 * @endcode 145 * 146 * ##Setting up a GPIO controlled LED # 147 * The following code snippet shows how a GPIO pin controlling an LED is 148 * configured. The index the user provides to LED_open() corresponds to an 149 * entry in the #GPIO_PinConfig array which will source the LED. It is the 150 * user's responsibility to ensure that the pin is configured properly in the 151 * pin array. Typically this means configuring the pin as an output. 152 * 153 * ### GPIO controlled LED # 154 * @anchor ti_drivers_LED_Examples_gpio_config 155 * 156 * The following definitions are in 157 * "ti_drivers_config.h" and "ti_drivers_config.c" respectively. This 158 * example uses GPIO pins 1.0 and 2.0 which control LED1 and RED LED on 159 * LaunchPad respectively. In addition to the structures shown below, the 160 * other GPIO configuration data must exist. See @ref GPIO.h. 161 * 162 * "ti_drivers_config.h" 163 * @code 164 * #define CONFIG_LED1 0 165 * #define CONFIG_LED_RED 1 166 * @endcode 167 * 168 * "ti_drivers_config.c" 169 * @code 170 * #include <ti/drivers/GPIO.h> 171 * GPIO_PinConfig gpioPinConfigs[] = { 172 * GPIOMSP432_P1_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW, 173 * GPIOMSP432_P2_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW, 174 * } 175 * 176 * @endcode 177 * 178 * ## Configuring a PWM controlled LED # 179 * The LED driver allows for an LED to be driven by the PWM driver. This allows 180 * the user to set a brightness level in addition to the other LED features. 181 * The user must specify in the #LED_HWAttrs of each #LED_Config entry which 182 * #PWM_Config the LED instance is allowed to use. LED instances cannot share 183 * a PWM instance. 184 * 185 * The user may specify the period of the PWM signal in the #LED_Params passed 186 * to LED_open(). This is not to be confused with #LED_Params.blinkPeriod 187 * which specifies the default blink period. 188 * 189 * ### Opening a PWM LED # 190 * @anchor ti_drivers_LED_Examples_pwm_led 191 * 192 * We will borrow the 3rd LED_config entry from the 193 * @ref ti_drivers_LED_Examples_config_array 194 * 195 * In "ti_drivers_config.h" 196 * @code 197 * #define CONFIG_LED0 0 198 * @endcode 199 * 200 * In application code: 201 * @code 202 * #include <ti/drivers/apps/LED.h> 203 * 204 * LED_Handle LEDHandle; 205 * LED_Params ledParams; 206 * 207 * LED_Params_init(&ledParams); 208 * ledParams.pwmPeriod = 100; // 0.1 ms period 209 * ledParams.blinkPeriod = 500; // LED will toggle twice a second 210 * ledParams.setState = LED_STATE_BLINKING; // Start LED blink on open 211 * ledHandle = LED_open(CONFIG_LED0, &ledParams); // Open the first LED_Config 212 * 213 * // Turn on at half brightness level 214 * LED_setOn(ledHandle, 50); 215 * @endcode 216 * 217 ******************************************************************************* 218 */ 219 220 221 #ifndef ti_drivers_LED__include 222 #define ti_drivers_LED__include 223 224 #include <stdint.h> 225 #include <stdbool.h> 226 227 /* Driver Header files */ 228 #include <ti/drivers/GPIO.h> 229 #include <ti/drivers/PWM.h> 230 #include <ti/drivers/dpl/ClockP.h> 231 232 #ifdef __cplusplus 233 extern "C" { 234 #endif 235 236 #define LED_BRIGHTNESS_MAX 100U /* Max brightness in % is 100%*/ 237 #define LED_BRIGHTNESS_MIN 0U /* Max brightness in % is 0%*/ 238 239 #define LED_ON 1U 240 #define LED_OFF 0U 241 242 #define LED_BLINK_FOREVER 0xFFFF 243 244 /* Number of user defined LED configurations */ 245 extern const uint_least8_t LED_count; 246 247 /*! 248 * @brief LED types based on control source 249 * 250 * A LED can be controlled by GPIO or PWM. Only a PWM controlled LED can 251 * be operated to show brightness variation. An unopened instance will be of 252 * type #LED_NONE. 253 */ 254 typedef enum { 255 LED_NONE = 0, 256 LED_GPIO_CONTROLLED, 257 LED_PWM_CONTROLLED 258 } LED_Type; 259 260 /*! 261 * @brief LED State 262 * 263 * A LED can be in OFF, ON or BLINKING state 264 * 265 * State of particular LED may be tied with a warning/alert in system 266 * which a thread/task may want to know. 267 */ 268 typedef enum { 269 LED_STATE_OFF = 0, 270 LED_STATE_ON, 271 LED_STATE_BLINKING 272 } LED_State; 273 274 /*! 275 * @brief LED configuration 276 * 277 * The LED_Config structure contains a set of pointers used to characterize 278 * the LED driver implementation. 279 * 280 * This structure needs to be defined and provided by the application and will 281 * be NULL terminated. 282 */ 283 typedef struct { 284 /*! Pointer to drivers internal data state object */ 285 void *object; 286 /*! Pointer to a driver specific hardware attributes structure */ 287 void const *hwAttrs; 288 } LED_Config; 289 290 /*! 291 * @brief A handle that is returned from a LED_open() call. 292 */ 293 typedef LED_Config* LED_Handle; 294 295 /*! 296 * @brief Hardware specific settings for a LED module. 297 * 298 * This structure should be defined and provided by the application. The 299 * index should be correspond to the desired pin in either the PWM or GPIO 300 * config tables depending on the requested #LED_Type. 301 */ 302 typedef struct { 303 uint_least8_t index; /*!< Index into GPIO or PWM config array */ 304 LED_Type type; /*<! GPIO (binary) or PWM (dimmable) control */ 305 } LED_HWAttrs; 306 307 /*! 308 * @brief LED Object structure 309 * 310 * The application must not access any member variables of this structure! 311 */ 312 typedef struct { 313 uint32_t pwmPeriod; /*!< pwmPeriod(us) of controlling PWM */ 314 PWM_Handle pwmHandle; /*!< Used for PWM calls if PWM type LED */ 315 ClockP_Handle clockHandle; /*!< Handle to clock used for blinking */ 316 ClockP_Struct clock; /*!< Clock internal data */ 317 LED_State state; /*!< Current State of LED */ 318 LED_State rawState; /*!< rawState maintains actual state On or Off 319 while blinking which is super state */ 320 LED_Type ledType; /*!< may be either GPIO or PWM controlled */ 321 uint8_t brightness; /*!< Varying min-max(0-100%) for PWM LED) */ 322 uint_least8_t gpioIndex; /*!< Index into #GPIO_PinConfig array */ 323 uint16_t togglePeriod; /*!< Toggleperiod(ms), 0 for non-blinking LED 324 This is half of blinkPeriod: two toggles 325 is one blink */ 326 uint16_t blinkCount; /*!< Blinkcount, 0 for non-blinking LED */ 327 } LED_Object; 328 329 /*! 330 * @brief LED Parameters 331 * 332 * LED parameters are used with the LED_open() call. Default values for 333 * these parameters are set using LED_Params_init(). It contains brightness 334 * field which will be used to control brightness of a LED and also blink 335 * period if user wants to set LED in blinking mode. 336 * 337 * @sa LED_Params_init() 338 */ 339 typedef struct { 340 uint32_t pwmPeriod; /*!< pwmPeriod(us) of controlling PWM */ 341 uint16_t blinkPeriod; /*!< param to set blink period (in ms) */ 342 uint8_t brightness; /*!< may vary from 0-100% for PWM LED */ 343 LED_State setState; /*!< request to set a LED state(eg blinking) */ 344 } LED_Params; 345 346 /*! 347 * @brief Function to close a LED specified by the LED handle 348 * 349 * This call will destruct associated clock, turn off LED, and close the PWM 350 * instance if applicable. 351 * 352 * @pre LED_open() had to be called first. 353 * 354 * @param ledHandle A #LED_Handle returned from LED_open() 355 * 356 */ 357 extern void LED_close(LED_Handle ledHandle); 358 359 /*! 360 * @brief Function to get LED state. 361 * 362 * This function may be useful in scenarios if a LED state(ON/OFF/BLINKING) is 363 * tied with some system warning/alerts 364 * 365 * @param ledHandle A #LED_Handle returned from LED_open() 366 * 367 * @return The LED State 368 */ 369 extern LED_State LED_getState(LED_Handle ledHandle); 370 371 /*! 372 * @brief Function to initialize LED driver. 373 * 374 * This function will initialize the LED driver. 375 */ 376 extern void LED_init(); 377 378 /*! 379 * @brief Function to open an instance of LED 380 * 381 * Function to open an LED instance in the LED_config array. The GPIO or PWM 382 * configuartions must already exist before this function is called. The 383 * #LED_Params input can be used to specify the run time options of the LED 384 * instance. 385 * 386 * @pre LED_init() has to be called first 387 * 388 * @param index Index into the LED_config array specifying the 389 * #LED_Config that is to be used to open the LED. 390 * 391 * @param *params A pointer to #LED_Params structure. If NULL, it 392 * will use default values. 393 * 394 * @return A LED_Handle on success, or a NULL on failure. 395 * 396 * @sa LED_init() 397 * @sa LED_Params_init() 398 * @sa LED_close() 399 */ 400 LED_Handle LED_open(uint_least8_t index, LED_Params *params); 401 402 /*! 403 * @brief Function to initialize a #LED_Params struct to its defaults 404 * 405 * @param params A pointer to #LED_Params structure for 406 * initialization. 407 * 408 * The default parameters are: 409 * - LED initially off 410 * - Blink period of zero 411 * - Max brightness (for PWM LED only) 412 * - PWM period of 1 ms (for PWM LED only) 413 */ 414 extern void LED_Params_init(LED_Params *params); 415 416 /*! 417 * @brief Function to set brightness level of a LED 418 * 419 * Ignores brightness settings if LED is not PWM controlled. Fails if 420 * requested brightness is above 100%. 421 * 422 * @param ledHandle A #LED_Handle 423 * 424 * @param level Brightness level in terms of percentage (0-100) 425 * 426 * @return true on success or false upon failure. 427 */ 428 extern bool LED_setBrightnessLevel(LED_Handle ledHandle, uint8_t level); 429 430 /*! 431 * @brief Function to turn off an LED 432 * 433 * @param ledHandle An #LED_Handle 434 * 435 * @return true on success or false upon failure. 436 */ 437 extern bool LED_setOff(LED_Handle ledHandle); 438 439 /*! 440 * @brief Function to turn on an LED 441 * 442 * @param ledHandle An #LED_Handle 443 * 444 * @param brightness Brightness level in terms of percentage 0-100%. 445 * Is ignored for non PWM LEDs. 446 * 447 * @return true on success or false upon failure. 448 */ 449 extern bool LED_setOn(LED_Handle ledHandle, uint8_t brightness); 450 451 /*! 452 * @brief Function to start an LED blinking 453 * 454 * @param ledHandle An #LED_Handle 455 * 456 * @param blinkPeriod Value in ms which determines how often the LED 457 * blinks. A value of 1000 will cause the LED to 458 * blink once a second. The maximum value is ~65 seconds 459 * or 0xFFFF ms. 460 * 461 * @param blinkCount If not set to #LED_BLINK_FOREVER, the LED will blink 462 * the specified number of times and then will turn off. 463 * A value of zero will stop the LED blinking. Maximum 464 * number of blinks is 0x7FFF or 32,767 blinks. An input 465 * exceeding this value will be truncated to 0x7FFF. 466 */ 467 extern void LED_startBlinking(LED_Handle ledHandle, 468 uint16_t blinkPeriod, 469 uint16_t blinkCount); 470 471 /*! 472 * @brief Function to stop an LED blinking 473 * 474 * @param ledHandle An #LED_Handle 475 * 476 */ 477 extern void LED_stopBlinking(LED_Handle ledHandle); 478 479 /*! 480 * @brief Function to toggle an LED 481 * 482 * @param ledHandle An #LED_Handle 483 * 484 */ 485 extern void LED_toggle(LED_Handle ledHandle); 486 487 /*! 488 * @brief Specify binary state of an LED 489 * 490 * @param ledHandle An #LED_Handle 491 * 492 * @param value TRUE for on, FALSE for off 493 * 494 */ 495 extern void LED_write(LED_Handle ledHandle, bool value); 496 497 #ifdef __cplusplus 498 } 499 #endif 500 501 #endif /* ti_drivers_LED__include */ 502