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