Choco OS  V.0.16.9.0
Join to the chocolate world
oc_clock_lld.c
1 
27 #include <oc_clock_lld.h>
28 #include <oc_mem_lld.h>
29 #include <oc_math.h>
30 #include <oc_module.h>
31 #include <oc_mcs.h>
32 #include <oc_lsf.h>
33 #include <oc_sys_lld.h>
34 #include <oc_interrupts.h>
35 
41 #define _________________________________________DEFINITIONS_SECTION________________________________________________________________________
42 
43 #define RCC_APB1ENR oC_Register(RCC,RCC_APB1ENR)
44 #define RCC_CR oC_Register(RCC,RCC_CR)
45 #define RCC_CFGR oC_Register(RCC,RCC_CFGR)
46 #define RCC_PLLCFGR oC_Register(RCC,RCC_PLLCFGR)
47 #define RCC_CSR oC_Register(RCC,RCC_CSR)
48 #define PWR_CR oC_Register(PWR,PWR_CR)
49 #define PWR_CSR oC_Register(PWR,PWR_CSR)
50 #define FLASH_ACR oC_Register(FLASH,FLASH_ACR)
51 #define MAX_FREQUENCY oC_MACHINE_MAXIMUM_FREQUENCY
52 #define HIBERNATION_FREQUENCY oC_MACHINE_HIBERNATION_OSCILLATOR_FREQUENCY
53 
54 #undef _________________________________________DEFINITIONS_SECTION________________________________________________________________________
55 
61 #define _________________________________________MACROS_SECTION_____________________________________________________________________________
62 
63 #define IsRam(Address) (oC_LSF_IsRamAddress(Address) || oC_LSF_IsExternalAddress(Address))
64 #define IsRom(Address) oC_LSF_IsRomAddress(Address)
65 
66 #undef _________________________________________MACROS_SECTION_____________________________________________________________________________
67 
68 
74 #define _________________________________________TYPES_SECTION______________________________________________________________________________
75 
76 typedef enum
77 {
78  MainClockSource_HSI = 0,
79  MainClockSource_HSE = 1 ,
80  MainClockSource_PLL = 2
81 } MainClockSource_t;
82 
83 typedef enum
84 {
85  PllSource_HSI = 0 ,
86  PllSource_HSE = 1
87 } PllSource_t;
88 
89 typedef struct
90 {
91  bool UsePll;
92  uint8_t PllM:6;
93  uint16_t PllN:9;
94  uint8_t PllP:2;
95  uint8_t Hpre:4;
96  oC_Frequency_t ResultFrequency;
97  oC_Frequency_t ResultDifference;
98  oC_Frequency_t TargetFrequency;
99  oC_Frequency_t PermissibleDifference;
100  oC_Frequency_t OscillatorFrequency;
102 
103 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
104 
110 #define _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
111 
112 static void SetPowerForInternalOscillator ( oC_Power_t Power );
113 static void SetPowerForExternalOscillator ( oC_Power_t Power );
114 static void SetPowerForHibernationOscillator ( oC_Power_t Power );
115 static void SetPowerForPll ( oC_Power_t Power );
116 static void SetPowerForOverDrive ( oC_Power_t Power );
117 static void SetFlashLatency ( uint8_t WaitStates );
118 static oC_ErrorCode_t FindFlashLatency ( oC_Frequency_t ClockFrequency , uint8_t * outWaitStates );
119 static void SetMainClockSource ( MainClockSource_t MainClockSource );
120 static void SetPllSource ( PllSource_t PllSource );
121 static bool CountClockConfiguration ( ClockConfiguration_t * ClockConfiguration );
122 static bool FindHpre ( oC_Frequency_t EntryFrequency , ClockConfiguration_t * ClockConfiguration );
123 static void ConfigurePll ( ClockConfiguration_t * ClockConfiguration );
124 static void SetHpre ( uint8_t Hpre );
125 static void ClockConfigured ( oC_Frequency_t RealFrequency , oC_Frequency_t OscillatorFrequency , oC_CLOCK_LLD_ClockSource_t ClockSource );
126 
127 #undef _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
128 
134 #define _________________________________________VARIABLES_SECTION__________________________________________________________________________
135 
137 static oC_Frequency_t CurrentOscillatorFrequency = oC_MACHINE_INTERNAL_OSCILLATOR_FREQUENCY;
139 static oC_CLOCK_LLD_Interrupt_t ClockConfiguredHandler = NULL;
140 static bool UseEthernet = false;
141 
142 #undef _________________________________________VARIABLES_SECTION__________________________________________________________________________
143 
149 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
150 
153 
154 //==========================================================================================================================================
159 //==========================================================================================================================================
160 oC_ErrorCode_t oC_CLOCK_LLD_TurnOnDriver( void )
161 {
162  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
163 
165 
166  if(oC_Module_TurnOffVerification(&errorCode , oC_Module_CLOCK_LLD))
167  {
168  /* ************************* NOTE ******************************
169  * ClockSource and ClockFrequency is specially not initialized *
170  * to not provide wrong informations about state of clock *
171  * configuration *
172  * *************************************************************/
173 
174  ClockConfiguredHandler = NULL;
175  UseEthernet = false;
176 
177  /* Enable power interface clock */
178  RCC_APB1ENR->PWR_EN = 1;
179  oC_MCS_Delay(10);
180 
181  /* This MUST be at the end of module initialization */
182  oC_Module_TurnOn(oC_Module_CLOCK_LLD);
183  errorCode = oC_ErrorCode_None;
184  }
185 
187 
188  return errorCode;
189 }
190 
191 //==========================================================================================================================================
196 //==========================================================================================================================================
197 oC_ErrorCode_t oC_CLOCK_LLD_TurnOffDriver( void )
198 {
199  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
200 
202 
203  if(oC_Module_TurnOnVerification(&errorCode , oC_Module_CLOCK_LLD))
204  {
205  /* This should be at the start of module release */
206  oC_Module_TurnOff(oC_Module_CLOCK_LLD);
207 
208  /* Disable power interface clock */
209  RCC_APB1ENR->PWR_EN = 0;
210  oC_MCS_Delay(10);
211 
212  errorCode = oC_ErrorCode_None;
213  }
214 
216 
217  return errorCode;
218 }
219 
220 //==========================================================================================================================================
225 //==========================================================================================================================================
227 {
228  return CurrentClockSource;
229 }
230 
231 //==========================================================================================================================================
236 //==========================================================================================================================================
238 {
239  return CurrentFrequency;
240 }
241 
242 //==========================================================================================================================================
247 //==========================================================================================================================================
249 {
250  return CurrentOscillatorFrequency;
251 }
252 
253 //==========================================================================================================================================
258 //==========================================================================================================================================
260 {
261  return MAX_FREQUENCY;
262 }
263 
264 //==========================================================================================================================================
269 //==========================================================================================================================================
271 {
272  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
273 
274  if(oC_Module_TurnOnVerification(&errorCode , oC_Module_CLOCK_LLD))
275  {
276  if(
277  oC_AssignErrorCodeIfFalse(&errorCode , ClockConfiguredHandler == NULL , oC_ErrorCode_InterruptHandlerAlreadySet ) &&
278  oC_AssignErrorCodeIfFalse(&errorCode , IsRom(Interrupt) || IsRam(Interrupt) , oC_ErrorCode_WrongEventHandlerAddress )
279  )
280  {
282  ClockConfiguredHandler = Interrupt;
283  errorCode = oC_ErrorCode_None;
285  }
286  }
287 
288  return errorCode;
289 }
290 
291 //==========================================================================================================================================
296 //==========================================================================================================================================
297 bool oC_CLOCK_LLD_DelayForMicroseconds( oC_UInt_t Microseconds )
298 {
299  oC_UInt_t numberOfCyclesPerMicrosecond = CurrentFrequency/1000000UL;
300 
301  oC_MCS_Delay(numberOfCyclesPerMicrosecond*Microseconds);
302 
303  return true;
304 }
305 
306 //==========================================================================================================================================
311 //==========================================================================================================================================
312 oC_ErrorCode_t oC_CLOCK_LLD_ConfigureInternalClock( oC_Frequency_t TargetFrequency , oC_Frequency_t PermissibleDifference )
313 {
314  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
315 
316  if(oC_Module_TurnOnVerification(&errorCode , oC_Module_CLOCK_LLD))
317  {
318  uint8_t latencyWaitStates = 0;
319  bool increasingFrequency = TargetFrequency >= CurrentFrequency;
320  ClockConfiguration_t clockConfig = {
321  .ResultDifference = PermissibleDifference + 1 ,
322  .TargetFrequency = TargetFrequency ,
323  .PermissibleDifference = PermissibleDifference ,
324  .OscillatorFrequency = oC_MACHINE_INTERNAL_OSCILLATOR_FREQUENCY
325  };
326 
327  if(
328  oC_AssignErrorCodeIfFalse(&errorCode , TargetFrequency > 0 , oC_ErrorCode_WrongFrequency ) &&
329  oC_AssignErrorCodeIfFalse(&errorCode , TargetFrequency <= MAX_FREQUENCY , oC_ErrorCode_FrequencyNotPossible) &&
330  oC_AssignErrorCodeIfFalse(&errorCode , CountClockConfiguration(&clockConfig) , oC_ErrorCode_FrequencyNotPossible) &&
331  oC_AssignErrorCode( &errorCode , FindFlashLatency(clockConfig.ResultFrequency , &latencyWaitStates))
332  )
333  {
335 
336  SetPowerForInternalOscillator(oC_Power_On);
337  SetPowerForPll(oC_Power_Off);
338 
339  if(clockConfig.UsePll)
340  {
341  SetPllSource(PllSource_HSI);
342  ConfigurePll(&clockConfig);
343  SetPowerForPll(oC_Power_On);
344 
345  SetPowerForOverDrive(oC_Power_On);
346 
347  /* ****************** NOTE ******************
348  * In case of increasing system clock *
349  * frequency, it is recommended to set flash*
350  * latency before selecting clock source *
351  * ******************************************/
352  if(increasingFrequency)
353  {
354  SetFlashLatency(latencyWaitStates);
355  }
356 
357  SetHpre(clockConfig.Hpre);
358 
359  SetMainClockSource(MainClockSource_PLL);
360  }
361  else
362  {
363  /* ****************** NOTE ******************
364  * In case of increasing system clock *
365  * frequency, it is recommended to set flash*
366  * latency before selecting clock source *
367  * ******************************************/
368  if(increasingFrequency)
369  {
370  SetFlashLatency(latencyWaitStates);
371  }
372 
373  SetHpre(clockConfig.Hpre);
374 
375  SetMainClockSource(MainClockSource_HSI);
376  }
377 
378  /* ****************** NOTE ******************
379  * In case of increasing system clock *
380  * frequency, it is recommended to set flash*
381  * latency after selecting clock source *
382  * ******************************************/
383  if(!increasingFrequency)
384  {
385  SetFlashLatency(latencyWaitStates);
386  }
387 
388  ClockConfigured(clockConfig.ResultFrequency , clockConfig.OscillatorFrequency , oC_CLOCK_LLD_ClockSource_Internal);
389 
390  errorCode = oC_ErrorCode_None;
391 
393  }
394  }
395 
396  return errorCode;
397 }
398 
399 //==========================================================================================================================================
404 //==========================================================================================================================================
405 oC_ErrorCode_t oC_CLOCK_LLD_ConfigureExternalClock( oC_Frequency_t TargetFrequency , oC_Frequency_t PermissibleDifference , oC_Frequency_t OscillatorFrequency )
406 {
407  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
408 
409  if(oC_Module_TurnOnVerification(&errorCode , oC_Module_CLOCK_LLD))
410  {
411  uint8_t latencyWaitStates = 0;
412  bool increasingFrequency = TargetFrequency >= CurrentFrequency;
413  ClockConfiguration_t clockConfig = {
414  .ResultDifference = PermissibleDifference + 1 ,
415  .TargetFrequency = TargetFrequency,
416  .PermissibleDifference = PermissibleDifference,
417  .OscillatorFrequency = OscillatorFrequency
418  };
419 
420  if(
421  oC_AssignErrorCodeIfFalse(&errorCode , TargetFrequency > 0 , oC_ErrorCode_WrongFrequency ) &&
422  oC_AssignErrorCodeIfFalse(&errorCode , OscillatorFrequency > 0 , oC_ErrorCode_WrongFrequency ) &&
423  oC_AssignErrorCodeIfFalse(&errorCode , TargetFrequency <= MAX_FREQUENCY , oC_ErrorCode_FrequencyNotPossible) &&
424  oC_AssignErrorCodeIfFalse(&errorCode , CountClockConfiguration(&clockConfig) , oC_ErrorCode_FrequencyNotPossible) &&
425  oC_AssignErrorCode( &errorCode , FindFlashLatency(clockConfig.ResultFrequency , &latencyWaitStates))
426  )
427  {
429 
430  SetPowerForExternalOscillator(oC_Power_On);
431  SetPowerForPll(oC_Power_Off);
432 
433  if(clockConfig.UsePll)
434  {
435  SetPllSource(PllSource_HSE);
436  ConfigurePll(&clockConfig);
437 
438  /* ****************** NOTE ******************
439  * Turning on power for external oscillator *
440  * must be done after configuring PLL *
441  * according to the documentation so it *
442  * cannot be done before this condition *
443  * block
444  * ******************************************/
445  SetPowerForExternalOscillator(oC_Power_On);
446  SetPowerForPll(oC_Power_On);
447 
448  SetPowerForOverDrive(oC_Power_On);
449 
450  /* ****************** NOTE ******************
451  * In case of increasing system clock *
452  * frequency, it is recommended to set flash*
453  * latency before selecting clock source *
454  * ******************************************/
455  if(increasingFrequency)
456  {
457  SetFlashLatency(latencyWaitStates);
458  }
459 
460  SetHpre(clockConfig.Hpre);
461 
462  SetMainClockSource(MainClockSource_PLL);
463  }
464  else
465  {
466  SetPowerForExternalOscillator(oC_Power_On);
467 
468  /* ****************** NOTE ******************
469  * In case of increasing system clock *
470  * frequency, it is recommended to set flash*
471  * latency before selecting clock source *
472  * ******************************************/
473  if(increasingFrequency)
474  {
475  SetFlashLatency(latencyWaitStates);
476  }
477 
478  SetHpre(clockConfig.Hpre);
479 
480  SetMainClockSource(MainClockSource_HSE);
481  }
482 
483  /* ****************** NOTE ******************
484  * In case of increasing system clock *
485  * frequency, it is recommended to set flash*
486  * latency after selecting clock source *
487  * ******************************************/
488  if(!increasingFrequency)
489  {
490  SetFlashLatency(latencyWaitStates);
491  }
492 
493  ClockConfigured(clockConfig.ResultFrequency , clockConfig.OscillatorFrequency , oC_CLOCK_LLD_ClockSource_External);
494 
496 
497  errorCode = oC_ErrorCode_None;
498  }
499  }
500 
501  return errorCode;
502 }
503 
504 //==========================================================================================================================================
509 //==========================================================================================================================================
510 oC_ErrorCode_t oC_CLOCK_LLD_ConfigureHibernationClock( oC_Frequency_t TargetFrequency , oC_Frequency_t PermissibleDifference , oC_Frequency_t OscillatorFrequency )
511 {
512  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
513 
514  if(oC_Module_TurnOnVerification(&errorCode , oC_Module_CLOCK_LLD))
515  {
516  if(TargetFrequency == 0)
517  {
518  TargetFrequency = HIBERNATION_FREQUENCY;
519  }
520 
521  if(oC_AssignErrorCodeIfFalse(&errorCode , TargetFrequency != HIBERNATION_FREQUENCY , oC_ErrorCode_WrongFrequency ))
522  {
523  SetPowerForHibernationOscillator(oC_Power_On);
524  errorCode = oC_ErrorCode_NotImplemented;
525  }
526  }
527 
528  return errorCode;
529 }
530 
531 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
532 
539 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
540 
541 //==========================================================================================================================================
545 //==========================================================================================================================================
546 static void SetPowerForInternalOscillator( oC_Power_t Power )
547 {
548  if(Power == oC_Power_On)
549  {
550  RCC_CR->HSION = 1;
551 
552  while(!RCC_CR->HSIRDY);
553  }
554  else
555  {
556  RCC_CR->HSION = 0;
557 
558  while(RCC_CR->HSIRDY);
559  }
560 }
561 
562 //==========================================================================================================================================
566 //==========================================================================================================================================
567 static void SetPowerForExternalOscillator( oC_Power_t Power )
568 {
569  if(Power == oC_Power_On)
570  {
571  RCC_CR->HSEON = 0;
572 
573  while(RCC_CR->HSERDY);
574 
575  RCC_CR->HSEBYP= 0;
576  RCC_CR->HSEON = 1;
577 
578  while(!RCC_CR->HSERDY);
579  }
580  else
581  {
582  RCC_CR->HSEON = 0;
583 
584  while(RCC_CR->HSERDY);
585  }
586 }
587 
588 //==========================================================================================================================================
592 //==========================================================================================================================================
593 static void SetPowerForHibernationOscillator( oC_Power_t Power )
594 {
595  if(Power == oC_Power_On)
596  {
597  RCC_CSR->LSION = 1;
598 
599  while(!RCC_CSR->LSIRDY);
600  }
601  else
602  {
603  RCC_CSR->LSION = 0;
604 
605  while(RCC_CSR->LSIRDY);
606  }
607 }
608 
609 //==========================================================================================================================================
613 //==========================================================================================================================================
614 static void SetPowerForPll( oC_Power_t Power )
615 {
616  if(Power == oC_Power_On)
617  {
618  RCC_CR->PLLON = 1;
619 
620  while(!RCC_CR->PLLRDY);
621  }
622  else
623  {
624  RCC_CR->PLLON = 0;
625 
626  while(RCC_CR->PLLRDY);
627  }
628 }
629 
630 //==========================================================================================================================================
634 //==========================================================================================================================================
635 static void SetPowerForOverDrive( oC_Power_t Power )
636 {
637  if(Power == oC_Power_On)
638  {
639  PWR_CR->ODEN = 1;
640 
641  while(!PWR_CSR->ODRDY);
642  }
643  else
644  {
645  PWR_CR->ODEN = 0;
646 
647  while(PWR_CSR->ODRDY);
648  }
649 }
650 
651 //==========================================================================================================================================
655 //==========================================================================================================================================
656 static void SetFlashLatency( uint8_t WaitStates )
657 {
658  FLASH_ACR->LATENCY = WaitStates;
659 
660  /* FLASH Latency cannot be programmed */
661  oC_ASSERT(FLASH_ACR->LATENCY == WaitStates);
662 }
663 
664 //==========================================================================================================================================
668 //==========================================================================================================================================
669 static oC_ErrorCode_t FindFlashLatency( oC_Frequency_t ClockFrequency , uint8_t * outWaitStates )
670 {
671  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
672  float vdd = 0;
673 
674  if(oC_AssignErrorCode(&errorCode , oC_SYS_LLD_ReadPowerState(&vdd)))
675  {
676  typedef struct
677  {
678  uint8_t WaitStates;
679  float VddMin;
680  float VddMax;
681  oC_Frequency_t SystemClockMin;
682  oC_Frequency_t SystemClockMax;
683  } FlashLatencyCapabilities_t;
684 
685  /* ****************************************************
686  * The array with definitions of wait states for *
687  * different conditions - the VDD voltage and *
688  * clock frequency is important here. For more *
689  * informations look at the documentation at 76 p. *
690  * ****************************************************/
691  static const FlashLatencyCapabilities_t latencyArray[] = {
692  /* 2.7 - 3.6 V */
693  { .WaitStates = 0 , .VddMin = 2.7 , .VddMax = 3.6 , .SystemClockMin = 0 , .SystemClockMax = MHz(30) } ,
694  { .WaitStates = 1 , .VddMin = 2.7 , .VddMax = 3.6 , .SystemClockMin = MHz(30) , .SystemClockMax = MHz(60) } ,
695  { .WaitStates = 2 , .VddMin = 2.7 , .VddMax = 3.6 , .SystemClockMin = MHz(60) , .SystemClockMax = MHz(90) } ,
696  { .WaitStates = 3 , .VddMin = 2.7 , .VddMax = 3.6 , .SystemClockMin = MHz(90) , .SystemClockMax = MHz(120) } ,
697  { .WaitStates = 4 , .VddMin = 2.7 , .VddMax = 3.6 , .SystemClockMin = MHz(120) , .SystemClockMax = MHz(150) } ,
698  { .WaitStates = 5 , .VddMin = 2.7 , .VddMax = 3.6 , .SystemClockMin = MHz(150) , .SystemClockMax = MHz(180) } ,
699  { .WaitStates = 6 , .VddMin = 2.7 , .VddMax = 3.6 , .SystemClockMin = MHz(180) , .SystemClockMax = MHz(210) } ,
700  { .WaitStates = 7 , .VddMin = 2.7 , .VddMax = 3.6 , .SystemClockMin = MHz(210) , .SystemClockMax = MHz(216) } ,
701 
702  /* 2.4 - 2.7 V */
703  { .WaitStates = 0 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = 0 , .SystemClockMax = MHz(24) } ,
704  { .WaitStates = 1 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = MHz(24) , .SystemClockMax = MHz(48) } ,
705  { .WaitStates = 2 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = MHz(48) , .SystemClockMax = MHz(72) } ,
706  { .WaitStates = 3 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = MHz(72) , .SystemClockMax = MHz(96) } ,
707  { .WaitStates = 4 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = MHz(96) , .SystemClockMax = MHz(120) } ,
708  { .WaitStates = 5 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = MHz(120) , .SystemClockMax = MHz(144) } ,
709  { .WaitStates = 6 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = MHz(144) , .SystemClockMax = MHz(168) } ,
710  { .WaitStates = 7 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = MHz(168) , .SystemClockMax = MHz(192) } ,
711  { .WaitStates = 8 , .VddMin = 2.4 , .VddMax = 2.7 , .SystemClockMin = MHz(192) , .SystemClockMax = MHz(216) } ,
712 
713  /* 2.1 - 2.4 V */
714  { .WaitStates = 0 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = 0 , .SystemClockMax = MHz(22) } ,
715  { .WaitStates = 1 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(22) , .SystemClockMax = MHz(44) } ,
716  { .WaitStates = 2 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(44) , .SystemClockMax = MHz(66) } ,
717  { .WaitStates = 3 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(66) , .SystemClockMax = MHz(88) } ,
718  { .WaitStates = 4 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(88) , .SystemClockMax = MHz(110) } ,
719  { .WaitStates = 5 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(110) , .SystemClockMax = MHz(132) } ,
720  { .WaitStates = 6 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(132) , .SystemClockMax = MHz(154) } ,
721  { .WaitStates = 7 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(154) , .SystemClockMax = MHz(176) } ,
722  { .WaitStates = 8 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(176) , .SystemClockMax = MHz(198) } ,
723  { .WaitStates = 9 , .VddMin = 2.1 , .VddMax = 2.4 , .SystemClockMin = MHz(198) , .SystemClockMax = MHz(216) } ,
724 
725  /* 1.8 - 2.1 V */
726  { .WaitStates = 0 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = 0 , .SystemClockMax = MHz(20) } ,
727  { .WaitStates = 1 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = MHz(20) , .SystemClockMax = MHz(40) } ,
728  { .WaitStates = 2 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = MHz(40) , .SystemClockMax = MHz(60) } ,
729  { .WaitStates = 3 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = MHz(60) , .SystemClockMax = MHz(80) } ,
730  { .WaitStates = 4 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = MHz(80) , .SystemClockMax = MHz(100) } ,
731  { .WaitStates = 5 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = MHz(100) , .SystemClockMax = MHz(120) } ,
732  { .WaitStates = 6 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = MHz(120) , .SystemClockMax = MHz(140) } ,
733  { .WaitStates = 7 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = MHz(140) , .SystemClockMax = MHz(160) } ,
734  { .WaitStates = 8 , .VddMin = 1.8 , .VddMax = 2.1 , .SystemClockMin = MHz(160) , .SystemClockMax = MHz(180) }
735  };
736 
737  errorCode = oC_ErrorCode_VoltageNotCorrect;
738 
739  oC_ARRAY_FOREACH_IN_ARRAY(latencyArray,latency)
740  {
741  if(vdd >= latency->VddMin && vdd < latency->VddMax)
742  {
743  if(ClockFrequency > latency->SystemClockMin && ClockFrequency < (latency->SystemClockMax + MHz(1)))
744  {
745  *outWaitStates = latency->WaitStates;
746  errorCode = oC_ErrorCode_None;
747  break;
748  }
749  }
750  }
751  }
752 
753  return errorCode;
754 }
755 
756 //==========================================================================================================================================
760 //==========================================================================================================================================
761 static void SetMainClockSource( MainClockSource_t MainClockSource )
762 {
763  RCC_CFGR->SW = MainClockSource;
764 
765  while(RCC_CFGR->SWS != MainClockSource);
766 }
767 
768 //==========================================================================================================================================
772 //==========================================================================================================================================
773 static void SetPllSource( PllSource_t PllSource )
774 {
775  RCC_PLLCFGR->PLLSRC = PllSource;
776 }
777 
778 //==========================================================================================================================================
782 //==========================================================================================================================================
783 static bool CountClockConfiguration( ClockConfiguration_t * ClockConfiguration )
784 {
785  bool configurationPossible = false;
786 
787  /* *************************************
788  * At the start we are trying to use *
789  * PLL to receive the best frequency. *
790  * *************************************/
791  for(uint8_t PLLM = 2 ; PLLM < 64 ; PLLM++)
792  {
793  oC_Frequency_t pllInputFrequency = ClockConfiguration->OscillatorFrequency / ((oC_Frequency_t)(PLLM));
794 
795  if(pllInputFrequency >= oC_MHz(1) && pllInputFrequency <= oC_MHz(2))
796  {
797  for(uint16_t PLLN = 0; PLLN < 511 ; PLLN++)
798  {
799  oC_Frequency_t pllOutputFrequency = pllInputFrequency * ( (oC_Frequency_t)(PLLN) );
800 
801  if(pllOutputFrequency >= oC_MHz(192) && pllOutputFrequency < oC_MHz(433))
802  {
803  for(uint8_t PLLP = 0 ; PLLP < 4 ; PLLP++)
804  {
805  oC_Frequency_t pllClkFrequency = pllOutputFrequency / ((oC_Frequency_t)((PLLP+1)<<1));
806 
807  if(FindHpre(pllClkFrequency , ClockConfiguration))
808  {
809  ClockConfiguration->UsePll = true;
810  ClockConfiguration->PllM = PLLM;
811  ClockConfiguration->PllN = PLLN;
812  ClockConfiguration->PllP = PLLP;
813 
814  configurationPossible = true;
815  }
816  }
817  }
818  }
819  }
820  }
821 
822  /* *************************************
823  * If it is possible, it is better to *
824  * use oscillator without PLL *
825  * *************************************/
826  if(FindHpre(ClockConfiguration->OscillatorFrequency , ClockConfiguration))
827  {
828  ClockConfiguration->UsePll = false;
829  ClockConfiguration->PllM = 0;
830  ClockConfiguration->PllN = 0;
831  ClockConfiguration->PllP = 0;
832 
833  configurationPossible = true;
834  }
835 
836 
837  return configurationPossible;
838 }
839 
840 //==========================================================================================================================================
844 //==========================================================================================================================================
845 static bool FindHpre( oC_Frequency_t EntryFrequency , ClockConfiguration_t * ClockConfiguration )
846 {
847  bool foundHpre = false;
848  const uint16_t hpreDivisors[] = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 4 , 8 , 16 , 64 , 128 , 256 , 512 };
849 
850  for(uint8_t HPRE = 0x0 ; HPRE <= 0xF ;HPRE++)
851  {
852  oC_Frequency_t mainClockFrequency = EntryFrequency / ((oC_Frequency_t)(hpreDivisors[HPRE]));
853 
854  if((UseEthernet && mainClockFrequency >= MHz(25)) || !UseEthernet)
855  {
856  if(!foundHpre || oC_ABS(mainClockFrequency,ClockConfiguration->TargetFrequency) <= ClockConfiguration->ResultDifference)
857  {
858  ClockConfiguration->ResultDifference= oC_ABS(mainClockFrequency,ClockConfiguration->TargetFrequency);
859 
860  if(ClockConfiguration->ResultDifference <= ClockConfiguration->PermissibleDifference)
861  {
862  ClockConfiguration->Hpre = HPRE;
863  ClockConfiguration->ResultFrequency = mainClockFrequency;
864  foundHpre = true;
865  break;
866  }
867  }
868  }
869  }
870 
871  return foundHpre;
872 }
873 
874 //==========================================================================================================================================
878 //==========================================================================================================================================
879 static void ConfigurePll( ClockConfiguration_t * ClockConfiguration )
880 {
881  RCC_PLLCFGR->PLLM = ClockConfiguration->PllM;
882  RCC_PLLCFGR->PLLN = ClockConfiguration->PllN;
883  RCC_PLLCFGR->PLLP = ClockConfiguration->PllP;
884 }
885 
886 //==========================================================================================================================================
890 //==========================================================================================================================================
891 static void SetHpre( uint8_t Hpre )
892 {
893  RCC_CFGR->HPRE = Hpre;
894 }
895 
896 //==========================================================================================================================================
900 //==========================================================================================================================================
901 static void ClockConfigured( oC_Frequency_t RealFrequency , oC_Frequency_t OscillatorFrequency , oC_CLOCK_LLD_ClockSource_t ClockSource )
902 {
904 
905  CurrentClockSource = ClockSource;
906  CurrentFrequency = RealFrequency;
907  CurrentOscillatorFrequency = OscillatorFrequency;
908 
909  if(IsRom(ClockConfiguredHandler) || IsRam(ClockConfiguredHandler))
910  {
911  ClockConfiguredHandler(RealFrequency);
912  }
913 
915 }
916 
917 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
Something is powered on.
Definition: oc_stdtypes.h:252
Basic math operations.
oC_ErrorCode_t oC_CLOCK_LLD_TurnOffDriver(void)
release the driver
Definition: oc_clock_lld.c:197
double oC_Frequency_t
type to store frequency
Definition: oc_frequency.h:76
oC_ErrorCode_t oC_CLOCK_LLD_SetClockConfiguredInterrupt(oC_CLOCK_LLD_Interrupt_t Interrupt)
configures an interrupt for clock configured event
Definition: oc_clock_lld.c:270
oC_CLOCK_LLD_ClockSource_t oC_CLOCK_LLD_GetClockSource(void)
returns source of the system clock
Definition: oc_clock_lld.c:226
#define MHz(Freq)
Number of MHz.
Definition: oc_cfg.h:108
oC_CLOCK_LLD_ClockSource_t
type for storing source of the system clock
Definition: oc_clock_lld.h:73
The file with interface for LSF module.
oC_Frequency_t oC_CLOCK_LLD_GetMaximumClockFrequency(void)
returns maximum frequency permissible for the machine
Definition: oc_clock_lld.c:259
oC_ErrorCode_t oC_CLOCK_LLD_ConfigureInternalClock(oC_Frequency_t TargetFrequency, oC_Frequency_t PermissibleDifference)
configures system clock in internal mode
Definition: oc_clock_lld.c:312
an external source of the clock is used
Definition: oc_clock_lld.h:76
The file with LLD interface for the MEM driver.
an internal clock source is used
Definition: oc_clock_lld.h:75
void oC_MCS_Delay(register oC_UInt_t Cycles)
delays operations for cycles
Definition: oc_mcs.c:679
The file with interface for the module library.
oC_Frequency_t oC_CLOCK_LLD_GetClockFrequency(void)
returns frequency of the system clock
Definition: oc_clock_lld.c:237
Something is powered off.
Definition: oc_stdtypes.h:251
oC_ErrorCode_t oC_CLOCK_LLD_TurnOnDriver(void)
initializes the driver to work
Definition: oc_clock_lld.c:160
The file with LLD interface for the CLOCK driver.
oC_ErrorCode_t oC_SYS_LLD_ReadPowerState(float *outVcc)
reads power state
Definition: oc_sys_lld.c:518
#define oC_ABS(A, B)
Definition: oc_math.h:46
oC_ErrorCode_t oC_CLOCK_LLD_ConfigureExternalClock(oC_Frequency_t TargetFrequency, oC_Frequency_t PermissibleDifference, oC_Frequency_t OscillatorFrequency)
configures system clock to work in external mode
Definition: oc_clock_lld.c:405
static void oC_Module_TurnOn(oC_Module_t Module)
sets module as turned on
Definition: oc_module.h:170
Contains machine core specific functions.
static void oC_MCS_EnterCriticalSection(void)
Enters to critical section.
Definition: oc_mcs.h:755
oC_ErrorCode_t oC_CLOCK_LLD_ConfigureHibernationClock(oC_Frequency_t TargetFrequency, oC_Frequency_t PermissibleDifference, oC_Frequency_t OscillatorFrequency)
configures system clock to work in hibernation mode
Definition: oc_clock_lld.c:510
The file with interface interrupt module.
static bool oC_Module_TurnOffVerification(oC_ErrorCode_t *outErrorCode, oC_Module_t Module)
verify if module is turned off
Definition: oc_module.h:155
void(* oC_CLOCK_LLD_Interrupt_t)(oC_Frequency_t Frequency)
type for storing interrupts pointers
Definition: oc_clock_lld.h:88
static bool oC_MCS_ExitCriticalSection(void)
Exits from critical section.
Definition: oc_mcs.h:784
static bool oC_Module_TurnOnVerification(oC_ErrorCode_t *outErrorCode, oC_Module_t Module)
verify if module is turned on
Definition: oc_module.h:138
The file with LLD interface for the SYS driver.
bool oC_CLOCK_LLD_DelayForMicroseconds(oC_UInt_t Microseconds)
perform a delay for us
Definition: oc_clock_lld.c:297
oC_Power_t
stores registers power state
Definition: oc_stdtypes.h:249
oC_Frequency_t oC_CLOCK_LLD_GetOscillatorFrequency(void)
returns frequency of the oscillator
Definition: oc_clock_lld.c:248
#define oC_MACHINE_INTERNAL_OSCILLATOR_FREQUENCY
#define NULL
pointer to a zero
Definition: oc_null.h:37
static void oC_Module_TurnOff(oC_Module_t Module)
sets module as turned off
Definition: oc_module.h:185