iMPROVED clock tree management for ATSAMA5D2 (Still uncomplete)

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10362 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Rocco Marco Guglielmi 2017-08-07 20:02:28 +00:00
parent 99dc081e54
commit e1a4894ab6
1 changed files with 48 additions and 30 deletions

View File

@ -73,44 +73,54 @@ void hal_lld_init(void) {
*/ */
void sama_clock_init(void) { void sama_clock_init(void) {
#if !SAMA_NO_INIT #if !SAMA_NO_INIT
/* Setting Slow clock source. */ uint32_t mor, pllar, mckr;
SCKC->SCKC_CR = SAMA_OSC_SEL; /* Disabling PMC write protection. */
PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
/* Disabling PMC write protection. */ /* Enforces the reset default configuration of clock tree. */
PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;
PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
/*
* Main oscillator configuration block.
*/
{ {
/* Switching on RC. */ /* Setting Slow Clock source to OSCRC. */
uint32_t mor = SAMA_MOR_ONE | CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN; SCKC->SCKC_CR = 0U;
PMC->CKGR_MOR |= mor;
/* Enabling MOSCRC. */
PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN);
while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)) while (!(PMC->PMC_SR & PMC_SR_MOSCRCS))
; /* Waits until MOSCRC is stable.*/ ; /* Waits until MOSCRC is stable.*/
/* Switching Main Oscillator Source to MOSRC. */
mor = PMC->CKGR_MOR;
mor &= ~CKGR_MOR_MOSCSEL;
mor |= (SAMA_MOSC_MOSCRC | CKGR_MOR_KEY_PASSWD);
PMC->CKGR_MOR = mor;
/* Switching Master Clock source to Main Clock. */
mckr = PMC->PMC_MCKR;
mckr &= ~PMC_MCKR_CSS_Msk;
mckr |= PMC_MCKR_CSS_MAIN_CLK;
PMC->PMC_MCKR = mckr;
}
/*
* Main oscillator configuration block.
*/
{
mor = PMC->CKGR_MOR | CKGR_MOR_KEY_PASSWD;
#if SAMA_MOSCXT_ENABLED #if SAMA_MOSCXT_ENABLED
uint32_t mor = SAMA_MOR_ONE | CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN; mor |= CKGR_MOR_MOSCXTEN;
PMC->CKGR_MOR |= mor; PMC->CKGR_MOR = mor;
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)) while (!(PMC->PMC_SR & PMC_SR_MOSCXTS))
; /* Waits until MOSCXT is stable.*/ ; /* Waits until MOSCXT is stable.*/
#else
mor &= ~CKGR_MOR_MOSCXTEN;
PMC->CKGR_MOR = mor;
#endif #endif
/* Switching MOC source. */ /* Switching Main Clock source. */
mor = SAMA_MOR_ONE | SAMA_MOR_MOSCXTST | CKGR_MOR_KEY_PASSWD | mor &= ~CKGR_MOR_MOSCSEL;
CKGR_MOR_MOSCRCEN;
#if SAMA_MOSCXT_ENABLED
mor |= CKGR_MOR_MOSCXTEN;
#endif
mor |= SAMA_MOSC_SEL; mor |= SAMA_MOSC_SEL;
PMC->CKGR_MOR = mor; PMC->CKGR_MOR = mor;
/* Disabling unused sources. */ /* Eventually disabling MOSCRC. */
#if !SAMA_MOSCXT_ENABLED
PMC->CKGR_MOR &= ~ CKGR_MOR_MOSCXTEN;
#endif
#if !SAMA_MOSCRC_ENABLED #if !SAMA_MOSCRC_ENABLED
PMC->CKGR_MOR &= ~ CKGR_MOR_MOSCRCEN; PMC->CKGR_MOR &= ~ CKGR_MOR_MOSCRCEN;
#endif #endif
@ -120,9 +130,9 @@ PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
* PLLA configuration block. * PLLA configuration block.
*/ */
{ {
uint32_t pllar = SAMA_PLLA_ONE; pllar = SAMA_PLLA_ONE | CKGR_PLLAR_PLLACOUNT(0x3F);
#if SAMA_ACTIVATE_PLLA #if SAMA_ACTIVATE_PLLA
pllar |= CKGR_PLLAR_DIVA_BYPASS | SAMA_PLLA_MUL; pllar |= CKGR_PLLAR_DIVA_BYPASS | SAMA_PLLA_MUL;
#endif #endif
PMC->CKGR_PLLAR = pllar; /* Writing PLLA register. */ PMC->CKGR_PLLAR = pllar; /* Writing PLLA register. */
@ -136,18 +146,26 @@ PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
* Master clock configuration block. * Master clock configuration block.
*/ */
{ {
uint32_t mckr = SAMA_MCK_PRES | SAMA_MCK_MDIV | SAMA_MCK_SEL; mckr = PMC->PMC_MCKR;
mckr &= ~PMC_MCKR_CSS_Msk;
mckr |= SAMA_MCK_SEL;
PMC->PMC_MCKR = mckr;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY))
; /* Waits until MCK is stable. */
mckr = SAMA_MCK_PRES | SAMA_MCK_MDIV | SAMA_MCK_SEL;
#if SAMA_PLLADIV2_EN #if SAMA_PLLADIV2_EN
mckr |= PMC_MCKR_PLLADIV2; mckr |= PMC_MCKR_PLLADIV2;
#endif #endif
PMC->PMC_MCKR = mckr; PMC->PMC_MCKR = mckr;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) while (!(PMC->PMC_SR & PMC_SR_MCKRDY))
; /* Waits until MCK is stable. */ ; /* Waits until MCK is stable. */
/* Setting Slow clock source. */
SCKC->SCKC_CR = SAMA_OSC_SEL;
} }
/* Enabling write protection. */ /* Enabling write protection. */
PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN; PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;
#endif /* !SAMA_NO_INIT */ #endif /* !SAMA_NO_INIT */
} }