]> begriffs open source - cmsis-freertos/blob - Demo/CORTEX_STM32F103_Primer_GCC/ST_Code/Util.c
Initial commit
[cmsis-freertos] / Demo / CORTEX_STM32F103_Primer_GCC / ST_Code / Util.c
1 /********************* (C) COPYRIGHT 2007 RAISONANCE S.A.S. *******************/
2 /**
3 *
4 * @file     Util.c
5 * @brief    Various utilities  for STM32 CircleOS.
6 * @author   RT
7 * @date     07/2007
8 *
9 **/
10 /******************************************************************************/
11
12 /* Includes ------------------------------------------------------------------*/
13
14 #include "circle.h"
15 #include "adc.h"
16
17 /// @cond Internal
18
19 /* Private defines -----------------------------------------------------------*/
20 #define  GPIO_USB_PIN   GPIO_Pin_1
21 #define  GPIOx_USB      GPIOA
22 #define  OsVersion      "V 1.7"    /*!< CircleOS version string. */
23
24 /* Private typedef -----------------------------------------------------------*/
25 enum eSpeed CurrentSpeed;
26
27 /* Private variables ---------------------------------------------------------*/
28 RCC_ClocksTypeDef    RCC_ClockFreq;
29 int                  dummycounter   = 0;
30 u8                   fTemperatureInFahrenheit = 0;  /*!< 1 : Fahrenheit, 0 : Celcius (default). */
31
32 /* Private function prototypes -----------------------------------------------*/
33 static void _int2str( char* ptr, s32 X, u16 digit, int flagunsigned, int fillwithzero );
34
35 /* Private functions ---------------------------------------------------------*/
36
37 /*******************************************************************************
38 *
39 *                    _int2str
40 *
41 *******************************************************************************/
42 /**
43 *
44 *  Translate a 32 bit word into a string.
45 *
46 *  @param[in,out] ptr            A pointer to a string large enough to contain
47 *                                the translated 32 bit word.
48 *  @param[in]     X              The 32 bit word to translate.
49 *  @param[in]     digit          The amount of digits wanted in the result string.
50 *  @param[in]     flagunsigned   Is the input word unsigned?
51 *  @param[in]     fillwithzero   Fill with zeros or spaces.
52 *
53 **/
54 /******************************************************************************/
55 static void _int2str( char* ptr, s32 X, u16 digit, int flagunsigned, int fillwithzero )
56    {
57    u8    c;
58    u8    fFirst   = 0;
59    u8    fNeg     = 0;
60    u32   DIG      = 1;
61    int   i;
62
63    for( i = 1; i < digit; i++ )
64       {
65       DIG *= 10;
66       }
67
68    if( !flagunsigned && ( X < 0 ) )
69       {
70       fNeg = 1;
71       X    = -X;
72       }
73
74    u32 r = X;
75
76    for( i = 0; i < digit; i++, DIG /= 10 )
77       {
78       c  = (r/DIG);
79       r -= (c*DIG);
80
81       if( fillwithzero || fFirst || c || ( i == ( digit - 1 ) ) )
82          {
83          if( ( fFirst == 0 ) && !flagunsigned )
84             {
85             *ptr++ = fNeg ? '-' : ' ';
86             }
87
88          *ptr++ = c + 0x30;
89          fFirst = 1;
90          }
91        else
92          {
93          *ptr++ = ' ';
94          }
95       }
96
97    *ptr++ = 0;
98    }
99
100 /* Public functions for CircleOS ---------------------------------------------*/
101
102 /*******************************************************************************
103 *
104 *                    delay_unit
105 *
106 *******************************************************************************/
107 /**
108 *
109 *  Called by starting_delay().
110 *
111 *  @note Not in main.c to avoid inlining.
112 *
113 **/
114 /******************************************************************************/
115 void delay_unit( void )
116    {
117    dummycounter++;
118    }
119
120 /// @endcond
121
122 /* Public functions ----------------------------------------------------------*/
123
124 /*******************************************************************************
125 *
126 *                    UTIL_GetBat
127 *
128 *******************************************************************************/
129 /**
130 *
131 *  Return the batterie tension in mV.
132 *
133 *  @return Batterie tension in mV.
134 *
135 **/
136 /******************************************************************************/
137 u16 UTIL_GetBat( void )
138    {
139 #ifdef _ADC
140    u16 vbat;
141
142    // Measure VBAT
143    vbat = ADC_ConvertedValue[0];  //*( (u16*)ADC1_DR_Address );      // <=== note changed 
144    vbat = vbat & 0xFFF;
145    vbat = ( vbat * VDD_VOLTAGE_MV ) / 0x1000;
146
147    return vbat;
148 #else
149    return 0;
150 #endif
151    }
152
153 /*******************************************************************************
154 *
155 *                    UTIL_GetTemp
156 *
157 *******************************************************************************/
158 /**
159 *
160 *  Return the Temperature: degrees / 10, Celcius or Fahrenheit.
161 *
162 *  @return The temperature (C or F) (averaging of several channels).
163 *
164 **/
165 /******************************************************************************/
166 u16 UTIL_GetTemp( void )
167    {
168    s32 temp;
169    s16 *p=&ADC_ConvertedValue[1];  //intent; point to first of 8 results from same source - use a short name for it!
170    
171    // Measure temp
172    //temp = ADC_ConvertedValue[1];//*( (u16*)ADC1_DR_Address ); 
173    temp = (p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7])/8; //take avg of burst of 8 temp reads. may only help reject hi freq noise a bit
174                                                        //will not help reduce mains ripple because conversions are SO FAST!!
175    temp = temp & 0xFFF;
176    temp = ( temp * VDD_VOLTAGE_MV ) / 0x1000;  //finds mV  
177    temp = (((1400-temp)*100000)/448)+25000;  //gives approx temp x 1000 degrees C
178    
179    //Fahrenheit = 32 + 9 / 5 * Celsius
180    if ( fTemperatureInFahrenheit ) 
181       {
182       temp = 32000 + (9 * temp) / 5 ;
183       }
184    
185    return temp / 100;
186    }
187
188 /*******************************************************************************
189 *
190 *                    UTIL_SetTempMode
191 *
192 *******************************************************************************/
193 /**
194 *
195 *  Set the temperature mode (F/C)
196 *
197 *  @param[in]     mode       0: Celcius, 1: Fahrenheit 
198 *
199 **/
200 /******************************************************************************/
201 void UTIL_SetTempMode ( int mode )
202    {
203    fTemperatureInFahrenheit = mode; 
204   
205    return;
206    }
207
208
209 /*******************************************************************************
210 *
211 *                    UTIL_GetUsb
212 *
213 *******************************************************************************/
214 /**
215 *
216 *  Return the USB connexion state.
217 *
218 *  @return The USB connexion state.
219 *
220 **/
221 /******************************************************************************/
222 u8 UTIL_GetUsb( void )
223    {
224    GPIO_InitStructure.GPIO_Pin   =  GPIO_USB_PIN;
225    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
226    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
227
228    GPIO_Init( GPIOx_USB, &GPIO_InitStructure );
229
230    return ( GPIO_ReadInputDataBit( GPIOx_USB, GPIO_USB_PIN ) == Bit_SET );
231    }
232
233 /*******************************************************************************
234 *
235 *                   UTIL_uint2str
236 *
237 *******************************************************************************/
238 /**
239 *
240 *  Convert an <b>unsigned</b> integer into a string.
241 *
242 *  @param [out]  ptr    The output string.
243 *  @param [in]   X      The unsigned value to convert.
244 *  @param [in]   digit  The number of digits in the output string.
245 *  @param [in]   fillwithzero  \li 0   fill with blanks.
246 *                              \li 1   fill with zeros.
247 *
248 **/
249 /********************************************************************************/
250 void UTIL_uint2str( char* ptr, u32 X, u16 digit, int fillwithzero )
251    {
252    _int2str( ptr, X, digit, 1, fillwithzero);
253    }
254
255 /*******************************************************************************
256 *
257 *                   UTIL_int2str
258 *
259 *******************************************************************************/
260 /**
261 *
262 *  Convert a <b>signed</b> integer into a string.
263 *
264 *  @param [out]  ptr    The output string.
265 *  @param [in]   X      The unsigned value to convert.
266 *  @param [in]   digit  The number of digits in the output string.
267 *  @param [in]   fillwithzero  \li 0   fill with blanks.
268 *                              \li 1   fill with zeros.
269 *
270 **/
271 /******************************************************************************/
272 void UTIL_int2str( char* ptr, s32 X, u16 digit, int fillwithzero )
273    {
274    _int2str( ptr, X, digit, 0, fillwithzero);
275    }
276
277 /*******************************************************************************
278 *
279 *                                UTIL_SetPll
280 *
281 *******************************************************************************/
282 /**
283 *
284 *  Set clock frequency (lower to save energy)
285 *
286 *  @param [in]   speed  New clock speed from very low to very fast.
287 *
288 **/
289 /******************************************************************************/
290 void UTIL_SetPll( enum eSpeed speed )
291    {
292    /* Select PLL as system clock source */
293    RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI );
294
295    /* Enable PLL */
296    RCC_PLLCmd( DISABLE );
297
298    if( ( speed < SPEED_VERY_LOW ) || ( speed > SPEED_VERY_HIGH ) )
299       {
300       speed = SPEED_MEDIUM;
301       } 
302
303    CurrentSpeed = speed; 
304
305    switch( speed )
306       {
307       // 18 MHz
308       case SPEED_VERY_LOW  :
309          /* PLLCLK = 6MHz * 3 = 18 MHz */
310          RCC_PLLConfig( RCC_PLLSource_HSE_Div2, RCC_PLLMul_3 );
311          break;
312
313       // 24MHz
314       case SPEED_LOW       :
315          /* PLLCLK = 12MHz * 2 = 24 MHz */
316          RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_2 );
317          break;
318
319       // 36MHz
320       case SPEED_MEDIUM    :   
321       default              :
322          /* PLLCLK = 12MHz * 3 = 36 MHz */
323          RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_3 );
324          break;
325
326       // 48MHz
327       case SPEED_HIGH      :
328          /* PLLCLK = 12MHz * 4 = 48 MHz */
329          RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_4 );
330          break;
331
332       // 72MHz
333       case SPEED_VERY_HIGH :
334          /* PLLCLK = 12MHz * 6 = 72 MHz */
335          RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_6 );
336          break;
337       }
338
339    /* Enable PLL */
340    RCC_PLLCmd( ENABLE );
341
342    /* Wait till PLL is ready */
343    while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET )
344       { ; }
345
346    /* Select PLL as system clock source */
347    RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
348
349    /* Wait till PLL is used as system clock source */
350    while( RCC_GetSYSCLKSource() != 0x08 )
351       { ; }
352
353    /* This function fills a RCC_ClocksTypeDef structure with the current frequencies
354      of different on chip clocks (for debug purpose) */
355    RCC_GetClocksFreq( &RCC_ClockFreq );
356    }
357
358 /*******************************************************************************
359 *
360 *                                UTIL_GetPll
361 *
362 *******************************************************************************/
363 /**
364 *
365 *  Get clock frequency
366 *
367 *  @return   Current clock speed from very low to very fast.
368 *
369 **/
370 /******************************************************************************/
371 enum eSpeed UTIL_GetPll( void )
372    {
373    return CurrentSpeed;
374    }
375
376 /*******************************************************************************
377 *
378 *                                UTIL_GetVersion
379 *
380 *******************************************************************************/
381 /**
382 *
383 *  Get CircleOS version.
384 *
385 *  @return  A pointer to a string containing the CircleOS version.
386 *
387 **/
388 /******************************************************************************/
389 const char* UTIL_GetVersion( void )
390    {
391    return OsVersion;
392    }
393
394 /*******************************************************************************
395 *
396 *                                UTIL_ReadBackupRegister
397 *
398 *******************************************************************************/
399 /**
400 *
401 *  Reads data from the specified Data Backup Register.
402 *
403 *  @param[in]  BKP_DR   Specifies the Data Backup Register. This parameter can be BKP_DRx where x:[1, 10]
404 *
405 *  @return  The content of the specified Data Backup Register.
406 *
407 **/
408 /******************************************************************************/
409 u16 UTIL_ReadBackupRegister( u16 BKP_DR )
410    {
411   return (*(vu16 *)( BKP_BASE + 4 * BKP_DR ) );
412    }
413
414 /*******************************************************************************
415 *
416 *                                UTIL_WriteBackupRegister
417 *
418 *******************************************************************************/
419 /**
420 *
421 *  Writes data to the specified Data Backup Register.
422 *
423 *  @param[in]  BKP_DR   Specifies the Data Backup Register. This parameter can be BKP_DRx where x:[1, 10]
424 *  @param[in]  Data     The data to write.
425 *
426 **/
427 /********************************************************************************/
428 void UTIL_WriteBackupRegister( u16 BKP_DR, u16 Data )
429    {
430   *(vu16 *)( BKP_BASE + 4 * BKP_DR ) = Data;
431    }
432
433
434 /*******************************************************************************
435 *
436 *                                UTIL_SetIrqHandler
437 *
438 *******************************************************************************/
439 /**
440 *
441 *  Redirect an IRQ handler.
442 *
443 *  @param[in]  Offs   Address in the NVIC table
444 *  @param[in]  pHDL   Pointer to the handler.
445 *
446 **/
447 /********************************************************************************/
448 void UTIL_SetIrqHandler( int Offs, tHandler pHDL )
449    {
450    if ( (Offs >= 8) && (Offs<0x100) )
451       *(tHandler *)( CIRCLEOS_RAM_BASE + Offs ) = pHDL;
452    }
453
454 /*******************************************************************************
455 *
456 *                                UTIL_GetIrqHandler
457 *
458 *******************************************************************************/
459 /**
460 *
461 *  Get the current IRQ handler.
462 *  Since (V1.6) the vector table is relocated in RAM, the vectors can be easily modified
463 *  by the applications. 
464 *
465 *  @param[in]  Offs   Address in the NVIC table
466 *  @return  A pointer to the current handler.
467 *
468 **/
469 /********************************************************************************/
470 tHandler UTIL_GetIrqHandler( int Offs )
471    {
472    if ( (Offs >= 8) && (Offs<0x100) )
473       return *(tHandler *)( CIRCLEOS_RAM_BASE + Offs );
474    }
475
476
477
478 /*******************************************************************************
479 *
480 *                                UTIL_SetSchHandler
481 *
482 *******************************************************************************/
483 /**
484 *
485 *  Redirect a SCHEDULER handler.
486 *  Set the current SCHEDULER handler. With UTIL_GetSchHandler(), these functions 
487 *  allow to take the control of the different handler. You can: 
488 *        - replace them (get-Set)by your own handler
489 *        - disable a handler: UTIL_SetSchHandler(Ix,0);  
490 *        - create a new handler (using the unused handlers).
491 *  See scheduler.c to understand further...
492 *
493 *  @param[in]  Ix   ID if the SCH Handler
494 *  @param[in]  pHDL   Pointer to the handler.
495 *
496 **/
497 /********************************************************************************/
498 void UTIL_SetSchHandler( enum eSchHandler Ix, tHandler pHDL )
499    {
500    if (Ix<SCH_HDL_MAX)
501       SchHandler[Ix] = pHDL;
502    }
503
504 /*******************************************************************************
505 *
506 *                                UTIL_GetSchHandler
507 *
508 *******************************************************************************/
509 /**
510 *
511 *  Get the current SCHEDULER handler. With UTIL_SetSchHandler(), these functions 
512 *  allow to take the control of the different handler. You can: 
513 *        - replace them (get-Set)by your own handler
514 *        - disable a handler: UTIL_SetSchHandler(Ix,0);  
515 *        - create a new handler (using the unused handlers).
516 *  See scheduler.c to understand further...
517 *
518 *  @param[in]  Ix   ID is the SCH Handler
519 *  @return  A pointer to the current handler.
520 *
521 **/
522 /********************************************************************************/
523 tHandler UTIL_GetSchHandler( enum eSchHandler Ix )
524    {
525    if ( Ix<SCH_HDL_MAX ) 
526       return SchHandler [Ix] ; 
527    }
528