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