Skip to content

Commit 0ae6b7a

Browse files
committed
Added clock fetching function for SDK implementation
1 parent e308bf4 commit 0ae6b7a

File tree

1 file changed

+199
-32
lines changed

1 file changed

+199
-32
lines changed

ARM/gcc_clang/system/src/renesas/ra8m1/init_clock.c

Lines changed: 199 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,47 @@ extern void * __Vectors[];
4646

4747
typedef 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
*/
564713
void 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

Comments
 (0)