1 /*
2  * Copyright 2018 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_common.h"
10 #include "fsl_adapter_pwm.h"
11 #include "fsl_ctimer.h"
12 
13 /************************************************************************************
14 *************************************************************************************
15 * Private prototypes
16 *************************************************************************************
17 ************************************************************************************/
18 typedef struct _hal_pwm_handle_struct_t
19 {
20     uint32_t pwmClock_Hz;
21     uint8_t instance;
22     uint8_t pwmLevelSelect;
23 } hal_pwm_handle_struct_t;
24 
25 /************************************************************************************
26 *************************************************************************************
27 * Private memory declarations
28 *************************************************************************************
29 ************************************************************************************/
30 
31 static CTIMER_Type *const s_cTimerBase[]                                        = CTIMER_BASE_PTRS;
32 static uint8_t s_pwmUsedChannel[sizeof(s_cTimerBase) / sizeof(s_cTimerBase[0])] = {0};
33 
34 /************************************************************************************
35 *************************************************************************************
36 * Public functions
37 *************************************************************************************
38 ************************************************************************************/
HAL_PwmInit(hal_pwm_handle_t halPwmHandle,uint8_t instance,uint32_t srcClock_Hz)39 hal_pwm_status_t HAL_PwmInit(hal_pwm_handle_t halPwmHandle, uint8_t instance, uint32_t srcClock_Hz)
40 {
41     ctimer_config_t ctimerInfo;
42     hal_pwm_handle_struct_t *halPwmState = halPwmHandle;
43 
44     assert(halPwmHandle);
45     assert(instance < (uint8_t)FSL_FEATURE_SOC_CTIMER_COUNT);
46     assert(sizeof(hal_pwm_handle_struct_t) == HAL_PWM_HANDLE_SIZE);
47     halPwmState->pwmClock_Hz = srcClock_Hz;
48     halPwmState->instance    = instance;
49 
50     /* Initialize CTIMER module */
51     if (0U == s_pwmUsedChannel[instance])
52     {
53         CTIMER_GetDefaultConfig(&ctimerInfo);
54         CTIMER_Init(s_cTimerBase[instance], &ctimerInfo);
55     }
56 
57     return kStatus_HAL_PwmSuccess;
58 }
59 
HAL_PwmDeinit(hal_pwm_handle_t halPwmHandle)60 void HAL_PwmDeinit(hal_pwm_handle_t halPwmHandle)
61 {
62     hal_pwm_handle_struct_t *halPwmState = halPwmHandle;
63 
64     assert(halPwmHandle);
65     assert(halPwmState->instance < (uint8_t)FSL_FEATURE_SOC_CTIMER_COUNT);
66 
67     /* Decrease the channel counter for the instance */
68     if (s_pwmUsedChannel[halPwmState->instance] > 0U)
69     {
70         s_pwmUsedChannel[halPwmState->instance] -= 1U;
71     }
72 
73     /* DeInitialize tpm module */
74     if (0U == s_pwmUsedChannel[halPwmState->instance])
75     {
76         CTIMER_Deinit(s_cTimerBase[halPwmState->instance]);
77     }
78 }
79 
80 /*! -------------------------------------------------------------------------
81  * \brief  Pwm setup.
82  *---------------------------------------------------------------------------*/
HAL_PwmSetupPwm(hal_pwm_handle_t halPwmHandle,uint8_t channel,hal_pwm_setup_config_t * setupConfig)83 hal_pwm_status_t HAL_PwmSetupPwm(hal_pwm_handle_t halPwmHandle, uint8_t channel, hal_pwm_setup_config_t *setupConfig)
84 {
85     hal_pwm_handle_struct_t *halPwmState = halPwmHandle;
86 
87     assert(halPwmHandle);
88     assert(channel <= (uint8_t)kCTIMER_Capture_2);
89     assert(halPwmState->instance < (uint8_t)FSL_FEATURE_SOC_CTIMER_COUNT);
90     assert(setupConfig);
91 
92     halPwmState->pwmLevelSelect = (uint8_t)(setupConfig->level);
93     if (kStatus_Success != CTIMER_SetupPwm(s_cTimerBase[halPwmState->instance], kCTIMER_Match_3,
94                                            (ctimer_match_t)channel, setupConfig->dutyCyclePercent,
95                                            setupConfig->pwmFreq_Hz, halPwmState->pwmClock_Hz, false))
96     {
97         return kStatus_HAL_PwmFail;
98     }
99 
100     CTIMER_StartTimer(s_cTimerBase[halPwmState->instance]);
101 
102     /* Increase the channel counter for the instance */
103     s_pwmUsedChannel[halPwmState->instance] += 1U;
104 
105     return kStatus_HAL_PwmSuccess;
106 }
107 
108 /*! -------------------------------------------------------------------------
109  * \brief   update the Duty cycle of pwm
110  *---------------------------------------------------------------------------*/
HAL_PwmUpdateDutycycle(hal_pwm_handle_t halPwmHandle,uint8_t channel,hal_pwm_mode_t mode,uint8_t dutyCyclePercent)111 hal_pwm_status_t HAL_PwmUpdateDutycycle(hal_pwm_handle_t halPwmHandle,
112                                         uint8_t channel,
113                                         hal_pwm_mode_t mode,
114                                         uint8_t dutyCyclePercent)
115 {
116     hal_pwm_handle_struct_t *halPwmState = halPwmHandle;
117     uint8_t duty                         = 0;
118 
119     assert(halPwmHandle);
120     assert(channel <= (uint8_t)kCTIMER_Capture_2);
121     assert(halPwmState->instance < (uint8_t)FSL_FEATURE_SOC_CTIMER_COUNT);
122     if (halPwmState->pwmLevelSelect == (uint8_t)kHAL_PwmHighTrue)
123     {
124         duty = dutyCyclePercent;
125     }
126     else
127     {
128         duty = (uint8_t)100 - dutyCyclePercent;
129     }
130     CTIMER_UpdatePwmDutycycle(s_cTimerBase[halPwmState->instance], kCTIMER_Match_3, (ctimer_match_t)channel, duty);
131     return kStatus_HAL_PwmSuccess;
132 }
133