1 | /** |
---|
2 | ****************************************************************************** |
---|
3 | * @file Project/STM32L0_Internal_RC_Oscillators_Calibration/Src/hsi16.c |
---|
4 | * @author MCD Application Team |
---|
5 | * @version V0.1.0 |
---|
6 | * @date 17-December-2014 |
---|
7 | * @brief This file provides all the HSI measurement and calibration firmware functions. |
---|
8 | ****************************************************************************** |
---|
9 | * @attention |
---|
10 | * |
---|
11 | * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> |
---|
12 | * |
---|
13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); |
---|
14 | * You may not use this file except in compliance with the License. |
---|
15 | * You may obtain a copy of the License at: |
---|
16 | * |
---|
17 | * http://www.st.com/software_license_agreement_liberty_v2 |
---|
18 | * |
---|
19 | * Unless required by applicable law or agreed to in writing, software |
---|
20 | * distributed under the License is distributed on an "AS IS" BASIS, |
---|
21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
---|
22 | * See the License for the specific language governing permissions and |
---|
23 | * limitations under the License. |
---|
24 | * |
---|
25 | ****************************************************************************** |
---|
26 | */ |
---|
27 | |
---|
28 | /* Includes ------------------------------------------------------------------*/ |
---|
29 | #include "hsi16.h" |
---|
30 | #include <stdio.h> |
---|
31 | /* Private typedef -----------------------------------------------------------*/ |
---|
32 | /* Private define ------------------------------------------------------------*/ |
---|
33 | #define HSI16_MEASURE_FREQUENCY_TABLE |
---|
34 | |
---|
35 | // Timer related Defines |
---|
36 | #define CAPTURE_START ((uint32_t) 0x00000001) |
---|
37 | #define CAPTURE_ONGOING ((uint32_t) 0x00000002) |
---|
38 | #define CAPTURE_COMPLETED ((uint32_t) 0x00000003) |
---|
39 | #define CAPTURE_READY_FOR_NEW ((uint32_t) 0x00000004) |
---|
40 | |
---|
41 | #define __TIMx_CLK_ENABLE() __HAL_RCC_TIM16_CLK_ENABLE() |
---|
42 | #define TIMx TIM16 |
---|
43 | #define TIM_CHANNEL_y TIM_CHANNEL_1 |
---|
44 | #define HAL_TIM_ACTIVE_CHANNEL_y HAL_TIM_ACTIVE_CHANNEL_1 |
---|
45 | #define TIM_TIMx_GPIO TIM16_TI1_GPIO |
---|
46 | #define TIM_TIMx_LSE TIM_TIM16_TI1_LSE |
---|
47 | #define TIM_TIMx_MCO TIM16_TI1_MCO |
---|
48 | #define TIMx_IRQn TIM16_IRQn |
---|
49 | |
---|
50 | #define INITIAL_ERROR ((uint32_t)99999000) |
---|
51 | |
---|
52 | /* Exported macro ------------------------------------------------------------*/ |
---|
53 | #define __HAL_GET_TIM_PRESCALER(__HANDLE__) ((__HANDLE__)->Instance->PSC) |
---|
54 | #define ABS_RETURN(x) ((x < 0) ? (-x) : (x)) |
---|
55 | |
---|
56 | #define HSI16_TIMx_COUNTER_PRESCALER ((uint32_t)0) |
---|
57 | /* The signal in input capture is divided by 8 */ |
---|
58 | #define HSI16_TIMx_IC_DIVIDER TIM_ICPSC_DIV8 |
---|
59 | |
---|
60 | /* The LSE is divided by 8 => LSE/8 = 32768/8 = 4096 */ |
---|
61 | #define REFERENCE_FREQUENCY ((uint32_t)4096) /*!< The reference frequency value in Hz */ |
---|
62 | |
---|
63 | /* Number of measurements in the loop */ |
---|
64 | #define HSI16_NUMBER_OF_LOOPS ((uint32_t)10) |
---|
65 | |
---|
66 | /* Timeout to avoid endless loop */ |
---|
67 | #define HSI16_TIMEOUT ((uint32_t)0xFFFFFF) |
---|
68 | |
---|
69 | /* Get actual trimming settings of HSI16 */ |
---|
70 | #define GET_HSI16_TRIMMING_VALUE() ((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> 8) |
---|
71 | |
---|
72 | /* Private macro -------------------------------------------------------------*/ |
---|
73 | /* Private variables ---------------------------------------------------------*/ |
---|
74 | |
---|
75 | TIM_HandleTypeDef TimHandle; /* Timer handler declaration */ |
---|
76 | |
---|
77 | static uint16_t LSIFrequency = LSI_VALUE; |
---|
78 | static uint32_t __IO CaptureState = 0; |
---|
79 | static uint32_t __IO Capture = 0; |
---|
80 | static uint32_t IC1ReadValue1 = 0, IC1ReadValue2 = 0; |
---|
81 | |
---|
82 | #ifdef HSI16_MEASURE_FREQUENCY_TABLE |
---|
83 | int32_t aFrequenceChangeTable[128]; /* 2^7 positions*/ |
---|
84 | #endif |
---|
85 | |
---|
86 | /* Private function prototypes -----------------------------------------------*/ |
---|
87 | void HSI16_TIMx_ConfigForCalibration(void); |
---|
88 | void HSI16_RCC_AdjustCalibrationValue(uint8_t InternOsc, uint8_t TrimmingValue); |
---|
89 | uint32_t HSI16_FreqMeasure(void); |
---|
90 | void HSI16_MeasurementInit(void); |
---|
91 | |
---|
92 | void CLK_ConfigForCalibration(void); |
---|
93 | void GPIO_ConfigForCalibration(void); |
---|
94 | /* Private functions ---------------------------------------------------------*/ |
---|
95 | |
---|
96 | /** @addtogroup STM32L0xx_AN4631 |
---|
97 | * @{ |
---|
98 | */ |
---|
99 | |
---|
100 | /** |
---|
101 | * @brief Calibrates internal oscillators HSI to the minimum computed error. |
---|
102 | * The system clock source is checked: |
---|
103 | * - If HSI oscillator is used as system clock source, HSI is calibrated |
---|
104 | * and the new HSI value is returned. |
---|
105 | * - Otherwise function returns 0. |
---|
106 | * @param None. |
---|
107 | * @retval The optimum computed frequency of HSI oscillator. |
---|
108 | * Returning 0 means that the system clock source is not HSI. |
---|
109 | */ |
---|
110 | uint32_t HSI16_CalibrateMinError(void) |
---|
111 | { |
---|
112 | uint32_t measuredfrequency = 0; |
---|
113 | uint32_t sysclockfrequency = 0; |
---|
114 | uint32_t optimumfrequency = 0; |
---|
115 | uint32_t frequencyerror = 0; |
---|
116 | uint32_t optimumfrequencyerror = INITIAL_ERROR; /* Large value */ |
---|
117 | uint32_t numbersteps = 0; /* Number of steps: size of trimming bits */ |
---|
118 | uint32_t trimmingvalue = 0; |
---|
119 | uint32_t optimumcalibrationvalue = 0; |
---|
120 | |
---|
121 | /* Set measurement environment */ |
---|
122 | HSI16_MeasurementInit(); |
---|
123 | |
---|
124 | /* Get system clock frequency */ |
---|
125 | sysclockfrequency = HAL_RCC_GetSysClockFreq(); |
---|
126 | |
---|
127 | /* HSI16TRIM is 7-bit length */ |
---|
128 | numbersteps = 128; /* number of steps is 2^7 = 128 */ |
---|
129 | |
---|
130 | /* Internal Osc frequency measurement for numbersteps */ |
---|
131 | for (trimmingvalue = 0; trimmingvalue < numbersteps; trimmingvalue++) |
---|
132 | { |
---|
133 | |
---|
134 | /* Set the Intern Osc trimming bits to trimmingvalue */ |
---|
135 | HSI16_RCC_AdjustCalibrationValue(__HAL_RCC_GET_SYSCLK_SOURCE(), trimmingvalue); |
---|
136 | |
---|
137 | /* Get actual frequency value */ |
---|
138 | measuredfrequency = HSI16_FreqMeasure(); |
---|
139 | |
---|
140 | /* Compute current frequency error corresponding to the current trimming value: |
---|
141 | measured value is subtracted from the typical one */ |
---|
142 | frequencyerror = ABS_RETURN((int32_t) (measuredfrequency - sysclockfrequency)); |
---|
143 | |
---|
144 | /* Get the nearest frequency value to typical one */ |
---|
145 | if (optimumfrequencyerror > frequencyerror) |
---|
146 | { |
---|
147 | optimumfrequencyerror = frequencyerror; |
---|
148 | optimumcalibrationvalue = trimmingvalue; |
---|
149 | optimumfrequency = measuredfrequency; |
---|
150 | } |
---|
151 | |
---|
152 | } |
---|
153 | |
---|
154 | /* Set trimming bits corresponding to the nearest frequency */ |
---|
155 | HSI16_RCC_AdjustCalibrationValue(__HAL_RCC_GET_SYSCLK_SOURCE(), optimumcalibrationvalue); |
---|
156 | /* Return the intern oscillator frequency after calibration */ |
---|
157 | printf("calilbration value : %d", optimumcalibrationvalue); |
---|
158 | measuredfrequency = HSI16_FreqMeasure(); |
---|
159 | printf(": frequency : %d\n", measuredfrequency); |
---|
160 | return (optimumfrequency); |
---|
161 | |
---|
162 | } |
---|
163 | |
---|
164 | /** |
---|
165 | * @brief Calibrates the internal oscillator (HSI only) with the maximum allowed |
---|
166 | * error value set by user. |
---|
167 | * If this value was not found, this function sets the oscillator |
---|
168 | * to default value. |
---|
169 | * @param MaxAllowedError: maximum absolute value allowed of the HSI frequency |
---|
170 | * error given in Hz. |
---|
171 | * @param Freq: returns value of calibrated frequency |
---|
172 | * @retval ErrorStatus: |
---|
173 | * - SUCCESS: a frequency error =< MaxAllowedError was found. |
---|
174 | * - ERROR: a frequency error =< MaxAllowedError was not found. |
---|
175 | */ |
---|
176 | ErrorStatus HSI16_CalibrateFixedError(uint32_t MaxAllowedError, uint32_t* Freq) |
---|
177 | { |
---|
178 | uint32_t measuredfrequency; |
---|
179 | uint32_t frequencyerror = 0; |
---|
180 | uint32_t sysclockfrequency = 0; |
---|
181 | uint32_t trimmingindex = 0; |
---|
182 | uint32_t trimmingvalue = 0; |
---|
183 | uint32_t numbersteps; |
---|
184 | int32_t sign = 1; |
---|
185 | ErrorStatus calibrationstatus = ERROR; |
---|
186 | |
---|
187 | /* HSI16TRIM is 7-bit length */ |
---|
188 | numbersteps = 128; /* number of steps is 2^7 = 128 */ |
---|
189 | |
---|
190 | /* Set measurement environment */ |
---|
191 | HSI16_MeasurementInit(); |
---|
192 | |
---|
193 | /* Get system clock frequency */ |
---|
194 | sysclockfrequency = HAL_RCC_GetSysClockFreq(); |
---|
195 | |
---|
196 | /* Start frequency measurement for current trimming value */ |
---|
197 | measuredfrequency = 0; |
---|
198 | |
---|
199 | /* RC Frequency measurement for different values */ |
---|
200 | for (trimmingindex = 0; trimmingindex < numbersteps; trimmingindex++) |
---|
201 | { |
---|
202 | /* Compute trimming value */ |
---|
203 | trimmingvalue = trimmingvalue + (trimmingindex * sign); |
---|
204 | sign *= (-1); |
---|
205 | |
---|
206 | /* Set the HSI16TRIM register to trimmingvalue to be ready for measurement */ |
---|
207 | __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(trimmingvalue); |
---|
208 | |
---|
209 | /* Get actual frequency value */ |
---|
210 | measuredfrequency = HSI16_FreqMeasure(); |
---|
211 | |
---|
212 | /* Compute current frequency error corresponding to the current trimming value: |
---|
213 | measured value is subtracted from the typical one */ |
---|
214 | frequencyerror = ABS_RETURN((int32_t) (measuredfrequency - sysclockfrequency)); |
---|
215 | |
---|
216 | /* Check if frequency error is less or equal to value set by the user */ |
---|
217 | if (frequencyerror <= MaxAllowedError) |
---|
218 | { |
---|
219 | calibrationstatus = SUCCESS; /* The calibration has succeed */ |
---|
220 | break; /* stop searching and measurements for frequencies */ |
---|
221 | } |
---|
222 | } |
---|
223 | |
---|
224 | /* Save the new HSI value */ |
---|
225 | *Freq = measuredfrequency; |
---|
226 | |
---|
227 | /* If the frequency error set by the user was not found */ |
---|
228 | if (calibrationstatus == ERROR) |
---|
229 | { |
---|
230 | /* Set the HSI16TRIM register to default value */ |
---|
231 | __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(numbersteps / 2); |
---|
232 | } |
---|
233 | |
---|
234 | /* Return the calibration status: ERROR or SUCCESS */ |
---|
235 | return (calibrationstatus); |
---|
236 | } |
---|
237 | |
---|
238 | #ifdef HSI16_MEASURE_FREQUENCY_TABLE |
---|
239 | /** |
---|
240 | * @brief For all possible trimming values change of frequency is measured |
---|
241 | * @retval None. |
---|
242 | */ |
---|
243 | void HSI16_GetCurve(void) |
---|
244 | { |
---|
245 | uint32_t output; |
---|
246 | uint32_t measuredfrequency; |
---|
247 | uint32_t trimmingindex = 0; |
---|
248 | uint32_t trimmingindexorig; |
---|
249 | //uint32_t orig_frequency; |
---|
250 | uint32_t numbersteps; |
---|
251 | uint32_t x; |
---|
252 | |
---|
253 | /* Set measurement environment */ |
---|
254 | HSI16_MeasurementInit(); |
---|
255 | |
---|
256 | /* HSI16TRIM is 7-bit length */ |
---|
257 | numbersteps = 128; /* number of steps is 2^7 = 128 */ |
---|
258 | |
---|
259 | /* Keep original values */ |
---|
260 | trimmingindexorig = GET_HSI16_TRIMMING_VALUE(); |
---|
261 | //orig_frequency = HSI16_FreqMeasure(); |
---|
262 | |
---|
263 | /* RC Frequency measurement for different values */ |
---|
264 | for (trimmingindex = 0; trimmingindex < numbersteps; trimmingindex++) |
---|
265 | { |
---|
266 | /* Set the HSI16TRIM register to trimmingvalue to be ready for measurement */ |
---|
267 | __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(trimmingindex); |
---|
268 | /* Start measuring Internal Oscillator frequency */ |
---|
269 | output = 2; |
---|
270 | while(output == 2) |
---|
271 | { |
---|
272 | output = HSI16_FreqMeasure(); |
---|
273 | } |
---|
274 | measuredfrequency = 0; |
---|
275 | measuredfrequency += output; |
---|
276 | |
---|
277 | /* Compute current frequency error corresponding to the current trimming value: |
---|
278 | measured value is subtracted from the typical one */ |
---|
279 | aFrequenceChangeTable[trimmingindex] = (int32_t)measuredfrequency; |
---|
280 | //aFrequenceChangeTable[trimmingindex] = ((int32_t)(measuredfrequency - orig_frequency)); |
---|
281 | #ifdef PRINT_FREQUENCY_MEASURE_RESULT |
---|
282 | printf(" %3d, %d\n", trimmingindex, aFrequenceChangeTable[trimmingindex]); |
---|
283 | #endif |
---|
284 | } |
---|
285 | |
---|
286 | /* Set back the original frequency value */ |
---|
287 | __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(trimmingindexorig); |
---|
288 | } |
---|
289 | #endif |
---|
290 | |
---|
291 | #ifdef HSI16_MEASURE_FREQUENCY_TABLE |
---|
292 | /** |
---|
293 | * @brief Adjust calibration value (writing to trimming bits) of selected oscillator. |
---|
294 | * @param Freq: pointer to an uint32_t variable that will contain the value |
---|
295 | * of the internal oscillator frequency after calibration. |
---|
296 | * @retval ErrorStatus: |
---|
297 | * - SUCCESS: successful calibration |
---|
298 | * - ERROR: if frequency could not be calibrated |
---|
299 | */ |
---|
300 | ErrorStatus HSI16_CalibrateCurve(uint32_t* Freq) |
---|
301 | { |
---|
302 | |
---|
303 | uint32_t measuredfrequency; |
---|
304 | uint32_t optimumcalibrationvalue; |
---|
305 | uint32_t i; |
---|
306 | uint32_t frequencyerror; |
---|
307 | uint32_t numbersteps = 128; |
---|
308 | uint32_t optimumfrequencyerror = INITIAL_ERROR; /* Large value */ |
---|
309 | ErrorStatus returnvalue = ERROR; |
---|
310 | |
---|
311 | /* HSI16TRIM is 7-bit length */ |
---|
312 | numbersteps = 128; /* number of steps is 2^7 = 128 */ |
---|
313 | |
---|
314 | /* Get position */ |
---|
315 | measuredfrequency = HSI16_FreqMeasure(); |
---|
316 | |
---|
317 | /* Find the closest difference */ |
---|
318 | for (i = 0; i < numbersteps; i++) |
---|
319 | { |
---|
320 | frequencyerror = ABS_RETURN((int32_t) (HSI_VALUE - (int32_t)(measuredfrequency + aFrequenceChangeTable[i]))); |
---|
321 | |
---|
322 | /* Get the nearest frequency value to typical one */ |
---|
323 | if (frequencyerror < optimumfrequencyerror) |
---|
324 | { |
---|
325 | optimumfrequencyerror = frequencyerror; |
---|
326 | optimumcalibrationvalue = i; |
---|
327 | } |
---|
328 | } |
---|
329 | |
---|
330 | if (optimumfrequencyerror != INITIAL_ERROR) |
---|
331 | { |
---|
332 | __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(optimumcalibrationvalue); |
---|
333 | /* Save the HSI measured value */ |
---|
334 | *Freq = measuredfrequency + aFrequenceChangeTable[optimumcalibrationvalue]; |
---|
335 | returnvalue = SUCCESS; |
---|
336 | } |
---|
337 | |
---|
338 | return returnvalue; |
---|
339 | } |
---|
340 | #endif |
---|
341 | |
---|
342 | /** |
---|
343 | * @brief Measures actual value of HSI |
---|
344 | * @param None. |
---|
345 | * @retval Actual HSI frequency |
---|
346 | */ |
---|
347 | static uint32_t frequencyMW; |
---|
348 | static int32_t loopCounter; |
---|
349 | |
---|
350 | uint32_t HSI16_FreqMeasure(void) |
---|
351 | { |
---|
352 | uint32_t measuredfrequency; |
---|
353 | //uint32_t timeout = HSI16_TIMEOUT; |
---|
354 | |
---|
355 | /* Start frequency measurement for current trimming value */ |
---|
356 | |
---|
357 | /* Start measuring Internal Oscillator frequency */ |
---|
358 | |
---|
359 | // EDIT ECS: |
---|
360 | // state machine einbauen um Blocken des Programmablaufes durch die while() Schleife zu verhindern |
---|
361 | // state machine ist schon da (globale var "CaptureState") |
---|
362 | |
---|
363 | if(CaptureState == CAPTURE_READY_FOR_NEW) |
---|
364 | { |
---|
365 | CaptureState = CAPTURE_START; |
---|
366 | |
---|
367 | /* Enable capture 1 interrupt */ |
---|
368 | HAL_TIM_IC_Start_IT(&TimHandle, TIM_CHANNEL_y); |
---|
369 | |
---|
370 | /* Enable the TIMx IRQ channel */ |
---|
371 | HAL_NVIC_EnableIRQ(TIMx_IRQn); |
---|
372 | // Return Capture Start |
---|
373 | return CAPTURE_ONGOING; |
---|
374 | } |
---|
375 | |
---|
376 | else if(CaptureState != CAPTURE_COMPLETED) |
---|
377 | { |
---|
378 | // Return Capture Ongoing |
---|
379 | return CAPTURE_ONGOING; |
---|
380 | } |
---|
381 | /* Wait for end of capture: two consecutive captures */ |
---|
382 | |
---|
383 | else if(CaptureState == CAPTURE_COMPLETED) |
---|
384 | { |
---|
385 | |
---|
386 | /* Disable IRQ channel */ |
---|
387 | HAL_NVIC_DisableIRQ(TIMx_IRQn); |
---|
388 | |
---|
389 | /* Disable TIMx */ |
---|
390 | HAL_TIM_IC_Stop_IT(&TimHandle, TIM_CHANNEL_y); |
---|
391 | |
---|
392 | CaptureState = CAPTURE_READY_FOR_NEW; |
---|
393 | |
---|
394 | if (loopCounter != 0) |
---|
395 | { |
---|
396 | /* Compute the frequency (the Timer prescaler isn't included) */ |
---|
397 | frequencyMW += (uint32_t) (REFERENCE_FREQUENCY * Capture); |
---|
398 | } |
---|
399 | |
---|
400 | if(loopCounter < HSI16_NUMBER_OF_LOOPS) |
---|
401 | { |
---|
402 | /* Increment loop counter */ |
---|
403 | loopCounter++; |
---|
404 | return CAPTURE_ONGOING; |
---|
405 | } |
---|
406 | /* END of Measurement */ |
---|
407 | else |
---|
408 | { |
---|
409 | measuredfrequency = 0; |
---|
410 | loopCounter = 0; |
---|
411 | /* Compute the average value corresponding the current trimming value */ |
---|
412 | measuredfrequency = (uint32_t)((__HAL_GET_TIM_PRESCALER(&TimHandle) + 1) * (frequencyMW / HSI16_NUMBER_OF_LOOPS)); |
---|
413 | frequencyMW = 0; |
---|
414 | return measuredfrequency; |
---|
415 | } |
---|
416 | } |
---|
417 | return 0; |
---|
418 | } |
---|
419 | |
---|
420 | /** |
---|
421 | * @brief Configures all the necessary peripherals necessary from frequency calibration. |
---|
422 | * @param None. |
---|
423 | * @retval None. |
---|
424 | */ |
---|
425 | void HSI16_MeasurementInit(void) |
---|
426 | { |
---|
427 | |
---|
428 | /* Configure the GPIO ports before starting calibration process */ |
---|
429 | //GPIO_ConfigForCalibration(); |
---|
430 | |
---|
431 | /* Configure clock before starting calibration process */ |
---|
432 | //CLK_ConfigForCalibration(); |
---|
433 | |
---|
434 | /* Configure TIMx before starting calibration process */ |
---|
435 | HSI16_TIMx_ConfigForCalibration(); |
---|
436 | CaptureState = CAPTURE_READY_FOR_NEW; |
---|
437 | } |
---|
438 | |
---|
439 | /** |
---|
440 | * @brief Configures the TIMx in input capture to measure HSI frequency. |
---|
441 | * @param None. |
---|
442 | * @retval None. |
---|
443 | */ |
---|
444 | void HSI16_TIMx_ConfigForCalibration(void) |
---|
445 | { |
---|
446 | TIM_IC_InitTypeDef ic_config; /* Timer Input Capture Configuration Structure declaration */ |
---|
447 | |
---|
448 | /* Enable TIMx clock */ |
---|
449 | __TIMx_CLK_ENABLE(); |
---|
450 | |
---|
451 | /* Set TIMx instance */ |
---|
452 | TimHandle.Instance = TIMx; |
---|
453 | |
---|
454 | /* Reset TIMx registers */ |
---|
455 | HAL_TIM_IC_DeInit(&TimHandle); |
---|
456 | |
---|
457 | /* Initialize TIMx peripheral as follows: |
---|
458 | + Period = 0xFFFF |
---|
459 | + Prescaler = 0 |
---|
460 | + ClockDivision = 0 |
---|
461 | + Counter direction = Up |
---|
462 | */ |
---|
463 | TimHandle.Init.Period = 0xFFFF; |
---|
464 | TimHandle.Init.Prescaler = HSI16_TIMx_COUNTER_PRESCALER; |
---|
465 | TimHandle.Init.ClockDivision = 0; |
---|
466 | TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; |
---|
467 | if (HAL_TIM_IC_Init(&TimHandle) != HAL_OK) |
---|
468 | { |
---|
469 | /* Initialization Error */ |
---|
470 | while(1); |
---|
471 | } |
---|
472 | |
---|
473 | /* Configure the Input Capture of channel y */ |
---|
474 | ic_config.ICPolarity = TIM_ICPOLARITY_RISING; |
---|
475 | ic_config.ICSelection = TIM_ICSELECTION_DIRECTTI; |
---|
476 | ic_config.ICPrescaler = HSI16_TIMx_IC_DIVIDER; |
---|
477 | ic_config.ICFilter = 0; |
---|
478 | if (HAL_TIM_IC_ConfigChannel(&TimHandle, &ic_config, TIM_CHANNEL_y) != HAL_OK) |
---|
479 | { |
---|
480 | /* Configuration Error */ |
---|
481 | while(1); |
---|
482 | } |
---|
483 | |
---|
484 | // EDIT ECS START |
---|
485 | // Timer Input Source Selection |
---|
486 | // LSE als Timer Input |
---|
487 | if (HAL_TIMEx_TISelection(&TimHandle, TIM_TIM16_TI1_LSE, TIM_CHANNEL_1) != HAL_OK) |
---|
488 | { |
---|
489 | while(1); |
---|
490 | } |
---|
491 | // EDIT ECS END |
---|
492 | |
---|
493 | /* Configure the NVIC for TIMx */ |
---|
494 | HAL_NVIC_SetPriority(TIMx_IRQn, 0, 0); |
---|
495 | |
---|
496 | /* Disable the TIMx global Interrupt */ |
---|
497 | HAL_NVIC_DisableIRQ(TIMx_IRQn); |
---|
498 | |
---|
499 | } |
---|
500 | |
---|
501 | |
---|
502 | /** |
---|
503 | * @brief Adjust calibration value (writing to trimming bits) of selected oscillator. |
---|
504 | * @param InternOsc: Internal Oscillator source: HSI |
---|
505 | * @param TrimmingValue: calibration value to be written in trimming bits. |
---|
506 | * @retval None. |
---|
507 | */ |
---|
508 | void HSI16_RCC_AdjustCalibrationValue(uint8_t InternOsc, uint8_t TrimmingValue) |
---|
509 | { |
---|
510 | __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(TrimmingValue); |
---|
511 | } |
---|
512 | |
---|
513 | /** |
---|
514 | * @brief Configures LSE to be used as RTC clock source |
---|
515 | * @param None. |
---|
516 | * @retval None. |
---|
517 | */ |
---|
518 | void CLK_ConfigForCalibration(void) |
---|
519 | { |
---|
520 | |
---|
521 | /* Enable the LSE OSC */ |
---|
522 | __HAL_RCC_LSE_CONFIG(RCC_LSE_ON); |
---|
523 | |
---|
524 | /* Wait till LSE is ready */ |
---|
525 | while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) |
---|
526 | {} |
---|
527 | } |
---|
528 | |
---|
529 | |
---|
530 | /** |
---|
531 | * @brief Conversion complete callback in non blocking mode |
---|
532 | * @param htim : hadc handle |
---|
533 | * @retval None |
---|
534 | */ |
---|
535 | void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) |
---|
536 | { |
---|
537 | |
---|
538 | if ((htim->Channel) == HAL_TIM_ACTIVE_CHANNEL_y) |
---|
539 | { |
---|
540 | if (CaptureState == CAPTURE_START) |
---|
541 | { |
---|
542 | /* Get the 1st Input Capture value */ |
---|
543 | IC1ReadValue1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_y); |
---|
544 | //htim->Instance->CNT = 0; |
---|
545 | CaptureState = CAPTURE_ONGOING; |
---|
546 | } |
---|
547 | else if (CaptureState == CAPTURE_ONGOING) |
---|
548 | { |
---|
549 | /* Get the 2nd Input Capture value */ |
---|
550 | IC1ReadValue2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_y); |
---|
551 | |
---|
552 | // Timer interrupt ausschalten sonst treten Fehler auf |
---|
553 | HAL_NVIC_DisableIRQ(TIMx_IRQn); |
---|
554 | HAL_TIM_IC_Stop_IT(&TimHandle, TIM_CHANNEL_y); |
---|
555 | __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1); |
---|
556 | |
---|
557 | /* Capture computation */ |
---|
558 | if (IC1ReadValue2 > IC1ReadValue1) |
---|
559 | { |
---|
560 | Capture = (IC1ReadValue2 - IC1ReadValue1); |
---|
561 | if(REFERENCE_FREQUENCY * Capture < 13000000) |
---|
562 | { |
---|
563 | printf("Value not valid\n"); |
---|
564 | printf("Frequency Measured = %d\n", REFERENCE_FREQUENCY * Capture); |
---|
565 | //while(1); |
---|
566 | } |
---|
567 | } |
---|
568 | else if (IC1ReadValue2 < IC1ReadValue1) |
---|
569 | { |
---|
570 | Capture = ((0xFFFF - IC1ReadValue1) + IC1ReadValue2); |
---|
571 | if(REFERENCE_FREQUENCY * Capture < 13000000) |
---|
572 | { |
---|
573 | printf("Value not valid\n"); |
---|
574 | printf("Frequency Measured = %d\n", REFERENCE_FREQUENCY * Capture); |
---|
575 | } |
---|
576 | } |
---|
577 | else |
---|
578 | { |
---|
579 | /* If capture values are equal, we have reached the limit of frequency |
---|
580 | measures */ |
---|
581 | while(1); |
---|
582 | } |
---|
583 | |
---|
584 | CaptureState = CAPTURE_COMPLETED; |
---|
585 | } |
---|
586 | } |
---|
587 | } |
---|
588 | |
---|
589 | /** |
---|
590 | * @} |
---|
591 | */ |
---|
592 | |
---|
593 | void frequencyErrorTest(void) |
---|
594 | { |
---|
595 | uint32_t HSIFrequencyBeforeCalib, highVal, lowVal; |
---|
596 | highVal = 0; |
---|
597 | lowVal = 20000000; |
---|
598 | HSI16_MeasurementInit(); |
---|
599 | while(1) |
---|
600 | { |
---|
601 | HSIFrequencyBeforeCalib = 2; |
---|
602 | while(HSIFrequencyBeforeCalib == 2) |
---|
603 | { |
---|
604 | HSIFrequencyBeforeCalib = HSI16_FreqMeasure(); |
---|
605 | } |
---|
606 | |
---|
607 | if(HSIFrequencyBeforeCalib > highVal) |
---|
608 | { |
---|
609 | highVal = HSIFrequencyBeforeCalib; |
---|
610 | printf("highest frequency %d\n",highVal); |
---|
611 | printf("lowest frequency %d\n",lowVal); |
---|
612 | } |
---|
613 | if(HSIFrequencyBeforeCalib < lowVal) |
---|
614 | { |
---|
615 | lowVal = HSIFrequencyBeforeCalib; |
---|
616 | printf("highest frequency %d\n",highVal); |
---|
617 | printf("lowest frequency %d\n",lowVal); |
---|
618 | } |
---|
619 | } |
---|
620 | } |
---|
621 | /******************* (C) COPYRIGHT 2014 STMicroelectronics *****END OF FILE****/ |
---|