1 /*
2  * Copyright 2021 MindMotion Microelectronics Co., Ltd.
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "hal_tim_32b.h"
9 
TIM_32B_Init(TIM_32B_Type * TIMx,TIM_32B_Init_Type * init)10 bool TIM_32B_Init(TIM_32B_Type * TIMx, TIM_32B_Init_Type * init)
11 {
12     uint32_t cr1 = TIMx->CR1 &~ ( TIM_32B_CR1_OPM_MASK
13                                 | TIM_32B_CR1_APRE_MASK
14                                 | TIM_32B_CR1_CMS_MASK
15                                 | TIM_32B_CR1_DIR_MASK
16                                 );
17     cr1 |= TIM_32B_CR1_OPM(init->PeriodMode);
18     cr1 |= ((init->EnablePreloadPeriod) ? TIM_32B_CR1_APRE_MASK: 0u);
19     switch ( init->CountMode )
20     {
21         case TIM_32B_CountMode_Increasing:
22             break;
23         case TIM_32B_CountMode_Decreasing:
24             cr1 |= TIM_32B_CR1_DIR_MASK;
25             break;
26         case TIM_32B_CountMode_CenterAligned1:
27             cr1 |= TIM_32B_CR1_CMS(1u);
28             break;
29         case TIM_32B_CountMode_CenterAligned2:
30             cr1 |= TIM_32B_CR1_CMS(2u);
31             break;
32         case TIM_32B_CountMode_CenterAligned3:
33             cr1 |= TIM_32B_CR1_CMS(3u);
34             break;
35         default:
36             break;
37     }
38     TIMx->CR1 = cr1;
39     /* Check the vadility of StepFreqHz. */
40     if ( (init->StepFreqHz == 0u) || (init->StepFreqHz > init->ClockFreqHz) )
41     {
42         return false;
43     }
44     /* Calculate the prescaler. */
45     TIMx->PSC = init->ClockFreqHz / init->StepFreqHz - 1u;
46     TIMx->ARR = init->Period;
47     return true;
48 }
49 
TIM_32B_Start(TIM_32B_Type * TIMx)50 void TIM_32B_Start(TIM_32B_Type * TIMx)
51 {
52     TIMx->CR1 |= TIM_32B_CR1_CEN_MASK;
53 }
54 
TIM_32B_Stop(TIM_32B_Type * TIMx)55 void TIM_32B_Stop(TIM_32B_Type * TIMx)
56 {
57     TIMx->CR1 &= ~TIM_32B_CR1_CEN_MASK;
58 }
59 
TIM_32B_GetCounterValue(TIM_32B_Type * TIMx)60 uint32_t TIM_32B_GetCounterValue(TIM_32B_Type * TIMx)
61 {
62     return TIMx->CNT;
63 }
64 
TIM_32B_ClearCounterValue(TIM_32B_Type * TIMx)65 void TIM_32B_ClearCounterValue(TIM_32B_Type * TIMx)
66 {
67     TIMx->CNT = 0u;
68 }
69 
TIM_32B_EnableInterrupts(TIM_32B_Type * TIMx,uint32_t interrupts,bool enable)70 void TIM_32B_EnableInterrupts(TIM_32B_Type * TIMx, uint32_t interrupts, bool enable)
71 {
72     if (enable)
73     {
74         TIMx->DIER |= interrupts;
75     }
76     else
77     {
78         TIMx->DIER &= ~interrupts;
79     }
80 }
81 
TIM_32B_EnableDMA(TIM_32B_Type * TIMx,uint32_t dmas,bool enable)82 void TIM_32B_EnableDMA(TIM_32B_Type * TIMx, uint32_t dmas, bool enable)
83 {
84     if (enable)
85     {
86         TIMx->DIER |= dmas;
87     }
88     else
89     {
90         TIMx->DIER &= ~dmas;
91     }
92 }
93 
TIM_32B_DoSwTrigger(TIM_32B_Type * TIMx,uint32_t swtrgs)94 void TIM_32B_DoSwTrigger(TIM_32B_Type * TIMx, uint32_t swtrgs)
95 {
96     TIMx->EGR = swtrgs;
97 }
98 
TIM_32B_GetInterruptStatus(TIM_32B_Type * TIMx)99 uint32_t TIM_32B_GetInterruptStatus(TIM_32B_Type * TIMx)
100 {
101     return TIMx->SR;
102 }
103 
TIM_32B_ClearInterruptStatus(TIM_32B_Type * TIMx,uint32_t status)104 void TIM_32B_ClearInterruptStatus(TIM_32B_Type * TIMx, uint32_t status)
105 {
106     TIMx->SR &= ~status;
107 }
108 
109 /*******************************/
_TIM_32B_WriteChannelCtrlReg(TIM_32B_Type * TIMx,uint32_t channel,uint32_t regval)110 static void _TIM_32B_WriteChannelCtrlReg(TIM_32B_Type * TIMx, uint32_t channel, uint32_t regval)
111 {
112     switch (channel)
113     {
114     case TIM_32B_CHN_1:
115         TIMx->CCMR1 = (TIMx->CCMR1 & ~(0xFF)) | (regval & 0xFF);
116         break;
117     case TIM_32B_CHN_2:
118         TIMx->CCMR1 = (TIMx->CCMR1 & ~(0xFF00)) | ((regval & 0xFF) << 8u);
119         break;
120     case TIM_32B_CHN_3:
121         TIMx->CCMR2 = (TIMx->CCMR2 & ~(0xFF)) | (regval & 0xFF);
122         break;
123     case TIM_32B_CHN_4:
124         TIMx->CCMR2 = (TIMx->CCMR2 & ~(0xFF00)) | ((regval & 0xFF) << 8u);
125         break;
126     default:
127         break;
128     }
129 }
130 
TIM_32B_EnableOutputCompare(TIM_32B_Type * TIMx,uint32_t channel,TIM_32B_OutputCompareConf_Type * conf)131 void TIM_32B_EnableOutputCompare(TIM_32B_Type * TIMx, uint32_t channel, TIM_32B_OutputCompareConf_Type * conf)
132 {
133 
134     uint32_t regval = TIM_32B_CCMR1_CC1S(TIM_32B_ChannelIOMode_Out) /* output compare mode. */
135                     | ( (conf->EnableFastOutput) ? TIM_32B_CCMR1_OC1FE_MASK : 0u ) /* fast output. */
136                     | ( (conf->EnablePreLoadChannelValue) ? TIM_32B_CCMR1_OC1PE_MASK : 0u) /* preload of channel value. */
137                     | TIM_32B_CCMR1_OC1M(conf->RefOutMode) /* output compare comparison mode. */
138                     | ( (conf->ClearRefOutOnExtTrigger) ? TIM_32B_CCMR1_OC1CE_MASK : 0u) /* external trigger clear ref. */
139                     ;
140 
141     _TIM_32B_WriteChannelCtrlReg(TIMx, channel, regval);
142 
143     TIM_32B_PutChannelValue(TIMx, channel, conf->ChannelValue);
144 
145     switch (conf->PinPolarity)
146     {
147         case TIM_32B_PinPolarity_Disable:
148             TIMx->CCER &= ~( TIM_32B_CCER_CC1E_MASK << (channel<<2u) );
149             break;
150 
151         case TIM_32B_PinPolarity_Rising:
152             TIMx->CCER = ( TIMx->CCER & ~(0xF << (channel<<2u)) )
153                        | (( TIM_32B_CCER_CC1E_MASK /* Enable the pin output / input. */
154                        ) << (channel<<2u));
155             break;
156 
157         case TIM_32B_PinPolarity_Falling:
158             TIMx->CCER = ( TIMx->CCER & ~(0xF << (channel<<2u)) )
159                        | (( TIM_32B_CCER_CC1E_MASK /* Enable the pin output / input. */
160                        |    TIM_32B_CCER_CC1P_MASK /* Set output active polarity. */
161                        |   ~TIM_32B_CCER_CC1NP_MASK
162                        ) << (channel<<2u));
163             break;
164 
165         default:
166             break;
167     }
168 }
169 
TIM_32B_EnableInputCapture(TIM_32B_Type * TIMx,uint32_t channel,TIM_32B_InputCaptureConf_Type * conf)170 void TIM_32B_EnableInputCapture(TIM_32B_Type * TIMx, uint32_t channel, TIM_32B_InputCaptureConf_Type * conf)
171 {
172     uint32_t regval = TIM_32B_CCMR1_CC1S(TIM_32B_ChannelIOMode_In) /* input capture mode. */
173                     | TIM_32B_CCMR1_IC1PSC(conf->InDiv)
174                     | TIM_32B_CCMR1_IC1F(conf->InFilter)
175                     ;
176 
177     _TIM_32B_WriteChannelCtrlReg(TIMx, channel, regval);
178 
179     switch (conf->PinPolarity)
180     {
181         case TIM_32B_PinPolarity_Disable:
182             TIMx->CCER &= ~(TIM_32B_CCER_CC1E_MASK << (channel<<2u));
183             break;
184         case TIM_32B_PinPolarity_Rising:
185             TIMx->CCER = (TIMx->CCER & ~(0xF << (channel<<2u)) )
186                        | (( TIM_32B_CCER_CC1E_MASK /* Enable the pin output / input */
187                        ) << (channel<<2u) );
188             break;
189         case TIM_32B_PinPolarity_Falling:
190             TIMx->CCER = ( TIMx->CCER & ~(0xF << (channel<<2u)) )
191                        | (( TIM_32B_CCER_CC1E_MASK /* Enable the pin output / input */
192                        |    TIM_32B_CCER_CC1P_MASK /* Set active input edge. */
193                        ) << (channel<<2u) );
194             break;
195         case TIM_32B_PinPolarity_RisingOrFalling:
196             TIMx->CCER = ( TIMx->CCER & ~(0xF << (channel<<2u)) )
197                        | (( TIM_32B_CCER_CC1E_MASK /* Enable the pin output / input */
198                        |    TIM_32B_CCER_CC1P_MASK /* Set active input edge. */
199                        |    TIM_32B_CCER_CC1NP_MASK
200                        ) << (channel<<2u) );
201             break;
202         default:
203             break;
204     }
205 }
206 
TIM_32B_GetChannelValue(TIM_32B_Type * TIMx,uint32_t channel)207 uint32_t TIM_32B_GetChannelValue(TIM_32B_Type * TIMx, uint32_t channel)
208 {
209     return TIMx->CCR[channel];
210 }
211 
TIM_32B_PutChannelValue(TIM_32B_Type * TIMx,uint32_t channel,uint32_t value)212 void TIM_32B_PutChannelValue(TIM_32B_Type * TIMx, uint32_t channel, uint32_t value)
213 {
214     TIMx->CCR[channel] = value;
215 }
216 
TIM_32B_EnableDeadArea(TIM_32B_Type * TIMx,TIM_32B_DeadAreaConf_Type * conf)217 void TIM_32B_EnableDeadArea(TIM_32B_Type * TIMx, TIM_32B_DeadAreaConf_Type * conf)
218 {
219     TIMx->CR1 = ( TIMx->CR1 &~ TIM_32B_CR1_CKD_MASK )
220               | ( TIM_32B_CR1_CKD(conf->StepFreqHz) ); /* set the frequncy ratio. */
221 }
222 
TIM_32B_EnableMasterMode(TIM_32B_Type * TIMx,TIM_32B_MasterModeConf_Type * conf)223 void TIM_32B_EnableMasterMode(TIM_32B_Type * TIMx, TIM_32B_MasterModeConf_Type * conf)
224 {
225     TIMx->CR2 = ( TIMx->CR2 &~ TIM_32B_CR2_MMS_MASK )
226               | ( TIM_32B_CR2_MMS(conf->Out) ); /* Set master mode output. */
227 
228     uint32_t smcr = TIMx->SMCR &~ TIM_32B_SMCR_MSM_MASK;
229     if (conf->EnableSync) /* synchronize with slave timers. */
230     {
231         smcr |= TIM_32B_SMCR_MSM_MASK;
232     }
233     TIMx->SMCR = smcr;
234 }
235 
TIM_32B_EnableSlaveMode(TIM_32B_Type * TIMx,TIM_32B_SlaveModeConf_Type * conf)236 void TIM_32B_EnableSlaveMode(TIM_32B_Type * TIMx, TIM_32B_SlaveModeConf_Type * conf)
237 {
238     if ( conf->Resp != TIM_32B_SlaveResp_Disable )
239     {
240         TIMx->SMCR = ( TIMx->SMCR &~ ( TIM_32B_SMCR_TS_MASK
241                                    | TIM_32B_SMCR_SMS_MASK
242                                    ) )
243                    | TIM_32B_SMCR_TS(conf->In) /* set input trigger source. */
244                    | TIM_32B_SMCR_SMS(conf->Resp); /* set response to the source */
245     }
246     else
247     {
248         TIMx->SMCR &= ~ TIM_32B_SMCR_SMS_MASK;
249     }
250 }
251 
TIM_32B_EnableExtTriggerIn(TIM_32B_Type * TIMx,TIM_32B_ExtTriggerInConf_Type * conf)252 void TIM_32B_EnableExtTriggerIn(TIM_32B_Type * TIMx, TIM_32B_ExtTriggerInConf_Type * conf)
253 {
254     uint32_t smcr = TIMx->SMCR &~ ( TIM_32B_SMCR_ETPS_MASK
255                                   | TIM_32B_SMCR_ETF_MASK
256                                   | TIM_32B_SMCR_ECE_MASK
257                                   | TIM_32B_SMCR_ETP_MASK
258                                   );
259     switch (conf->PinPolarity)
260     {
261         case TIM_32B_PinPolarity_Disable:
262             break;
263         case TIM_32B_PinPolarity_Rising:
264             smcr |= TIM_32B_SMCR_ECE_MASK; /* enable external trigger input. */
265             break;
266         case TIM_32B_PinPolarity_Falling:
267             smcr |= TIM_32B_SMCR_ETP_MASK; /* falling edge active. */
268             smcr |= TIM_32B_SMCR_ECE_MASK; /* enable external trigger input. */
269             break;
270         default:
271             break;
272     }
273     smcr |= TIM_32B_SMCR_ETPS( conf->InDiv ); /* division to the input external trigger. */
274     smcr |= TIM_32B_SMCR_ETF( conf->InFilter ); /* set filter. */
275     TIMx->SMCR = smcr;
276 }
277 
TIM_32B_EnableDMABurst(TIM_32B_Type * TIMx,TIM_32B_DMABurstConf_Type * conf)278 uint32_t TIM_32B_EnableDMABurst(TIM_32B_Type * TIMx, TIM_32B_DMABurstConf_Type * conf)
279 {
280     TIMx->DCR = TIM_32B_DCR_DBA(conf->BaseAddr) | TIM_32B_DCR_DBL(conf->Length);
281     return (uint32_t)(&(TIMx->DMAR));
282 }
283 
TIM_32B_GetEncoder(TIM_32B_Type * TIMx,uint32_t * value)284 TIM_32B_EncoderDirection_Type TIM_32B_GetEncoder(TIM_32B_Type * TIMx, uint32_t * value)
285 {
286     if (value)
287     {
288         * value = TIM_32B_GetCounterValue(TIMx);
289     }
290 
291     if ( (TIMx->CR1 & TIM_32B_CR1_DIR_MASK) != 0u )
292     {
293         return TIM_32B_EncoderDirection_Backward;
294     }
295     else
296     {
297         return TIM_32B_EncoderDirection_Forward;
298     }
299 }
300 
301 /* EOF. */
302 
303