示例#1
0
/**
 * \brief Performs the low-level initialization of the chip.
 * This includes EFC and master clock configuration.
 * It also enable a low level on the pin NRST triggers a user reset.
 */
extern WEAK void LowLevelInit( void )
{
    uint32_t dwTimeout;

    /* Set 3 WS for Embedded Flash Access for 84 MHz */
    EFC0->EEFC_FMR = EEFC_FMR_FWS( 3 );
    EFC1->EEFC_FMR = EEFC_FMR_FWS( 3 );

    /* Initialize main oscillator */
    if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )  /* Main Oscillator Selection */
    {
        /* The Main Crystal Oscillator is enabled */
        PMC->CKGR_MOR = CKGR_MOR_KEY(0x37)
                      | CKGR_MOR_MOSCXTST(0x8) /* Main Crystal Oscillator Start-up Time: 1.4ms(datasheet) */
                      /* Specifies the number of Slow Clock cycles multiplied by 8 for the Main Crystal Oscillator start-up time */
                      | CKGR_MOR_MOSCRCEN      /* Main On-Chip RC Oscillator Enable */
                      | CKGR_MOR_MOSCXTEN;     /* Main Crystal Oscillator Enable */
                      /* MOSCSEL: The Main On-Chip RC Oscillator is selected */
                      /* MOSCRCF: The Fast RC Oscillator Frequency is at 4 MHz (default) */
                      /* CFDEN:  The Clock Failure Detector is disabled. */
        dwTimeout = 0;
        while ( !(PMC->PMC_SR & PMC_SR_MOSCXTS) && (dwTimeout++ < CLOCK_TIMEOUT) );
    }

    /* Switch to 3-20MHz Xtal oscillator */
    /* The Main Crystal Oscillator is enabled */
    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37)
                  | CKGR_MOR_MOSCXTST(0x8)  /* Main Crystal Oscillator Start-up Time: 1.4ms(datasheet) */
                  /* Specifies the number of Slow Clock cycles multiplied by 8 for the Main Crystal Oscillator start-up time */
                  | CKGR_MOR_MOSCRCEN       /* Main On-Chip RC Oscillator Enable */
                  | CKGR_MOR_MOSCXTEN       /* Main Crystal Oscillator Enable */
                  | CKGR_MOR_MOSCSEL;       /* The Main Crystal Oscillator is selected */
                  /* MOSCRCF: The Fast RC Oscillator Frequency is at 4 MHz (default) */
                  /* CFDEN:  The Clock Failure Detector is disabled. */
    dwTimeout = 0;
    /* Wait Main XTAL Oscillator Status */
    while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (dwTimeout++ < CLOCK_TIMEOUT));

    /* configure PLLA to 168 MHz */
    PMC->CKGR_PLLAR = CKGR_PLLAR_STUCKTO1
                    | CKGR_PLLAR_MULA(13)     /* PLLA Multiplier 12 MHz x (13+1) = 168 MHz */
                    | CKGR_PLLAR_PLLACOUNT(2) /* PLLA Counter 200µs(datasheet) */
                    | CKGR_PLLAR_DIVA(1);     /* Divider bypassed */
    dwTimeout = 0;
    /* Wait PLL A Lock Status */
    while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (dwTimeout++ < CLOCK_TIMEOUT));

    PMC->PMC_MCKR = PMC_MCKR_PRES_CLK_2        /* Selected clock divided by 2 => 168/2 = 84 MHz  */
                  | PMC_MCKR_CSS_MAIN_CLK;     /* Main Clock is selected */
    dwTimeout = 0;
    /* Wait Master Clock Status */
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (dwTimeout++ < CLOCK_TIMEOUT));

    PMC->PMC_MCKR = PMC_MCKR_PRES_CLK_2        /* Selected clock divided by 2 => 168/2 = 84 MHz  */
                  | PMC_MCKR_CSS_PLLA_CLK;   /* PLLA Clock is selected */
    dwTimeout = 0;
    /* Wait Master Clock Status */
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (dwTimeout++ < CLOCK_TIMEOUT));

}
示例#2
0
/**
 * \brief Performs the low-level initialization of the chip.
 * This includes EFC and master clock configuration.
 * It also enable a low level on the pin NRST triggers a user reset.
 */
extern WEAK void LowLevelInit( void )
{
    uint32_t timeout = 0;

    /* Set 3 FWS for Embedded Flash Access */
    EFC->EEFC_FMR = EEFC_FMR_FWS(3);


    /* Initialize main oscillator */
    if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
    {
        PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
        timeout = 0;
        while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));
    }

    /* Switch to 3-20MHz Xtal oscillator */
    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
    timeout = 0;
    while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));
    PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );

    /* Initialize PLLB */
    PMC->CKGR_PLLBR = BOARD_PLLBR;
    timeout = 0;
    while (!(PMC->PMC_SR & PMC_SR_LOCKB) && (timeout++ < CLOCK_TIMEOUT));

    /* Switch to main clock */
    PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );

    PMC->PMC_MCKR = BOARD_MCKR ;
    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
}
示例#3
0
void clock_init(void)
{
	uint32_t timeout;

	/* Disable watchdog */
	WDT_MR = BV(WDT_WDDIS);

	/* Set wait states for flash access, needed for higher CPU clock rates */
	EEFC0_FMR = EEFC_FMR_FWS(3);
#ifdef EEFC1_FMR
	EEFC1_FMR = EEFC_FMR_FWS(3);
#endif

	// Initialize main oscillator
	if (!(CKGR_MOR & BV(CKGR_MOR_MOSCSEL)))
	{
		CKGR_MOR = CKGR_MOR_KEY(0x37) | CKGR_MOR_MOSCXTST(0x8)
			| BV(CKGR_MOR_MOSCRCEN) | BV(CKGR_MOR_MOSCXTEN);
		timeout = CLOCK_TIMEOUT;
		while (!(PMC_SR & BV(PMC_SR_MOSCXTS)) && --timeout);
	}

	// Switch to external oscillator
	CKGR_MOR = CKGR_MOR_KEY(0x37) | CKGR_MOR_MOSCXTST(0x8)
		| BV(CKGR_MOR_MOSCRCEN) | BV(CKGR_MOR_MOSCXTEN) | BV(CKGR_MOR_MOSCSEL);
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_MOSCXTS)) && --timeout);

	// Initialize and enable PLL clock
	CKGR_PLLR = evaluate_pll() | BV(CKGR_PLLR_STUCKTO1) | CKGR_PLLR_PLLCOUNT(0x2);
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_LOCK)) && --timeout);

	PMC_MCKR = PMC_MCKR_CSS_MAIN_CLK;
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_MCKRDY)) && --timeout);

	PMC_MCKR = PMC_MCKR_CSS_PLL_CLK;
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_MCKRDY)) && --timeout);

	/* Enable clock on PIO for inputs */
	// TODO: move this in gpio_init() for better power management?
	pmc_periphEnable(PIOA_ID);
	pmc_periphEnable(PIOB_ID);
	pmc_periphEnable(PIOC_ID);
#ifdef PIOF_ID
	pmc_periphEnable(PIOD_ID);
	pmc_periphEnable(PIOE_ID);
	pmc_periphEnable(PIOF_ID);
#endif
}
示例#4
0
文件: cpu.c 项目: A-Paul/RIOT
/**
 * @brief Initialize the CPU, set IRQ priorities
 */
void cpu_init(void)
{
    /* disable the watchdog timer */
    WDT->WDT_MR |= WDT_MR_WDDIS;
    /* initialize the Cortex-M core */
    cortexm_init();

    /* setup the flash wait states */
    EFC0->EEFC_FMR = EEFC_FMR_FWS(CLOCK_FWS);
    EFC1->EEFC_FMR = EEFC_FMR_FWS(CLOCK_FWS);

    /* unlock write protect register for PMC module */
    PMC->PMC_WPMR = PMC_WPMR_WPKEY(WPKEY);

    /* activate the external crystal */
    PMC->CKGR_MOR = (CKGR_MOR_KEY(MORKEY) |
                     CKGR_MOR_MOSCXTST(XTAL_STARTUP) |
                     CKGR_MOR_MOSCXTEN |
                     CKGR_MOR_MOSCRCEN);
    /* wait for crystal to be stable */
    while (!(PMC->PMC_SR & PMC_SR_MOSCXTS));

    /* select crystal to clock the main clock */
    PMC->CKGR_MOR = (CKGR_MOR_KEY(MORKEY) |
                     CKGR_MOR_MOSCXTST(XTAL_STARTUP) |
                     CKGR_MOR_MOSCXTEN |
                     CKGR_MOR_MOSCRCEN |
                     CKGR_MOR_MOSCSEL);
    /* wait for main oscillator selection to be complete */
    while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));

    /* setup PLLA */
    PMC->CKGR_PLLAR = (CKGR_PLLAR_ONE |
                       CKGR_PLLAR_PLLACOUNT(PLL_CNT) |
                       CKGR_PLLAR_MULA(CLOCK_PLL_MUL) |
                       CKGR_PLLAR_DIVA(CLOCK_PLL_DIV));
    /* wait for PLL to lock */
    while (!(PMC->PMC_SR & PMC_SR_LOCKA));

    /* before switching to PLLA, we need to switch to main clock */
    PMC->PMC_MCKR = PMC_MCKR_CSS_MAIN_CLK;
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

    /* use PLLA as main clock source */
    PMC->PMC_MCKR = PMC_MCKR_CSS_PLLA_CLK;
    /* wait for master clock to be ready */
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

    /* trigger static peripheral initialization */
    periph_init();
}
示例#5
0
void clock_init(void)
{
	uint32_t timeout;

	/* Disable watchdog */
	WDT_MR = BV(WDT_WDDIS);

	/* Set 4 wait states for flash access, needed for higher CPU clock rates */
	EEFC_FMR = EEFC_FMR_FWS(3);

	// Select external slow clock
	if (!(SUPC_SR & BV(SUPC_SR_OSCSEL)))
	{
		SUPC_CR = BV(SUPC_CR_XTALSEL) | SUPC_CR_KEY(0xA5);
		while (!(SUPC_SR & BV(SUPC_SR_OSCSEL)));
	}

	// Initialize main oscillator
	if (!(CKGR_MOR & BV(CKGR_MOR_MOSCSEL)))
	{
		CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSC_COUNT | BV(CKGR_MOR_MOSCRCEN) | BV(CKGR_MOR_MOSCXTEN);
		timeout = CLOCK_TIMEOUT;
		while (!(PMC_SR & BV(PMC_SR_MOSCXTS)) && --timeout);
	}

	// Switch to external oscillator
	CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSC_COUNT | BV(CKGR_MOR_MOSCRCEN) | BV(CKGR_MOR_MOSCXTEN) | BV(CKGR_MOR_MOSCSEL);
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_MOSCSELS)) && --timeout);

	PMC_MCKR = (PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_MASK) | PMC_MCKR_CSS_MAIN_CLK;
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_MCKRDY)) && --timeout);

	// Initialize and enable PLL clock
	CKGR_PLLR = evaluate_pll() | BV(CKGR_PLLR_STUCKTO1) | CKGR_PLLR_PLLCOUNT(0x1);
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_LOCK)) && --timeout);

	PMC_MCKR = PMC_MCKR_CSS_MAIN_CLK;
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_MCKRDY)) && --timeout);

	PMC_MCKR = PMC_MCKR_CSS_PLL_CLK;
	timeout = CLOCK_TIMEOUT;
	while (!(PMC_SR & BV(PMC_SR_MCKRDY)) && --timeout);

	/* Enable clock on PIO for inputs */
	PMC_PCER = BV(PIOA_ID) | BV(PIOB_ID) | BV(PIOC_ID);
}
示例#6
0
/**
 * \brief Enable internal 4/8/12MHz fast RC as main clock input.
 *
 * \param freqSelect fast RC frequency (FAST_RC_4MHZ, FAST_RC_8MHZ, FAST_RC_12MHZ).
 */
extern void PMC_EnableIntRC4_8_12MHz(uint32_t freqSelect)
{
    uint32_t   read_MOR;

    /* Before switching MAIN OSC on RC OSC : enable it and don't disable
     * at the same time external crystal in case of if MAIN OSC is still using external crystal
     */

    read_MOR = PMC->CKGR_MOR;

    read_MOR &= ~CKGR_MOR_MOSCRCF_Msk;   /* reset MOSCRCF field in MOR register before select RC 12MHz */

    read_MOR |= (CKGR_MOR_KEY(0x37u) |
            freqSelect               |
            CKGR_MOR_MOSCXTEN        |
            CKGR_MOR_MOSCRCEN        |
            CKGR_MOR_MOSCXTST(PmcFastRcCnt));  /* enable external crystal - enable RC OSC */

    PMC->CKGR_MOR = read_MOR;

    while( !(PMC->PMC_SR & PMC_SR_MOSCRCS ) );  /* wait end of RC oscillator stabilization */
    while( !(PMC->PMC_SR & PMC_SR_MCKRDY) );


    read_MOR &= ~CKGR_MOR_MOSCSEL;               /* select internal fast RC */

    PMC->CKGR_MOR = read_MOR;

    while( !(PMC->PMC_SR & PMC_SR_MOSCSELS ) ); /* Wait end of Main Oscillator Selection */
    while( !(PMC->PMC_SR & PMC_SR_MCKRDY) );
}
示例#7
0
文件: mcu.c 项目: ishgum/Wacky-Racers
static void
mcu_xtal_mainck_start (void)
{
    PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) |
        CKGR_MOR_KEY (0x37) | CKGR_MOR_MOSCXTEN |
        CKGR_MOR_MOSCXTST (MCU_MAINCK_COUNT);
    
    /* Wait for the xtal oscillator to stabilize.  */
    while (! (PMC->PMC_SR & PMC_SR_MOSCXTS))
        continue;
    
    PMC->CKGR_MOR |= CKGR_MOR_KEY (0x37) | CKGR_MOR_MOSCSEL;

    /* Could check if xtal oscillator fails to start; say if xtal
       not connected.  */
}
/**
 * \brief Select internal 12M OSC.
 */
extern void PMC_SelectInt12M_Osc(void)
{
    uint32_t  count;
    /* switch from external OSC 12 MHz to internal RC 12 MHz*/
    /* enable internal RC 12 MHz */
    PMC->CKGR_MOR |= CKGR_MOR_MOSCRCEN | CKGR_MOR_KEY(0x37); 
    /* Wait internal 12 MHz RC Startup Time for clock stabilization (software loop) */
    for (count = 0; count < 0x100000; count++); 
    /* switch MAIN clock to internal RC 12 MHz */
    PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | CKGR_MOR_KEY(0x37);
    /* wait MAIN clock status change for internal RC 12 MHz selection*/
    while(PMC->PMC_SR & PMC_SR_MOSCSELS);
    /* in case where MCK is running on MAIN CLK */
    while(!(PMC->PMC_SR & PMC_SR_MCKRDY));
    /* disable external OSC 12 MHz   */
    PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | CKGR_MOR_KEY(0x37);
}
示例#9
0
/**
 * \brief Disable external oscilator.
 */
extern void PMC_DisableExtOsc(void)
{
    uint32_t   read_MOR;

    read_MOR = PMC->CKGR_MOR;

    read_MOR &= ~CKGR_MOR_MOSCXTEN; /* disable main xtal osc */
    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37u) | read_MOR;
    while( !(PMC->PMC_SR & PMC_SR_MCKRDY) );
}
示例#10
0
/**
 * \brief Select external OSC.
 */
extern void PMC_SelectExtBypassOsc(void)
{ 
    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) |
                    CKGR_MOR_MOSCRCEN | 
                    CKGR_MOR_MOSCXTST(0xFF) |
                    CKGR_MOR_MOSCXTBY;
    PMC->CKGR_MOR |= CKGR_MOR_MOSCSEL;
    /* wait MAIN clock status change for external OSC 12 MHz selection*/
    while(!(PMC->PMC_SR & PMC_SR_MOSCSELS));
}
示例#11
0
文件: pmc.c 项目: joh06937/playground
/**
 * \brief Enable Wait Mode. Enter condition: (WAITMODE bit = 1) +
 * (SLEEPDEEP bit = 0) + FLPM
 */
void pmc_enable_waitmode(void)
{
    uint32_t i;

    /* Flash in Deep Power Down mode */
    i = PMC->PMC_FSMR;
    i &= ~PMC_FSMR_FLPM_Msk;
    i |= ul_flash_in_wait_mode;
    PMC->PMC_FSMR = i;

    /* Clear SLEEPDEEP bit */
    SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk;

    /* Backup FWS setting and set Flash Wait State at 0 */
#if defined(ID_EFC)
    uint32_t fmr_backup;
    fmr_backup = EFC->EEFC_FMR;
    EFC->EEFC_FMR &= (uint32_t) ~ EEFC_FMR_FWS_Msk;
#endif
#if defined(ID_EFC0)
    uint32_t fmr0_backup;
    fmr0_backup = EFC0->EEFC_FMR;
    EFC0->EEFC_FMR &= (uint32_t) ~ EEFC_FMR_FWS_Msk;
#endif
#if defined(ID_EFC1)
    uint32_t fmr1_backup;
    fmr1_backup = EFC1->EEFC_FMR;
    EFC1->EEFC_FMR &= (uint32_t) ~ EEFC_FMR_FWS_Msk;
#endif

    /* Set the WAITMODE bit = 1 */
    PMC->CKGR_MOR |= CKGR_MOR_KEY(0x37u) | CKGR_MOR_WAITMODE;

    /* Waiting for Master Clock Ready MCKRDY = 1 */
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

    /* Waiting for MOSCRCEN bit cleared is strongly recommended
     * to ensure that the core will not execute undesired instructions
     */
    for (i = 0; i < 500; i++) {
        __NOP();
    }
    while (!(PMC->CKGR_MOR & CKGR_MOR_MOSCRCEN));

    /* Restore EFC FMR setting */
#if defined(ID_EFC)
    EFC->EEFC_FMR = fmr_backup;
#endif
#if defined(ID_EFC0)
    EFC0->EEFC_FMR = fmr0_backup;
#endif
#if defined(ID_EFC1)
    EFC1->EEFC_FMR = fmr1_backup;
#endif
}
示例#12
0
/**
 * \brief Disable internal 4/8/12MHz fast RC.
 */
extern void PMC_DisableIntRC4_8_12MHz(void)
{
    uint32_t   read_MOR;

    read_MOR = PMC->CKGR_MOR;

    read_MOR &= ~CKGR_MOR_MOSCRCF_Msk;   /* reset MOSCRCF field in MOR register */
    read_MOR &= ~CKGR_MOR_MOSCRCEN;      /* disable fast RC */
    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37u) | read_MOR;
    while( !(PMC->PMC_SR & PMC_SR_MCKRDY) );
}
示例#13
0
/**
 * \brief Select external OSC.
 */
extern void PMC_SelectExtOsc(void)
{ 
    /* switch from internal RC 12 MHz to external OSC 12 MHz */
    /* wait Main XTAL Oscillator stabilisation*/
    while(!(PMC->PMC_SR & PMC_SR_MOSCXTS));
    /* enable external OSC 12 MHz */
    PMC->CKGR_MOR |= CKGR_MOR_MOSCXTEN | CKGR_MOR_KEY(0x37); 
    /* wait Main CLK Ready */
    while(!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY)); 
    /* disable external OSC 12 MHz bypass */
    PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | CKGR_MOR_KEY(0x37); 
    /* switch MAIN clock to external OSC 12 MHz*/
    PMC->CKGR_MOR |= CKGR_MOR_MOSCSEL | CKGR_MOR_KEY(0x37); 
    /* wait MAIN clock status change for external OSC 12 MHz selection*/
    while(!(PMC->PMC_SR & PMC_SR_MOSCSELS));
    /* in case where MCK is running on MAIN CLK */
    while(!(PMC->PMC_SR & PMC_SR_MCKRDY));
    /* disable internal RC 12 MHz*/
    //PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN) | CKGR_MOR_KEY(0x37);
}
示例#14
0
//------CPU时钟初始化-----------------------------------------------------
//功能: 初始化CPU时钟,上电默认使用的是内部的晶振时钟,该函数将晶振源切换到
 //     外部调整时钟,后面将main clock时钟切换到PLLB分频后的时钟
//参数: 无
//返回: 无
//-----------------------------------------------------------------------
void cpu_clk_init(void)
{
    uint32_t timeout = 0;

    /* Initialize main oscillator */
    if ( !(SAM_PMC_REG->CKGR_MOR & CKGR_MOR_MOSCSEL) )
    {
    	SAM_PMC_REG->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT |
                                CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
        timeout = 0;
        while (!(SAM_PMC_REG->PMC_SR & PMC_SR_MOSCXTS) &&
                                    (timeout++ < CLOCK_TIMEOUT));
    }

    /* Switch to 3-20MHz Xtal oscillator */
    SAM_PMC_REG->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT |
                CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
    timeout = 0;
    while (!(SAM_PMC_REG->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));
    SAM_PMC_REG->PMC_MCKR = (SAM_PMC_REG->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) |
                                PMC_MCKR_CSS_MAIN_CLK;
    for ( timeout = 0; !(SAM_PMC_REG->PMC_SR & PMC_SR_MCKRDY) &&
                            (timeout++ < CLOCK_TIMEOUT) ; );

    /* Initialize PLLB */
    SAM_PMC_REG->CKGR_PLLBR = BOARD_PLLBR;
    timeout = 0;
    while (!(SAM_PMC_REG->PMC_SR & PMC_SR_LOCKB) && (timeout++ < CLOCK_TIMEOUT));

    /* Switch to main clock */
    SAM_PMC_REG->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
    for ( timeout = 0; !(SAM_PMC_REG->PMC_SR & PMC_SR_MCKRDY) &&
                                    (timeout++ < CLOCK_TIMEOUT) ; );

    SAM_PMC_REG->PMC_MCKR = BOARD_MCKR ;
    for ( timeout = 0; !(SAM_PMC_REG->PMC_SR & PMC_SR_MCKRDY) &&
                                    (timeout++ < CLOCK_TIMEOUT) ; );
}
示例#15
0
/**
 * \brief Disable all clocks.
 */
extern void PMC_DisableAllClocks(void)
{
    uint32_t   read_reg;

    PMC->PMC_SCDR = PMC_SCDR_PCK0 | PMC_SCDR_PCK1 | PMC_SCDR_PCK2;  /* disable PCK */

    _PMC_SwitchMck2MainClock();

    PMC->CKGR_PLLR = PMC->CKGR_PLLR & ~CKGR_PLLR_MUL_Msk;       /* disable PLL A */

    _PMC_SwitchMck2SlowClock();

    read_reg  =  PMC->CKGR_MOR;

    read_reg  =  (read_reg & ~CKGR_MOR_MOSCRCEN) | CKGR_MOR_KEY(0x37u);  /* disable RC OSC */

    PMC->CKGR_MOR = read_reg;

    PMC_DisableAllPeripherals(); /* disable all peripheral clocks */
}
/**
 * \brief Performs the low-level initialization of the chip.
 * This includes EFC and master clock configuration.
 * It also enable a low level on the pin NRST triggers a user reset.
 */
extern WEAK void LowLevelInit( void )
{
    uint32_t dwTimeout ;

    /* Set 2 WS for Embedded Flash Access */
	EFC0->EEFC_FMR = EEFC_FMR_FWS( 4 ) ;
	EFC1->EEFC_FMR = EEFC_FMR_FWS( 4 ) ;

    /* Initialize main oscillator */
    if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )  /* Main Oscillator Selection */
    {
        // 48MHz
        PMC->CKGR_MOR = CKGR_MOR_KEY(0x37)
                      | CKGR_MOR_MOSCXTST(0x8) /* Main Crystal Oscillator Start-up Time: 1.4ms(datasheet) */
                      | CKGR_MOR_MOSCRCEN      /* Main On-Chip RC Oscillator Enable */
                      | CKGR_MOR_MOSCXTEN;     /* Main Crystal Oscillator Enable */
                                               /* The Main On-Chip RC Oscillator is selected */
        dwTimeout = 0 ;
        while ( !(PMC->PMC_SR & PMC_SR_MOSCXTS) && (dwTimeout++ < CLOCK_TIMEOUT) ) ;
    }

    /* Switch to 3-20MHz Xtal oscillator */
    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37)
                  | CKGR_MOR_MOSCXTST(0x8)  /* Main Crystal Oscillator Start-up Time: 1.4ms(datasheet) */
                  | CKGR_MOR_MOSCRCEN       /* Main On-Chip RC Oscillator Enable */
                  | CKGR_MOR_MOSCXTEN       /* Main Crystal Oscillator Enable */
                  | CKGR_MOR_MOSCSEL;       /* The Main Crystal Oscillator is selected */
    dwTimeout = 0;
    /* Wait Main Oscillator Selection Status */
    while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (dwTimeout++ < CLOCK_TIMEOUT));

    PMC->PMC_MCKR = (PMC->PMC_MCKR & ~ (0x7UL <<  0)/*AT91C_PMC_CSS*/)
                   | PMC_MCKR_CSS_MAIN_CLK;     /* Main Clock is selected */
    dwTimeout = 0;
    /* Wait Master Clock Status */
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (dwTimeout++ < CLOCK_TIMEOUT));

    /* Initialize PLLA */
    PMC->CKGR_PLLAR = CKGR_PLLAR_STUCKTO1
                    | CKGR_PLLAR_MULA(13)      /* PLLA Multiplier */
                    | CKGR_PLLAR_PLLACOUNT(2) /* PLLA Counter 200µs(datasheet) */
                    | CKGR_PLLAR_DIVA(1);     /* Divider */
    dwTimeout = 0;
    /* Wait PLL A Lock Status */
    while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (dwTimeout++ < CLOCK_TIMEOUT));

    /* Initialize UTMI for USB usage, can be disabled if not using USB for the sake of saving power*/
    PMC->CKGR_UCKR |= CKGR_UCKR_UPLLCOUNT(3) /* UTMI PLL Start-up Time */
                    | CKGR_UCKR_UPLLEN;      /* UTMI PLL Enable */
    dwTimeout = 0;
    /* Wait UTMI PLL Lock Status */
    while (!(PMC->PMC_SR & PMC_SR_LOCKU) && (dwTimeout++ < CLOCK_TIMEOUT));

    /* Switch to PLLA*/
    PMC->PMC_MCKR = ((PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK) & ~(0x7UL <<  0)/*AT91C_PMC_CSS*/)
                    | PMC_MCKR_CSS_MAIN_CLK;  /* Main Clock is selected */
    dwTimeout = 0;
    /* Wait Master Clock Status */
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (dwTimeout++ < CLOCK_TIMEOUT));

    PMC->PMC_MCKR = PMC_MCKR_PRES_CLK_2       /* Selected clock divided by 2 */
                  | PMC_MCKR_CSS_PLLA_CLK;    /* PLLA Clock is selected */
    dwTimeout = 0;
    /* Wait Master Clock Status */
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (dwTimeout++ < CLOCK_TIMEOUT));
}
示例#17
0
/**
 * \brief Performs the low-level initialization of the chip.
 * This includes EFC and master clock configuration.
 * It also enable a low level on the pin NRST triggers a user reset.
 */
extern WEAK void LowLevelInit( void )
{
    uint8_t i;
    uint32_t _dwTimeout = 0;
    volatile uint32_t read = 0;
    
    if ((uint32_t)LowLevelInit < EBI_CS0_ADDR) /* Code not in external mem */
    {
        /* Switch to PLL + prescaler */
        read = PMC->PMC_MCKR;
        read &= ~(PMC_MCKR_CSS_Msk);
        read |= PMC_MCKR_CSS_MAIN_CLK;
        PMC->PMC_MCKR = read;
        while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
        
        PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | CKGR_MOR_MOSCXTST(64) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
        _dwTimeout = 0;
        while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (_dwTimeout++ < CLOCK_TIMEOUT));
        
        PMC->CKGR_PLLAR = 0;

        /* Initialize PLLA */
        PMC->CKGR_PLLAR = CKGR_PLLAR_STUCKTO1
                        | CKGR_PLLAR_MULA(199) 
                        | CKGR_PLLAR_OUTA(0)
                        | CKGR_PLLAR_PLLACOUNT(63)
                        | CKGR_PLLAR_DIVA(3);
        _dwTimeout = 0;
        while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (_dwTimeout++ < CLOCK_TIMEOUT));
        
        /* Wait for the master clock if it was already initialized */
        for ( _dwTimeout =  0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (_dwTimeout++ < CLOCK_TIMEOUT) ; );

        /* Switch to fast clock
        **********************/
        /* Switch to main oscillator + prescaler */
        read = PMC->PMC_MCKR;
        read &= ~(PMC_MCKR_MDIV_Msk);
        read |= (PMC_MCKR_MDIV_PCK_DIV3 | PMC_MCKR_PLLADIV2_DIV2);
        PMC->PMC_MCKR = read;
       
        /* Wait for the master clock if it was already initialized */
        for ( _dwTimeout =  0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (_dwTimeout++ < CLOCK_TIMEOUT) ; );
      
        /* Switch to main oscillator + prescaler */
        read = PMC->PMC_MCKR;
        read &= ~(PMC_MCKR_PRES_Msk);
        read |= PMC_MCKR_PRES_CLOCK;
        PMC->PMC_MCKR = read;

        /* Wait for the master clock if it was already initialized */
        for ( _dwTimeout =  0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (_dwTimeout++ < CLOCK_TIMEOUT) ; );

        /* Switch to PLL + prescaler */
        read = PMC->PMC_MCKR;
        read &= ~(PMC_MCKR_CSS_Msk);
        read |= PMC_MCKR_CSS_PLLA_CLK;
        PMC->PMC_MCKR = read;

        /* Wait for the master clock if it was already initialized */
        for ( _dwTimeout =  0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (_dwTimeout++ < CLOCK_TIMEOUT) ; );
    } 

    /* Initialize AIC */
    AIC->AIC_IDCR = 0xFFFFFFFF;
    AIC->AIC_SVR[0] = (unsigned int) defaultFiqHandler;

    for (i = 1; i < 31; i++) {
        AIC->AIC_SVR[i] = (unsigned int) defaultIrqHandler;
    }
    AIC->AIC_SPU = (unsigned int) defaultSpuriousHandler;

    /* Unstack nested interrupts */
    for (i = 0; i < 8 ; i++) {

        AIC->AIC_EOICR = 0;
    }

    /* Remap */
    BOARD_RemapRam();
    BOARD_ConfigureDdram();
}
示例#18
0
文件: drivers.cpp 项目: bratkov/tmos
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#define MHz(x) (x * 1000000)
extern "C" const PMC_DRIVER_INFO pmc_driver =
{
	{
		DRIVER_INFO_STUB,
		(DRV_ISR)PMC_ISR,
		(DRV_DCR)PMC_DCR,
		(DRV_DSR)PMC_DSR,
		PMC_IRQn,
		DRV_PRIORITY_KERNEL,
		ID_PMC
	},
	PMC,
	CKGR_MOR_CFDEN | CKGR_MOR_MOSCSEL | CKGR_MOR_KEY(0x37) |
	CKGR_MOR_MOSCXTST(255) |
	CKGR_MOR_MOSCXTEN,				//CFG_CKGR_MOR

//	CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCRCF_4MHZ | CKGR_MOR_KEY(0x37) |
//		CKGR_MOR_CFDEN,				//CFG_CKGR_MOR


	//PCK = 12000000 * (7+1) / 2  = 48 MHz
	//PCK = 12000000 * (7+1) / 1  = 96 MHz
	CKGR_PLLAR_STUCKTO1 | CKGR_PLLAR_MULA(7) | CKGR_PLLAR_PLLACOUNT(0x3f)
		| CKGR_PLLAR_DIVA(2),


	//PCK = 12000000 * (15+1) / 3 = 64 MHz
//	CKGR_PLLAR_STUCKTO1 | CKGR_PLLAR_MULA(15) | CKGR_PLLAR_PLLACOUNT(0x3f)
示例#19
0
static void SetupCpuClock ( void )
{
    // WARNING: This routine is called very early after a reset, so things
    // like the .data and .bss segments have probably not been initialised yet.

    // NOTE about JTAG debugging:
    //   You may have trouble connecting with a JTAG debugger before the clock
    //   has been setup. After a hardware reset, the core runs at 4 MHz by default.
    //   This routine switches to a 12 MHz clock (or 6 MHz after a soft reset), and
    //   then to the final 84 MHz. Even if your debugger can slow the JTAG clock down,
    //   I am not sure that the JTAG connection will always survive the clock changes.


    // Set the FWS (Flash Wait State in the Flash Mode Register) for both flash banks:
    // - FAM: Flash Access Mode: 0: 128-bit access in read Mode only, enhances access speed at the cost of power consumption.
    // - FRDY: Ready Interrupt Enable: 0: Flash Ready does not generate an interrupt.
    // - FWS: Flash Wait State: 4 + 1 = 5 wait states. See also constant CHIP_FREQ_FWS_3.
    //   The core will run at 84 MHz, and the CPU's VDDCORE pins are tied on the Arduino Due
    //   to signal VDDOUT -> VDDPLL. VDDIN has 3.3V, but I could not find any information on
    //   how to program the embedded Power Regulator.
    //   According to the data sheet, section "Embedded Flash Characteristics", if we run
    //   the CPU core at 84 MHz with VDDCORE set to 1.80 V, then we need 5 wait states,
    //   which matches our setting. However, should VDDCORE be 1.62 V, we are out of spec.
    EFC0->EEFC_FMR = EEFC_FMR_FWS(4);
    EFC1->EEFC_FMR = EEFC_FMR_FWS(4);


    const uint32_t SYS_BOARD_OSCOUNT = CKGR_MOR_MOSCXTST( 0x8 );   // Start-up time in Slow Clock cycles (multiplied by 8).
    const uint32_t SYS_CKGR_MOR_KEY_VALUE = CKGR_MOR_KEY( 0x37 );  // Key to unlock MOR register.

    // If the crystal oscillator has not already been selected into the Main Clock,
    // assume that it has not been enabled and stabilised yet, so do it here.

    if ( !( PMC->CKGR_MOR & CKGR_MOR_MOSCSEL ) )
    {
        PMC->CKGR_MOR = SYS_CKGR_MOR_KEY_VALUE |
                        SYS_BOARD_OSCOUNT |
                        CKGR_MOR_MOSCRCEN |  // Main On-Chip RC Oscillator Enable. This is probably the on-chip fast RC oscillator.
                                             // After a hardware reset we are running on it, so it probably must be kept enabled
                                             // until we are finished configuring the clocks.
                        CKGR_MOR_MOSCXTEN;   // Main Crystal Oscillator Enable.

        //  Wail until the PMC Status Register reports that the main XTAL oscillator is stabilised.
        while ( !(PMC->PMC_SR & PMC_SR_MOSCXTS) )
        {
        }
    }

    // Switch the Main Clock to the crystal oscillator. By default after a hardware reset, the on-chip fast RC oscillator runs at 4 MHz,
    // and the crystal oscillator on the Arduino Due runs at 12 MHz. So we are running the CPU faster here,
    // assuming we came here after a hardware reset.
    PMC->CKGR_MOR = SYS_CKGR_MOR_KEY_VALUE |
                    SYS_BOARD_OSCOUNT |
                    CKGR_MOR_MOSCRCEN |
                    CKGR_MOR_MOSCXTEN |
                    CKGR_MOR_MOSCSEL;

    // Wail until the PMC Status Register reports that the switch is complete.
    while (!(PMC->PMC_SR & PMC_SR_MOSCSELS))
    {
    }

    // Switch the Master Clock to the Main Clock, leaving other clock settings unchanged.
    // If we were on the PLL clock, remember that we cannot change the clock source and
    // the prescaler factor at the same time, so the resulting speed may be 12 MHz / 2 = 6 MHz for a short time.
    const uint32_t prevPmcMckr = PMC->PMC_MCKR;
    // - After a hard reset, prevPmcMckr is 1, which means that the Main Clock is selected, as expected.
    // - After a GDB 'load' command (which does a kind of soft reset), the value is 18 (0b10010),
    //   meaning that the PLLA clock divided by 2 was selected (which is what this routine does at the end).
    PMC->PMC_MCKR = (prevPmcMckr & ~uint32_t(PMC_MCKR_CSS_Msk) ) | PMC_MCKR_CSS_MAIN_CLK;

    // Wail until the PMC Status Register reports that the Master Clock is ready.
    while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) )
    {
    }

    // Generate a fast clock with the PLL by setting the PLLA Register in the PMC Clock Generator.
    PMC->CKGR_PLLAR = CKGR_PLLAR_ONE |  // Always 1.
                      CKGR_PLLAR_MULA(0xdUL) |  // Multiplier is 0xd + 1 = 0xe (14). The crystal oscillator freq. is 12 MHz,
                                                // so the resulting frequency is 12 MHz x 14 = 168 MHz (84 MHz x 2).
                      CKGR_PLLAR_PLLACOUNT(0x3fUL) |   // Some delay used during the switching.
                      CKGR_PLLAR_DIVA(0x1UL);   // 1 = The divider is bypassed.

    // Wail until the PMC Status Register reports that the PLL is locked.
    while ( !(PMC->PMC_SR & PMC_SR_LOCKA) )
    {
    }


    // We cannot switch directly to the PLL / 2 clock, we must set the prescaler factor first.
    const uint32_t PLL_FACTOR = PMC_MCKR_PRES_CLK_2;  // 168 MHz / prescaler of 2 = our target core frequency of 84 MHz.

    PMC->PMC_MCKR = PLL_FACTOR | PMC_MCKR_CSS_MAIN_CLK;

    // Wail until the PMC Status Register reports that the Master Clock is ready.
    while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) )
    {
    }


    // Switch the Master Clock to the PLLA / 2 clock.
    PMC->PMC_MCKR = PLL_FACTOR | PMC_MCKR_CSS_PLLA_CLK;

    // Wail until the PMC Status Register reports that the Master Clock is ready.
    while (!(PMC->PMC_SR & PMC_SR_MCKRDY))
    {
    }


    // You can check the Main Clock frequency by reading the CKGR_MCFR register like this:
    //   const uint16_t measuredMainClockFreqIn16SlowClockCycles = PMC->CKGR_MCFR & CKGR_MCFR_MAINF_Msk;
    // On the Arduino Due, the crystal oscillator freq. is 12 MHz, and the Slow Clock runs at 32 KHz,
    // that would be 375 Main Clock ticks for every Slow Clock tick.
    // In 16 Slow Clock ticks, we have 6000 Main Clock ticks then. On my board, the value read
    // is 6601, which is around 10 % off.
}