1 /*
2  * Copyright 2018 - 2019 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_adapter_gpio.h"
10 #include "fsl_component_timer_manager.h"
11 
12 #include "fsl_component_led.h"
13 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
14 #include "fsl_adapter_pwm.h"
15 #endif
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 #if defined(OSA_USED)
21 #include "fsl_os_abstraction.h"
22 #if (defined(USE_RTOS) && (USE_RTOS > 0U))
23 #define LED_ENTER_CRITICAL() \
24     OSA_SR_ALLOC();          \
25     OSA_ENTER_CRITICAL()
26 #define LED_EXIT_CRITICAL() OSA_EXIT_CRITICAL()
27 #else
28 #define LED_ENTER_CRITICAL()
29 #define LED_EXIT_CRITICAL()
30 #endif
31 #else
32 #define LED_ENTER_CRITICAL() uint32_t regPrimask = DisableGlobalIRQ();
33 #define LED_EXIT_CRITICAL()  EnableGlobalIRQ(regPrimask);
34 #endif
35 
36 /* LED control type enumeration */
37 typedef enum _led_control_type
38 {
39     kLED_TurnOffOn = 0x01U, /*!< Turn Off or on*/
40     kLED_Flash,             /*!< Flash */
41 #if (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U))
42     kLED_TricolorCycleFlash, /*!< Tricolor Cycle Flash */
43     kLED_CycleFlash,         /*!< Cycle Flash */
44 #endif                       /* (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U)) */
45     kLED_Dimming,            /*!< Dimming */
46 } led_control_type_t;
47 
48 /* LED Dimming state structure when dimming is enabled */
49 typedef struct _led_dimming
50 {
51     uint8_t increasement;
52     uint8_t powerDelta[sizeof(led_config_t) / sizeof(led_pin_config_t)];
53 } led_dimming_t;
54 
55 /*! @brief The pin config struct of LED */
56 typedef struct _led_pin
57 {
58     union
59     {
60         struct
61         {
62             uint16_t type : 2U;          /*!< LED type, 1 - RGB, 2 - Monochrome */
63             uint16_t dimmingEnable : 1U; /*!< dimming enable, 0 - disable, 1 - enable */
64             uint16_t : 13U;
65         } config;
66         struct
67         {
68             uint16_t : 3U;
69             uint16_t port : 4U;            /*!< GPIO Port */
70             uint16_t pin : 5U;             /*!< GPIO Pin */
71             uint16_t pinStateDefault : 1U; /*!< GPIO Pin voltage when LED is off (0 - low level, 1 - high level)*/
72             uint16_t : 3U;
73         } gpio;
74         struct
75         {
76             uint16_t : 3U;
77             uint16_t instance : 4U;        /*!< PWM instance of the pin */
78             uint16_t channel : 5U;         /*!< PWM channel of the pin */
79             uint16_t pinStateDefault : 1U; /*!< The Pin voltage when LED is off (0 - low level, 1 - high level)*/
80             uint16_t : 3U;
81         } dimming;
82     };
83 } led_pin_t;
84 
85 /* LED state structure */
86 typedef struct _led_state
87 {
88     struct _led_state *next;
89     uint32_t gpioHandle[sizeof(led_config_t) / sizeof(led_pin_config_t)]
90                        [((HAL_GPIO_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
91     volatile uint32_t expiryPeriodCount;
92 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
93     uint32_t pwmHandle[sizeof(led_config_t) / sizeof(led_pin_config_t)]
94                       [((HAL_PWM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
95 #endif
96     uint32_t flashCycle;
97     led_color_t settingColor;
98     led_color_t currentColor;
99     led_color_t nextColor;
100 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
101     const led_config_t *pinsConfig;
102 #else
103     led_pin_t pins[sizeof(led_config_t) / sizeof(led_pin_config_t)];
104 #endif
105     uint16_t flashPeriod;
106 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
107     led_dimming_t dimming;
108 #endif
109     struct
110     {
111         uint16_t controlType : 4U;
112 #if (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U))
113         uint16_t flashCount : 3U;
114 #endif
115         uint16_t : 1U;
116         uint16_t flashDuty : 7U;
117         uint16_t : 1U;
118     };
119 } led_state_t;
120 
121 typedef struct _led_list
122 {
123     led_state_t *ledState;
124     volatile uint32_t periodCount;
125     TIMER_MANAGER_HANDLE_DEFINE(timerHandle);
126 } led_list_t;
127 
128 /*******************************************************************************
129  * Prototypes
130  ******************************************************************************/
131 
132 /*******************************************************************************
133  * Variables
134  ******************************************************************************/
135 static led_list_t s_ledList;
136 
137 /*******************************************************************************
138  * Code
139  ******************************************************************************/
140 #if defined(__IAR_SYSTEMS_ICC__)
141 #pragma inline   = never
142 #pragma optimize = no_inline
143 #elif defined(__GNUC__)
144 #endif
145 
LED_SetStatus(led_state_t * ledState,led_color_t color,uint32_t threshold)146 static led_status_t LED_SetStatus(led_state_t *ledState, led_color_t color, uint32_t threshold)
147 {
148 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
149     led_pin_config_t *ledRgbPin;
150 #else
151     led_pin_t *ledRgbPin;
152 #endif
153     led_status_t status = kStatus_LED_Success;
154     led_color_t colorSet;
155     uint8_t count = 1;
156 
157     ledState->expiryPeriodCount = s_ledList.periodCount + threshold;
158 
159 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
160     ledRgbPin = (led_pin_config_t *)(const void *)&ledState->pinsConfig->ledRgb;
161 #else
162     ledRgbPin = (led_pin_t *)ledState->pins;
163 #endif
164 
165 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
166     if (kLED_TypeRgb == ledState->pinsConfig->type)
167 #else
168     if ((uint16_t)kLED_TypeRgb == ledRgbPin->config.type)
169 #endif
170     {
171         count = sizeof(led_config_t) / sizeof(led_pin_config_t);
172     }
173 
174     for (uint8_t i = 0; i < count; i++)
175     {
176         colorSet = ((color >> (i * 8U)) & (0xFFU));
177 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
178 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
179         if (0U != ledRgbPin[i].dimmingEnable)
180 #else
181         if (0U != ledRgbPin[i].config.dimmingEnable)
182 #endif
183         {
184             (void)HAL_PwmUpdateDutycycle(ledState->pwmHandle[i], (uint8_t)ledRgbPin[i].dimming.channel,
185                                          kHAL_EdgeAlignedPwm, (uint8_t)(colorSet * 100U / 255U));
186         }
187         else
188 #endif
189         {
190 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
191             (void)HAL_GpioSetOutput(ledState->gpioHandle[i], (colorSet != 0U) ?
192                                                                  (1U - (uint8_t)ledRgbPin[i].gpio.level) :
193                                                                  (uint8_t)ledRgbPin[i].gpio.level);
194 #else
195             (void)HAL_GpioSetOutput(ledState->gpioHandle[i], (colorSet != 0U) ?
196                                                                  (1U - (uint8_t)ledRgbPin[i].gpio.pinStateDefault) :
197                                                                  (uint8_t)ledRgbPin[i].gpio.pinStateDefault);
198 #endif
199         }
200     }
201 
202     return status;
203 }
204 
LED_TimerEvent(void * param)205 static void LED_TimerEvent(void *param)
206 {
207     led_state_t *ledState = (led_state_t *)s_ledList.ledState;
208     uint32_t threshold    = 0;
209     led_color_t color;
210 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
211     uint16_t power[sizeof(led_config_t) / sizeof(led_pin_config_t)];
212     uint8_t count = sizeof(led_config_t) / sizeof(led_pin_config_t);
213 #endif
214 
215     s_ledList.periodCount += LED_TIMER_INTERVAL;
216 
217     while (NULL != ledState)
218     {
219         if (s_ledList.periodCount >= ledState->expiryPeriodCount)
220         {
221             switch (ledState->controlType)
222             {
223                 case (uint16_t)kLED_Flash: /*!< Flash */
224 #if (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U))
225                 case (uint16_t)kLED_TricolorCycleFlash: /*!< Tricolor Cycle Flash */
226                 case (uint16_t)kLED_CycleFlash:         /*!< Cycle Flash */
227 #endif /* (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U)) */
228                     if (LED_FLASH_CYCLE_FOREVER != ledState->flashCycle)
229                     {
230                         if ((0U != ledState->flashCycle))
231                         {
232                             if (((led_color_t)kLED_Black == ledState->currentColor) || (100U == ledState->flashDuty))
233                             {
234                                 ledState->flashCycle--;
235                             }
236                         }
237                     }
238                     if (0U != ledState->flashCycle)
239                     {
240                         if ((100U > ledState->flashDuty))
241                         {
242                             color                  = ledState->nextColor;
243                             ledState->nextColor    = ledState->currentColor;
244                             ledState->currentColor = color;
245                         }
246 
247                         if (((led_color_t)kLED_Black == ledState->currentColor))
248                         {
249                             threshold = (uint32_t)ledState->flashPeriod * (100U - (uint32_t)ledState->flashDuty) / 100U;
250                         }
251                         else
252                         {
253 #if (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U))
254                             ledState->flashCount++;
255                             if ((uint16_t)kLED_TricolorCycleFlash == ledState->controlType)
256                             {
257                                 ledState->currentColor = (led_color_t)(0xFFUL << ((ledState->flashCount % 3U) * 8U));
258                             }
259                             else if ((uint16_t)kLED_CycleFlash == ledState->controlType)
260                             {
261                                 color = 0;
262                                 if (0U == ((ledState->flashCount) & 0x07U))
263                                 {
264                                     (ledState->flashCount)++;
265                                 }
266                                 if (0U != ((ledState->flashCount) & 0x04U))
267                                 {
268                                     color = (led_color_t)0xFF0000;
269                                 }
270                                 if (0U != ((ledState->flashCount) & 0x02U))
271                                 {
272                                     color |= (led_color_t)0xFF00;
273                                 }
274                                 if (0U != ((ledState->flashCount) & 0x01U))
275                                 {
276                                     color |= (led_color_t)0xFF;
277                                 }
278                                 ledState->currentColor = color;
279                             }
280                             else
281                             {
282                                 /*Misra Rule 15.7*/
283                             }
284 #endif /* (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U)) */
285                             threshold = (uint32_t)ledState->flashPeriod * (uint32_t)(ledState->flashDuty) / 100U;
286                         }
287 
288                         (void)LED_SetStatus(ledState, ledState->currentColor, threshold);
289                     }
290                     break;
291 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
292                 case (uint16_t)kLED_Dimming: /*!< Dimming */
293                     for (uint8_t i = 0; i < count; i++)
294                     {
295                         uint8_t value = (uint8_t)((ledState->currentColor >> (8U * i)) & 0xFFU);
296                         if (0U != ledState->dimming.increasement)
297                         {
298                             if ((value + ledState->dimming.powerDelta[i]) < 0xFFU)
299                             {
300                                 power[i] = (uint16_t)value + (uint16_t)ledState->dimming.powerDelta[i];
301                             }
302                             else
303                             {
304                                 power[i] = 0xFFU;
305                             }
306                         }
307                         else
308                         {
309                             if (value > ledState->dimming.powerDelta[i])
310                             {
311                                 power[i] = (uint16_t)value - (uint16_t)ledState->dimming.powerDelta[i];
312                             }
313                             else
314                             {
315                                 power[i] = 0;
316                             }
317                         }
318 
319 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
320                         if (kLED_TypeMonochrome == ledState->pinsConfig->type)
321 #else
322                         if ((uint16_t)kLED_TypeMonochrome == ledState->pins[0].config.type)
323 #endif
324                         {
325                             break;
326                         }
327                     }
328                     ledState->currentColor = LED_MAKE_COLOR(power[0], power[1], power[2]);
329                     (void)LED_SetStatus(ledState, ledState->currentColor, ledState->flashPeriod);
330                     break;
331 #endif
332                 default:
333                     /* MISRA Rule 16.4*/
334                     break;
335             }
336         }
337         ledState = ledState->next;
338     }
339 }
340 
LED_Init(led_handle_t ledHandle,const led_config_t * ledConfig)341 led_status_t LED_Init(led_handle_t ledHandle, const led_config_t *ledConfig)
342 {
343     led_state_t *ledState;
344     led_pin_config_t *ledRgbConfigPin;
345 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
346 #else
347     hal_gpio_pin_config_t controlPin;
348 #endif
349     uint32_t count = 1;
350     uint32_t regPrimask;
351     int i;
352 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
353     /* The configure parameters check only work on debug mode in order to reduce code size. */
354 #ifdef NDEBUG
355 #else  /* NDEBUG */
356     uint8_t rgbFlag = 0;
357     uint8_t rgbDimmingFlag = 0;
358 #endif /* NDEBUG */
359 #endif
360 
361     assert((NULL != ledHandle) && (NULL != ledConfig));
362     assert(LED_HANDLE_SIZE >= sizeof(led_state_t));
363 
364     if (kLED_TypeRgb == ledConfig->type)
365     {
366         count = sizeof(led_config_t) / sizeof(led_pin_config_t);
367     }
368 
369     ledState = (led_state_t *)ledHandle;
370 
371     (void)memset(ledHandle, 0, sizeof(led_state_t));
372 
373     regPrimask = DisableGlobalIRQ();
374     if (NULL == s_ledList.ledState)
375     {
376         do
377         {
378             timer_status_t tmState;
379             tmState = TM_Open((timer_handle_t)s_ledList.timerHandle);
380             assert(kStatus_TimerSuccess == tmState);
381 
382             tmState = TM_InstallCallback(s_ledList.timerHandle, LED_TimerEvent, &s_ledList);
383             assert(kStatus_TimerSuccess == tmState);
384 
385             tmState = TM_Start(s_ledList.timerHandle, (uint8_t)kTimerModeIntervalTimer, LED_TIMER_INTERVAL);
386             assert(kStatus_TimerSuccess == tmState);
387             (void)tmState;
388 
389             s_ledList.ledState = ledState;
390         } while (false);
391     }
392     else
393     {
394         ledState->next     = s_ledList.ledState;
395         s_ledList.ledState = ledState;
396     }
397     EnableGlobalIRQ(regPrimask);
398 
399     assert(s_ledList.ledState);
400     ledState->settingColor = (led_color_t)kLED_White;
401     ledRgbConfigPin        = (led_pin_config_t *)(const void *)&ledConfig->ledRgb;
402 
403 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
404     ledState->pinsConfig = ledConfig;
405 #else
406     controlPin.direction = kHAL_GpioDirectionOut;
407 #endif
408 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
409     /* The configure parameters check only work on debug mode in order to reduce code size. */
410 #ifdef NDEBUG
411 #else  /* NDEBUG */
412     for (i = 0; i < (int)count; i++)
413     {
414         if (0U != ledRgbConfigPin[i].dimmingEnable)
415         {
416             rgbDimmingFlag = 1;
417         }
418         else
419         {
420             rgbFlag = 1;
421         }
422     }
423     assert(!((0U != rgbDimmingFlag) && (0U != rgbFlag)));
424 #endif /* NDEBUG */
425 #endif
426     for (i = 0; i < (int)count; i++)
427     {
428 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
429 #else
430         ledState->pins[i].config.type = (uint16_t)ledConfig->type;
431 #endif
432 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
433         if (0U != ledRgbConfigPin[i].dimmingEnable)
434         {
435             hal_pwm_setup_config_t setupConfig;
436 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
437 #else
438             ledState->pins[i].config.dimmingEnable = ledRgbConfigPin[i].dimmingEnable;
439             ledState->pins[i].dimming.instance = ledRgbConfigPin[i].dimming.instance;
440             ledState->pins[i].dimming.channel = ledRgbConfigPin[i].dimming.channel;
441             ledState->pins[i].dimming.pinStateDefault = ledRgbConfigPin[i].dimming.pinStateDefault;
442 #endif
443             (void)HAL_PwmInit((hal_pwm_handle_t)ledState->pwmHandle[i], ledRgbConfigPin[i].dimming.instance,
444                               ledRgbConfigPin[i].dimming.sourceClock);
445             setupConfig.dutyCyclePercent = 0;
446             setupConfig.level            = (0U != ledRgbConfigPin[i].dimming.pinStateDefault) ?
447                                     (hal_pwm_level_select_t)kHAL_PwmLowTrue :
448                                     (hal_pwm_level_select_t)kHAL_PwmHighTrue;
449             setupConfig.mode       = kHAL_EdgeAlignedPwm;
450             setupConfig.pwmFreq_Hz = 1000U;
451             (void)HAL_PwmSetupPwm(ledState->pwmHandle[i], ledRgbConfigPin[i].dimming.channel, &setupConfig);
452         }
453         else
454 #endif
455         {
456 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
457 #else
458             ledState->pins[i].gpio.port            = ledRgbConfigPin[i].gpio.port;
459             ledState->pins[i].gpio.pin             = ledRgbConfigPin[i].gpio.pin;
460             ledState->pins[i].gpio.pinStateDefault = ledRgbConfigPin[i].gpio.pinStateDefault;
461             controlPin.port                        = ledRgbConfigPin[i].gpio.port;
462             controlPin.pin                         = ledRgbConfigPin[i].gpio.pin;
463             controlPin.level                       = ledRgbConfigPin[i].gpio.pinStateDefault;
464 #endif
465 
466 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
467             if (kStatus_HAL_GpioSuccess != HAL_GpioInit((hal_gpio_handle_t)ledState->gpioHandle[i],
468                                                         (hal_gpio_pin_config_t *)&ledRgbConfigPin[i].gpio))
469 #else
470             if (kStatus_HAL_GpioSuccess != HAL_GpioInit((hal_gpio_handle_t)ledState->gpioHandle[i], &controlPin))
471 #endif
472             {
473                 return kStatus_LED_Error;
474             }
475         }
476     }
477 
478     return LED_TurnOnOff(ledState, 0);
479 }
480 
LED_Deinit(led_handle_t ledHandle)481 led_status_t LED_Deinit(led_handle_t ledHandle)
482 {
483     led_state_t *ledState;
484     led_state_t *ledStatePre;
485     uint32_t regPrimask;
486 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
487 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
488     led_pin_config_t *ledRgbPin;
489 #else
490     led_pin_t *ledRgbPin;
491 #endif
492 #endif
493 
494     assert(ledHandle);
495 
496     ledState = (led_state_t *)ledHandle;
497 
498     regPrimask  = DisableGlobalIRQ();
499     ledStatePre = s_ledList.ledState;
500     if (ledStatePre != ledState)
501     {
502         while ((NULL != ledStatePre) && (ledStatePre->next != ledState))
503         {
504             ledStatePre = ledStatePre->next;
505         }
506         if (NULL != ledStatePre)
507         {
508             ledStatePre->next = ledState->next;
509         }
510     }
511     else
512     {
513         s_ledList.ledState = ledState->next;
514     }
515 
516     if (NULL == s_ledList.ledState)
517     {
518         (void)TM_Close(s_ledList.timerHandle);
519     }
520     EnableGlobalIRQ(regPrimask);
521 
522 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
523 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
524     ledRgbPin = (led_pin_config_t *)(void *)&ledState->pinsConfig->ledRgb;
525 #else
526     ledRgbPin = (led_pin_t *)(ledState->pins);
527 #endif
528 #endif
529     for (uint32_t i = 0; i < (sizeof(led_config_t) / sizeof(led_pin_config_t)); i++)
530     {
531 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
532 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
533         if (0U != ledRgbPin[i].dimmingEnable)
534 #else
535         if (0u != ledRgbPin[i].config.dimmingEnable)
536 #endif
537         {
538             HAL_PwmDeinit(ledState->pwmHandle[i]);
539         }
540         else
541 #endif
542         {
543             (void)HAL_GpioDeinit(ledState->gpioHandle[i]);
544         }
545 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
546         if (kLED_TypeRgb != ledState->pinsConfig->type)
547 #else
548         if (((uint16_t)kLED_TypeRgb != ledState->pins[i].config.type))
549 #endif
550         {
551             break;
552         }
553     }
554 
555     return kStatus_LED_Success;
556 }
557 
LED_TurnOnOff(led_handle_t ledHandle,uint8_t turnOnOff)558 led_status_t LED_TurnOnOff(led_handle_t ledHandle, uint8_t turnOnOff)
559 {
560     led_state_t *ledState;
561 
562     assert(ledHandle);
563 
564     ledState               = (led_state_t *)ledHandle;
565     ledState->controlType  = (uint16_t)kLED_TurnOffOn;
566     ledState->currentColor = (1U == turnOnOff) ? ledState->settingColor : (led_color_t)kLED_Black;
567     (void)LED_SetStatus(ledState, ledState->currentColor, 0);
568     return kStatus_LED_Success;
569 }
570 
LED_SetColor(led_handle_t ledHandle,led_color_t ledRgbColor)571 led_status_t LED_SetColor(led_handle_t ledHandle, led_color_t ledRgbColor)
572 {
573     led_state_t *ledState;
574 
575     assert(ledHandle);
576 
577     ledState = (led_state_t *)ledHandle;
578 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
579     assert(kLED_TypeRgb == ledState->pinsConfig->type);
580 #else
581     assert((uint16_t)kLED_TypeRgb == ledState->pins[0].config.type);
582 #endif
583 
584     ledState->settingColor = ledRgbColor;
585 
586     return kStatus_LED_Success;
587 }
588 
LED_Flash(led_handle_t ledHandle,led_flash_config_t * ledFlash)589 led_status_t LED_Flash(led_handle_t ledHandle, led_flash_config_t *ledFlash)
590 {
591     led_state_t *ledState;
592 
593     assert(ledHandle);
594     assert(ledFlash);
595     assert(ledFlash->times);
596     assert(ledFlash->duty <= 100U);
597 
598     ledState = (led_state_t *)ledHandle;
599 
600     ledState->flashPeriod = ledFlash->period;
601     ledState->flashDuty   = ledFlash->duty;
602 
603     ledState->currentColor = ledState->settingColor;
604     ledState->flashCycle   = ledFlash->times;
605     ledState->nextColor    = (led_color_t)kLED_Black;
606 
607 #if (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U))
608     if (kLED_FlashOneColor == ledFlash->flashType)
609     {
610         ledState->controlType = (uint16_t)kLED_Flash;
611     }
612     else
613     {
614 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
615         assert(kLED_TypeRgb == ledState->pinsConfig->type);
616 #else
617         assert((uint16_t)kLED_TypeRgb == ledState->pins[0].config.type);
618 #endif
619         ledState->controlType = (uint16_t)kLED_CycleFlash;
620     }
621 #else
622     ledState->controlType = (uint16_t)kLED_Flash;
623 #endif /* (defined(LED_COLOR_WHEEL_ENABLEMENT) && (LED_COLOR_WHEEL_ENABLEMENT > 0U)) */
624     (void)LED_SetStatus(ledState, ledState->currentColor,
625                         ((uint32_t)ledState->flashPeriod * (uint32_t)ledState->flashDuty) / 100U);
626     return kStatus_LED_Success;
627 }
628 
LED_Blip(led_handle_t ledHandle)629 led_status_t LED_Blip(led_handle_t ledHandle)
630 {
631     led_flash_config_t ledFlash;
632 
633     ledFlash.duty      = 50;
634     ledFlash.flashType = kLED_FlashOneColor;
635     ledFlash.period    = LED_BLIP_INTERVAL;
636     ledFlash.times     = 1;
637     return LED_Flash(ledHandle, &ledFlash);
638 }
639 
LED_Dimming(led_handle_t ledHandle,uint16_t dimmingPeriod,uint8_t increasement)640 led_status_t LED_Dimming(led_handle_t ledHandle, uint16_t dimmingPeriod, uint8_t increasement)
641 {
642 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
643     led_state_t *ledState;
644     uint16_t power[sizeof(led_config_t) / sizeof(led_pin_config_t)];
645     uint8_t value;
646     uint8_t count = sizeof(led_config_t) / sizeof(led_pin_config_t);
647 
648     assert(ledHandle);
649     assert(dimmingPeriod);
650 
651     ledState = (led_state_t *)ledHandle;
652 
653 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
654     assert(ledState->pinsConfig->ledRgb.redPin.dimmingEnable);
655 #else
656     assert(ledState->pins[0].config.dimmingEnable);
657 #endif
658 
659     LED_ENTER_CRITICAL();
660 
661     ledState->controlType          = (uint16_t)kLED_Dimming;
662     ledState->flashPeriod          = LED_DIMMING_UPDATE_INTERVAL;
663     ledState->flashDuty            = 100U;
664     ledState->dimming.increasement = increasement;
665 
666 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
667     if (kLED_TypeRgb == ledState->pinsConfig->type)
668 #else
669     if ((uint16_t)kLED_TypeRgb == ledState->pins[0].config.type)
670 #endif
671     {
672         ledState->currentColor = ledState->settingColor;
673     }
674 
675     for (uint8_t i = 0U; i < count; i++)
676     {
677         ledState->dimming.powerDelta[i] = 0U;
678     }
679 
680     for (uint8_t i = 0U; i < count; i++)
681     {
682         value = (uint8_t)((ledState->currentColor >> (8U * (i))) & 0xFFU);
683         if (0U != ledState->dimming.increasement)
684         {
685             ledState->dimming.powerDelta[i] =
686                 (uint8_t)(((uint16_t)0xFF - value) * LED_DIMMING_UPDATE_INTERVAL / (dimmingPeriod));
687             if ((value + ledState->dimming.powerDelta[i]) < 0xFFU)
688             {
689                 power[i] = (uint16_t)value + ledState->dimming.powerDelta[i];
690             }
691             else
692             {
693                 power[i] = 0xFFU;
694             }
695         }
696         else
697         {
698             ledState->dimming.powerDelta[i] =
699                 (uint8_t)((uint16_t)(value)*LED_DIMMING_UPDATE_INTERVAL / (dimmingPeriod));
700             if (value > ledState->dimming.powerDelta[i])
701             {
702                 power[i] = (uint16_t)value - (uint16_t)ledState->dimming.powerDelta[i];
703             }
704             else
705             {
706                 power[i] = 0U;
707             }
708         }
709 #if (defined(LED_USE_CONFIGURE_STRUCTURE) && (LED_USE_CONFIGURE_STRUCTURE > 0U))
710         if (kLED_TypeMonochrome == ledState->pinsConfig->type)
711 #else
712         if ((uint16_t)kLED_TypeMonochrome == ledState->pins[0].config.type)
713 #endif
714         {
715             break;
716         }
717     }
718 
719     ledState->currentColor = LED_MAKE_COLOR(power[0], power[1], power[2]);
720     ledState->flashCycle   = LED_FLASH_CYCLE_FOREVER;
721     LED_EXIT_CRITICAL();
722     (void)LED_SetStatus(ledState, ledState->currentColor, ledState->flashPeriod);
723 
724     return kStatus_LED_Success;
725 #else
726     return kStatus_LED_Error;
727 #endif
728 }
729 
LED_EnterLowpower(led_handle_t ledHandle)730 led_status_t LED_EnterLowpower(led_handle_t ledHandle)
731 {
732 #if 0
733     led_state_t* ledState;
734     led_pin_config_t* ledRgbPin;
735     led_status_t status;
736     int count;
737 
738     assert(ledHandle);
739 
740     ledState = (led_state_t*)ledHandle;
741 
742     ledRgbPin = (led_pin_config_t*)&ledState->config.ledRgb;
743     if (kLED_TypeRgb == ledState->config.type)
744     {
745         count = sizeof(led_config_t) / sizeof(led_pin_config_t);
746     }
747     else
748     {
749         count = 1;
750     }
751 
752     for (int i = 0;i < count; i++)
753     {
754 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
755         if (ledRgbPin[i].dimmingEnable)
756         {
757             HAL_PwmEnterLowpower(ledRgbPin[i].dimming.instance, ledRgbPin[i].dimming.channel);
758         }
759         else
760 #endif
761         {
762             HAL_GpioEnterLowpower(ledState->gpioHandle[i]);
763         }
764     }
765 #endif
766     return kStatus_LED_Success;
767 }
768 
LED_ExitLowpower(led_handle_t ledHandle)769 led_status_t LED_ExitLowpower(led_handle_t ledHandle)
770 {
771 #if 0
772     led_state_t* ledState;
773     led_pin_config_t* ledRgbPin;
774     led_status_t status;
775     int count;
776 
777     assert(ledHandle);
778 
779     ledState = (led_state_t*)ledHandle;
780 
781     ledRgbPin = (led_pin_config_t*)&ledState->config.ledRgb;
782     if (kLED_TypeRgb == ledState->config.type)
783     {
784         count = sizeof(led_config_t) / sizeof(led_pin_config_t);
785     }
786     else
787     {
788         count = 1;
789     }
790 
791     for (int i = 0;i < count; i++)
792     {
793 #if (defined(LED_DIMMING_ENABLEMENT) && (LED_DIMMING_ENABLEMENT > 0U))
794         if (ledRgbPin[i].dimmingEnable)
795         {
796             HAL_PwmExitLowpower(ledRgbPin[i].dimming.instance, ledRgbPin[i].dimming.channel);
797         }
798         else
799 #endif
800         {
801             HAL_GpioExitLowpower(ledState->gpioHandle[i]);
802         }
803     }
804 #endif
805     return kStatus_LED_Success;
806 }
807