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_ftm.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 } hal_pwm_handle_struct_t;
23 /************************************************************************************
24 *************************************************************************************
25 * Private memory declarations
26 *************************************************************************************
27 ************************************************************************************/
28 
29 static FTM_Type *const s_ftmBase[]                                        = FTM_BASE_PTRS;
30 static uint8_t s_pwmUsedChannel[sizeof(s_ftmBase) / sizeof(s_ftmBase[0])] = {0};
31 
32 /************************************************************************************
33 *************************************************************************************
34 * Public functions
35 *************************************************************************************
36 ************************************************************************************/
HAL_PwmInit(hal_pwm_handle_t halPwmHandle,uint8_t instance,uint32_t srcClock_Hz)37 hal_pwm_status_t HAL_PwmInit(hal_pwm_handle_t halPwmHandle, uint8_t instance, uint32_t srcClock_Hz)
38 {
39     ftm_config_t ftmInfo;
40     hal_pwm_handle_struct_t *halPwmState = halPwmHandle;
41 
42     assert(instance < (uint8_t)FSL_FEATURE_SOC_FTM_COUNT);
43     assert(NULL != halPwmHandle);
44     assert(sizeof(hal_pwm_handle_struct_t) == HAL_PWM_HANDLE_SIZE);
45     halPwmState->pwmClock_Hz = srcClock_Hz;
46     halPwmState->instance    = instance;
47 
48     /* Initialize ftm module */
49     if (0U == s_pwmUsedChannel[instance])
50     {
51         FTM_GetDefaultConfig(&ftmInfo);
52         if (kStatus_Fail == FTM_Init(s_ftmBase[instance], &ftmInfo))
53         {
54             return kStatus_HAL_PwmFail;
55         }
56     }
57 
58     return kStatus_HAL_PwmSuccess;
59 }
60 
HAL_PwmDeinit(hal_pwm_handle_t halPwmHandle)61 void HAL_PwmDeinit(hal_pwm_handle_t halPwmHandle)
62 {
63     hal_pwm_handle_struct_t *halPwmState = halPwmHandle;
64 
65     assert(halPwmHandle);
66     assert(halPwmState->instance < (uint8_t)FSL_FEATURE_SOC_FTM_COUNT);
67 
68     /* Decrease the channel counter for the instance */
69     if (s_pwmUsedChannel[halPwmState->instance] > 0U)
70     {
71         s_pwmUsedChannel[halPwmState->instance] -= 1U;
72     }
73 
74     /* DeInitialize tpm module */
75     if (0U == s_pwmUsedChannel[halPwmState->instance])
76     {
77         FTM_Deinit(s_ftmBase[halPwmState->instance]);
78     }
79 }
80 /*! -------------------------------------------------------------------------
81  * \brief  Returns the absolute time at the moment of the call.
82  * \return Absolute time at the moment of the call in microseconds.
83  *---------------------------------------------------------------------------*/
HAL_PwmSetupPwm(hal_pwm_handle_t halPwmHandle,uint8_t channel,hal_pwm_setup_config_t * setupConfig)84 hal_pwm_status_t HAL_PwmSetupPwm(hal_pwm_handle_t halPwmHandle, uint8_t channel, hal_pwm_setup_config_t *setupConfig)
85 {
86     hal_pwm_handle_struct_t *halPwmState = halPwmHandle;
87 
88     assert(halPwmHandle);
89     assert(channel <= (uint8_t)kFTM_Chnl_7);
90     assert(halPwmState->instance < (uint8_t)FSL_FEATURE_SOC_FTM_COUNT);
91     assert(setupConfig);
92     ftm_chnl_pwm_signal_param_t pwmChannelConfig = {
93         .chnlNumber       = (ftm_chnl_t)channel,
94         .level            = (ftm_pwm_level_select_t)setupConfig->level,
95         .dutyCyclePercent = setupConfig->dutyCyclePercent,
96 #if defined(FSL_FEATURE_FTM_HAS_COMBINE) && FSL_FEATURE_FTM_HAS_COMBINE
97         .firstEdgeDelayPercent = 0
98 #endif
99     };
100 
101     if (kStatus_Success != FTM_SetupPwm(s_ftmBase[halPwmState->instance], &pwmChannelConfig, 1,
102                                         (ftm_pwm_mode_t)setupConfig->mode, setupConfig->pwmFreq_Hz,
103                                         halPwmState->pwmClock_Hz))
104     {
105         return kStatus_HAL_PwmFail;
106     }
107     FTM_StartTimer(s_ftmBase[halPwmState->instance], kFTM_SystemClock);
108 
109     /* Increase the channel counter for the instance */
110     s_pwmUsedChannel[halPwmState->instance] += 1U;
111 
112     return kStatus_HAL_PwmSuccess;
113 }
114 
115 /*! -------------------------------------------------------------------------
116  * \brief   update the Duty cycle
117  *---------------------------------------------------------------------------*/
HAL_PwmUpdateDutycycle(hal_pwm_handle_t halPwmHandle,uint8_t channel,hal_pwm_mode_t mode,uint8_t dutyCyclePercent)118 hal_pwm_status_t HAL_PwmUpdateDutycycle(hal_pwm_handle_t halPwmHandle,
119                                         uint8_t channel,
120                                         hal_pwm_mode_t mode,
121                                         uint8_t dutyCyclePercent)
122 {
123     hal_pwm_handle_struct_t *halPwmState = halPwmHandle;
124 
125     assert(halPwmHandle);
126     assert(channel <= (uint8_t)kFTM_Chnl_7);
127     assert(halPwmState->instance < (uint8_t)FSL_FEATURE_SOC_FTM_COUNT);
128 
129     FTM_UpdatePwmDutycycle(s_ftmBase[halPwmState->instance], (ftm_chnl_t)channel, (ftm_pwm_mode_t)mode,
130                            dutyCyclePercent);
131     /* Software trigger to update registers */
132     FTM_SetSoftwareTrigger(s_ftmBase[halPwmState->instance], true);
133 
134     return kStatus_HAL_PwmSuccess;
135 }
136