@@ -46,15 +46,47 @@ extern void * __Vectors[];
4646
4747typedef struct
4848{
49+ uint32_t CPUCLK_Frequency ; // CPU clock frequency in Hz
4950 uint32_t ICLK_Frequency ; // System clock frequency in Hz
5051 uint32_t PCLKA_Frequency ; // PCLKA clock frequency in Hz
5152 uint32_t PCLKB_Frequency ; // PCLKB clock frequency in Hz
5253 uint32_t PCLKC_Frequency ; // PCLKC clock frequency in Hz
5354 uint32_t PCLKD_Frequency ; // PCLKD clock frequency in Hz
55+ uint32_t PCLKE_Frequency ; // PCLKE clock frequency in Hz
5456 uint32_t FCLK_Frequency ; // Flash interface clock frequency in Hz
57+ uint32_t SPICLK_Frequency ; // SPI clock frequency in Hz
58+ uint32_t SCICLK_Frequency ; // SCI clock frequency in Hz
5559} SYSTEM_ClocksTypeDef ;
5660
57- static uint8_t ClockPrescTable [ 7 ] = { 1 , 2 , 4 , 8 , 16 , 32 , 64 };
61+ static uint8_t ClockPrescTable [] = { 1 , 2 , 4 , 8 , 16 , 32 , 64 , 0 , 3 , 6 , 12 };
62+
63+ /* Helper macros for getting SPI and SCI clock sources. */
64+ #define SCI_SPI_SOURCE_HOCO (0)
65+ #define SCI_SPI_SOURCE_MOCO (1)
66+ #define SCI_SPI_SOURCE_LOCO (2)
67+ #define SCI_SPI_SOURCE_MOSC (3)
68+ #define SCI_SPI_SOURCE_SOSC (4)
69+ #define SCI_SPI_SOURCE_PLL1P (5)
70+ #define SCI_SPI_SOURCE_PLL2P (6)
71+ #define SCI_SPI_SOURCE_PLL1Q (7)
72+ #define SCI_SPI_SOURCE_PLL1R (8)
73+ #define SCI_SPI_SOURCE_PLL2Q (9)
74+ #define SCI_SPI_SOURCE_PLL2R (10)
75+ #define HOCO_FREQUENCY_MHZ_16 (0)
76+ #define HOCO_FREQUENCY_MHZ_18 (1)
77+ #define HOCO_FREQUENCY_MHZ_20 (2)
78+ #define HOCO_FREQUENCY_MHZ_32 (4)
79+ #define HOCO_FREQUENCY_MHZ_48 (7)
80+ #define FREQUENCY_32768HZ (32768)
81+ #define FREQUENCY_8MHZ (8000000)
82+ #define FREQUENCY_16MHZ (16000000)
83+ #define FREQUENCY_18MHZ (18000000)
84+ #define FREQUENCY_20MHZ (20000000)
85+ #define FREQUENCY_32MHZ (32000000)
86+ #define FREQUENCY_48MHZ (48000000)
87+ #define PLLMULNF_HALF (0xC0)
88+ #define PLLMULNF_TWO_THIRDS (0x80)
89+ #define PLLMULNF_ONE_THIRD (0x40)
5890
5991/* Key code for writing PRCR register. */
6092#define BSP_PRV_PRCR_KEY (0xA500U)
@@ -553,6 +585,123 @@ static void system_clock_configuration();
553585
554586// -----------------------------------------------------------------------------------------
555587
588+ /**
589+ * @brief Gets PLL subclock values.
590+ *
591+ * Calculates configured clock frequency for PLL1P, PLL1Q, PLL1R, PLL2P, PLL2Q and PLL2R.
592+ *
593+ * @return PLL subclock value.
594+ */
595+ uint32_t SYSTEM_GetPLLClocksFrequency ( uint32_t pll_config_value , \
596+ uint32_t hoco_frequency , uint8_t prescaler ) {
597+ uint32_t pll_frequency ;
598+
599+ // Get PLL source clock.
600+ if ( pll_config_value & R_SYSTEM_PLLCCR_PLSRCSEL_Msk )
601+ pll_frequency = hoco_frequency ;
602+ else
603+ // Note: MOSC value used by EK-RA8M1 Board.
604+ pll_frequency = FREQUENCY_20MHZ ;
605+ // Divide PLL source clock based on PLIDIV value.
606+ pll_frequency /= ( pll_config_value & R_SYSTEM_PLLCCR_PLIDIV_Msk ) + 1 ;
607+ // Multiply result clock based on PLLMUL value.
608+ pll_frequency *= (( pll_config_value & R_SYSTEM_PLLCCR_PLLMUL_Msk )\
609+ >> R_SYSTEM_PLLCCR_PLLMUL_Pos ) + 1 ;
610+ // Take into consideration the PLLMULNF part.
611+ if ( PLLMULNF_HALF == ( pll_config_value & R_SYSTEM_PLLCCR_PLLMULNF_Msk ))
612+ pll_frequency += pll_frequency / 2 ;
613+ else if ( PLLMULNF_TWO_THIRDS == ( pll_config_value & R_SYSTEM_PLLCCR_PLLMULNF_Msk ))
614+ pll_frequency += pll_frequency * 2 / 3 ;
615+ else if ( PLLMULNF_ONE_THIRD == ( pll_config_value & R_SYSTEM_PLLCCR_PLLMULNF_Msk ))
616+ pll_frequency += pll_frequency / 3 ;
617+
618+ return ( pll_frequency / prescaler );
619+ }
620+
621+ /**
622+ * @brief Gets the peripheral clock values for SPI and SCI modules.
623+ *
624+ * Calculates configured clock frequency for SPI and SCI clocks.
625+ *
626+ * @return SPI or SCI peripheral clock value.
627+ */
628+ uint32_t SYSTEM_GetSPISCIClocksFrequency ( uint8_t config_value ) {
629+ uint32_t hoco_frequency , peripheral_clock ;
630+ uint8_t prescaler ;
631+
632+ // Get HOCO frequency.
633+ if ( HOCO_FREQUENCY_MHZ_16 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ))
634+ hoco_frequency = FREQUENCY_16MHZ ;
635+ else if ( HOCO_FREQUENCY_MHZ_18 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ))
636+ hoco_frequency = FREQUENCY_18MHZ ;
637+ else if ( HOCO_FREQUENCY_MHZ_20 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ))
638+ hoco_frequency = FREQUENCY_20MHZ ;
639+ else if ( HOCO_FREQUENCY_MHZ_32 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ))
640+ hoco_frequency = FREQUENCY_32MHZ ;
641+ else if ( HOCO_FREQUENCY_MHZ_48 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ))
642+ hoco_frequency = FREQUENCY_48MHZ ;
643+
644+ switch ( config_value ) {
645+ case SCI_SPI_SOURCE_HOCO :
646+ peripheral_clock = hoco_frequency ;
647+ break ;
648+ case SCI_SPI_SOURCE_MOCO :
649+ peripheral_clock = FREQUENCY_8MHZ ;
650+ break ;
651+ case SCI_SPI_SOURCE_LOCO :
652+ peripheral_clock = FREQUENCY_32768HZ ;
653+ break ;
654+ case SCI_SPI_SOURCE_MOSC :
655+ // Note: MOSC value used by EK-RA8M1 Board.
656+ peripheral_clock = FREQUENCY_20MHZ ;
657+ break ;
658+ case SCI_SPI_SOURCE_SOSC :
659+ peripheral_clock = FREQUENCY_32768HZ ;
660+ break ;
661+ case SCI_SPI_SOURCE_PLL1P :
662+ prescaler = (( VALUE_SYSTEM_PLLCCR2 & R_SYSTEM_PLLCCR2_PLODIVP_Msk ) \
663+ >> R_SYSTEM_PLLCCR2_PLODIVP_Pos ) + 1 ;
664+ peripheral_clock = \
665+ SYSTEM_GetPLLClocksFrequency ( VALUE_SYSTEM_PLLCCR , hoco_frequency , prescaler );
666+ break ;
667+ case SCI_SPI_SOURCE_PLL2P :
668+ prescaler = (( VALUE_SYSTEM_PLL2CCR2 & R_SYSTEM_PLL2CCR2_PL2ODIVP_Msk ) \
669+ >> R_SYSTEM_PLL2CCR2_PL2ODIVP_Pos ) + 1 ;
670+ peripheral_clock = \
671+ SYSTEM_GetPLLClocksFrequency ( VALUE_SYSTEM_PLL2CCR , hoco_frequency , prescaler );
672+ break ;
673+ case SCI_SPI_SOURCE_PLL1Q :
674+ prescaler = (( VALUE_SYSTEM_PLLCCR2 & R_SYSTEM_PLLCCR2_PLODIVQ_Msk ) \
675+ >> R_SYSTEM_PLLCCR2_PLODIVQ_Pos ) + 1 ;
676+ peripheral_clock = \
677+ SYSTEM_GetPLLClocksFrequency ( VALUE_SYSTEM_PLLCCR , hoco_frequency , prescaler );
678+ break ;
679+ case SCI_SPI_SOURCE_PLL1R :
680+ prescaler = (( VALUE_SYSTEM_PLLCCR2 & R_SYSTEM_PLLCCR2_PLODIVR_Msk ) \
681+ >> R_SYSTEM_PLLCCR2_PLODIVR_Pos ) + 1 ;
682+ peripheral_clock = \
683+ SYSTEM_GetPLLClocksFrequency ( VALUE_SYSTEM_PLLCCR , hoco_frequency , prescaler );
684+ break ;
685+ case SCI_SPI_SOURCE_PLL2Q :
686+ prescaler = (( VALUE_SYSTEM_PLL2CCR2 & R_SYSTEM_PLL2CCR2_PL2ODIVQ_Msk ) \
687+ >> R_SYSTEM_PLL2CCR2_PL2ODIVQ_Pos ) + 1 ;
688+ peripheral_clock = \
689+ SYSTEM_GetPLLClocksFrequency ( VALUE_SYSTEM_PLL2CCR , hoco_frequency , prescaler );
690+ break ;
691+ case SCI_SPI_SOURCE_PLL2R :
692+ prescaler = (( VALUE_SYSTEM_PLL2CCR2 & R_SYSTEM_PLL2CCR2_PL2ODIVR_Msk ) \
693+ >> R_SYSTEM_PLL2CCR2_PL2ODIVR_Pos ) + 1 ;
694+ peripheral_clock = \
695+ SYSTEM_GetPLLClocksFrequency ( VALUE_SYSTEM_PLL2CCR , hoco_frequency , prescaler );
696+ break ;
697+
698+ default :
699+ break ;
700+ }
701+
702+ return peripheral_clock ;
703+ }
704+
556705/**
557706 * @brief Gets the system clock values.
558707 *
@@ -562,34 +711,51 @@ static void system_clock_configuration();
562711 * @return None
563712 */
564713void SYSTEM_GetClocksFrequency ( SYSTEM_ClocksTypeDef * SYSTEM_Clocks ) {
565- uint32_t prescaler , source_clock ;
714+ uint32_t source_clock ;
715+ uint8_t prescaler ;
566716
567- // Get the frequency of main clock.
568- SYSTEM_Clocks -> ICLK_Frequency = FOSC_KHZ_VALUE * 1000 ;
717+ // Get the frequency of CPU clock.
718+ SYSTEM_Clocks -> CPUCLK_Frequency = FOSC_KHZ_VALUE * 1000 ;
569719
570720 // Get the source frequency for all clocks.
571- prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0x7000000 ) >> 24 ];
572- source_clock = SYSTEM_Clocks -> ICLK_Frequency * prescaler ;
721+ prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR2 & 0xF ) ];
722+ source_clock = SYSTEM_Clocks -> CPUCLK_Frequency * prescaler ;
723+
724+ // Get FCLK clock frequency.
725+ prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0xF0000000 ) >> 28 ];
726+ SYSTEM_Clocks -> FCLK_Frequency = source_clock / prescaler ;
727+
728+ // Get the frequency of system clock.
729+ prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0xF000000 ) >> 24 ];
730+ SYSTEM_Clocks -> ICLK_Frequency = source_clock / prescaler ;
731+
732+ // Get PCLKE clock frequency.
733+ prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0xF00000 ) >> 20 ];
734+ SYSTEM_Clocks -> PCLKE_Frequency = source_clock / prescaler ;
573735
574736 // Get PCLKA clock frequency.
575- prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0x7000 ) >> 12 ];
737+ prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0xF000 ) >> 12 ];
576738 SYSTEM_Clocks -> PCLKA_Frequency = source_clock / prescaler ;
577739
578740 // Get PCLKB clock frequency.
579- prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0x700 ) >> 8 ];
741+ prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0xF00 ) >> 8 ];
580742 SYSTEM_Clocks -> PCLKB_Frequency = source_clock / prescaler ;
581743
582744 // Get PCLKC clock frequency.
583- prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0x70 ) >> 4 ];
745+ prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0xF0 ) >> 4 ];
584746 SYSTEM_Clocks -> PCLKC_Frequency = source_clock / prescaler ;
585747
586748 // Get PCLKD clock frequency.
587- prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0x7 ) ];
749+ prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0xF ) ];
588750 SYSTEM_Clocks -> PCLKD_Frequency = source_clock / prescaler ;
589751
590- // Get FCLK clock frequency.
591- prescaler = ClockPrescTable [ ( VALUE_SYSTEM_SCKDIVCR & 0x7000 ) >> 12 ];
592- SYSTEM_Clocks -> FCLK_Frequency = source_clock / prescaler ;
752+ // Get the source clock of SPI module.
753+ SYSTEM_Clocks -> SPICLK_Frequency = \
754+ SYSTEM_GetSPISCIClocksFrequency ( VALUE_SYSTEM_SPICKCR & R_SYSTEM_SPICKCR_CKSEL_Msk );
755+
756+ // Get the source clock of SCI module.
757+ SYSTEM_Clocks -> SCICLK_Frequency = \
758+ SYSTEM_GetSPISCIClocksFrequency ( VALUE_SYSTEM_SCICKCR & R_SYSTEM_SCICKCR_SCICKSEL_Msk );
593759}
594760
595761/**
@@ -656,16 +822,6 @@ void SystemInit(void)
656822 // Clock setting
657823 system_clock_configuration ();
658824
659- // Unlock LVOCR register
660- R_SYSTEM -> PRCR = (uint16_t ) BSP_PRV_PRCR_PRC1_UNLOCK ;
661-
662- /* Set LVOCR according to BSP configuration.
663- * Configure prior to warm start post clock, since OSPI_B may initialize within and begin using I/O. */
664- R_SYSTEM -> LVOCR = 0 ;
665-
666- // Lock LVOCR register
667- R_SYSTEM -> PRCR = (uint16_t ) BSP_PRV_PRCR_LOCK ;
668-
669825 memset (
670826 & __ram_zero$$Base ,
671827 0 ,
@@ -724,16 +880,13 @@ static void system_clock_configuration() {
724880 }
725881
726882 if ( !( VALUE_SYSTEM_HOCOCR & R_SYSTEM_HOCOCR_HCSTP_Msk ) ) {
727- if ( 0x2 == ( VALUE_SYSTEM_HOCOCR2 & 0x3 ) ) // 20MHz
728- {
883+ if ( HOCO_FREQUENCY_MHZ_20 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ) ) {
729884 R_SYSTEM -> FLLCR2_b .FLLCNTL = 0x263 ;
730- } else if ( 0x1 == ( VALUE_SYSTEM_HOCOCR2 & 0x3 ) ) // 18MHz
731- {
885+ } else if ( HOCO_FREQUENCY_MHZ_18 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ) ) {
732886 R_SYSTEM -> FLLCR2_b .FLLCNTL = 0x226 ;
733- } else if (( 0x0 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ) ) || // 16MHz
734- ( 0x4 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 )) || // or 32MHz
735- ( 0x7 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ) )) // or 48MHz
736- {
887+ } else if (( HOCO_FREQUENCY_MHZ_16 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ) ) ||
888+ ( HOCO_FREQUENCY_MHZ_32 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 )) ||
889+ ( HOCO_FREQUENCY_MHZ_48 == ( VALUE_SYSTEM_HOCOCR2 & 0x7 ) )) {
737890 R_SYSTEM -> FLLCR2_b .FLLCNTL = 0x1E9 ;
738891 }
739892
@@ -808,6 +961,20 @@ static void system_clock_configuration() {
808961 R_SYSTEM -> SCICKCR = VALUE_SYSTEM_SCICKCR ;
809962 R_SYSTEM -> SPICKCR = VALUE_SYSTEM_SPICKCR ;
810963
811- // Lock write protection register
964+ /* If PLL2 is enabled and PLL1 is not chosen as source clock
965+ * or PLL2 is disabled and PLL1 is chosen as clock source.
966+ */
967+ if (( !( VALUE_SYSTEM_PLL2CR & R_SYSTEM_PLL2CR_PLL2STP_Msk ) && (( VALUE_SYSTEM_SCKSCR & R_SYSTEM_SCKSCR_CKSEL_Msk ) != 0x5 )) || \
968+ ( ( VALUE_SYSTEM_PLL2CR & R_SYSTEM_PLL2CR_PLL2STP_Msk ) && (( VALUE_SYSTEM_SCKSCR & R_SYSTEM_SCKSCR_CKSEL_Msk ) == 0x5 ))) {
969+ // Unlock LVOCR register
970+ R_SYSTEM -> PRCR = (uint16_t ) BSP_PRV_PRCR_PRC1_UNLOCK ;
971+
972+ /* Set LVOCR according to BSP configuration.
973+ * Configure prior to warm start post clock
974+ * since OSPI_B may initialize within and begin using I/O. */
975+ R_SYSTEM -> LVOCR = 0 ;
976+ }
977+
978+ // Lock LVOCR register
812979 R_SYSTEM -> PRCR = (uint16_t ) BSP_PRV_PRCR_LOCK ;
813980}
0 commit comments