Exemple #1
0
/**
 * \brief Enable PLLA clock.
 *
 * \param mula PLLA multiplier.
 * \param pllacount PLLA counter.
 * \param diva Divider.
 */
void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva)
{
	/* first disable the PLL to unlock the lock */
	pmc_disable_pllack();

#if (SAM4C || SAM4CM || SAM4CP || SAMG)
	PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(diva) |
			CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula);
#else
	PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_DIVA(diva) |
			CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula);
#endif
	while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0);
}
/**
 * \brief Setup the microcontroller system.
 *
 * Initialize the System and update the SystemFrequency variable.
 */
void SystemInit( void )
{
  /* Set 6 FWS for Embedded Flash Access */
  EFC->EEFC_FMR = EEFC_FMR_FWS(5) | EEFC_FMR_CLOE ;

	/* Initialize main oscillator */
	if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
  {
  	PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTST(0x8U) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN ;
  	while ( !(PMC->PMC_SR & PMC_SR_MOSCXTS) ) ;
	}

	/* Switch to 3-20MHz Xtal oscillator */
	PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTST(0x8U) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
	while ( !(PMC->PMC_SR & PMC_SR_MOSCSELS) ) ;

	PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK ;
	while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) ) ;

	/* Initialize PLLA */
	PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0x13U) | CKGR_PLLAR_PLLACOUNT(0x3fU) | CKGR_PLLAR_DIVA(0x1U) ;
	while ( !(PMC->PMC_SR & PMC_SR_LOCKA) ) ;

	/* Switch to main clock */
	PMC->PMC_MCKR = ((PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK) & ~PMC_MCKR_CSS_Msk) |	PMC_MCKR_CSS_MAIN_CLK ;
	while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) ) ;

	/* Switch to PLLA */
	PMC->PMC_MCKR = PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK ;
	while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) ) ;

  SystemCoreClock=__SYSTEM_CLOCK_120MHZ ;
}
Exemple #3
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));

}
Exemple #4
0
/**
 * \brief Enable PLLA clock.
 *
 * \param mula PLLA multiplier.
 * \param pllacount PLLA counter.
 * \param diva Divider.
 */
void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva)
{
    /* first disable the PLL to unlock the lock!*/
    pmc_disable_pllack();

    PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_DIVA(diva) |
                      CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula);
    while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0);
}
Exemple #5
0
/**
 * \brief Enable PLLA clock.
 *
 * \param mula PLLA multiplier.
 * \param pllacount PLLA counter.
 * \param diva Divider.
 */
void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva)
{
    pmc_disable_pllack(); // Hardware BUG FIX : first disable the PLL to unlock the lock!
    // It occurs when re-enabling the PLL with the same parameters.

    PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_DIVA(diva) |
                      CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula);
    while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0);
}
/**
 * \brief Setup the microcontroller system.
 *
 * Initialize the System and update the System Frequency variable.
 */
void SystemInit( void )
{
  /* Set 6 FWS for Embedded Flash Access according to 120MHz configuration */
  EFC0->EEFC_FMR = EEFC_FMR_FWS(5)|EEFC_FMR_CLOE;

  /*
   * We are coming from a Hard Reset or Backup mode.
   * The core is clocked by Internal Fast RC @ 8MHz.
   * We intend to use the device @120MHz from external 32kHz oscillator.
   * Steps are:
   * 1- Activation of external 32kHz oscillator
   * 2- Set PLLA configuration
   * 3- Select the master clock and processor clock
   * 4- Select the programmable clocks (optional)
   */

  /* Step 1 - Activation of external 32kHz oscillator
   * Then, we wait the startup time to be finished by checking PMC_SR_MOSCXTS in PMC_SR.
   */
  SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL;
  while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL) && (PMC->PMC_SR & PMC_SR_OSCSELS)) ;

  /* Step 2 - Set PLLA configuration
   * The external oscillator is 32kHz. As we intend to clock the system @120MHz,
   * we need to multiply the oscillator frequency by 3662 (120000000/32768).
   * This can be done by setting CKGR_PLLAR_MULA to value 0xe4d (3662 - 1).
   * We set the maximum PLL Lock time to maximum in CKGR_PLLAR_PLLACOUNT.
   * Reference is product datasheet at 18.19.9 PMC Clock Generator PLLA Register.
   *
   * In case of, we could check first if PLLA is already active and put CKGR_PLLAR_MULA
   * prior to set new configuration (not done here).
   */
  PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(1ul) | CKGR_PLLAR_MULA(0xe4dul) | CKGR_PLLAR_PLLACOUNT(0x3ful);
  for ( ; (PMC->PMC_SR & PMC_SR_LOCKA) != PMC_SR_LOCKA ; );

  /* Step 3 - Select the master clock and processor clock
   * Source clock will be PLLA, instead of MAINCK from startup (8MHz Fast-RC).
   * We first update the prescaler value to one and then switch source to PLLA.
   */
  PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | PMC_MCKR_PRES_CLK_1;
  for ( ; !(PMC->PMC_SR & PMC_SR_MCKRDY););

  PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | PMC_MCKR_CSS_PLLA_CLK;
  for ( ; !(PMC->PMC_SR & PMC_SR_MCKRDY); );

  /*
   * Step 4 - Select the programmable clocks
   *
   * Output MCK on PCK1/pins PA17/PA21/PA30
   * Used to validate Master Clock settings
   */
//  PMC->PMC_SCER = PMC_SCER_PCK1 ;

  SystemCoreClock=__SYSTEM_CLOCK_120MHZ;
}
Exemple #7
0
/**
 * @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();
}
Exemple #8
0
/**
 * \brief Configure PLLA clock by giving MUL and DIV.
 *        Disable PLLA when 'mul' set to 0.
 *
 * \param mul  PLL multiplier factor.
 * \param div  PLL divider factor.
 */
void PMC_SetPllaClock(uint32_t mul, uint32_t div)
{
	if (mul != 0) {
		/* Init PLL speed */
		PMC->CKGR_PLLAR = CKGR_PLLAR_ONE 
			| CKGR_PLLAR_PLLACOUNT(DEFAUTL_PLLA_COUNT)
			| CKGR_PLLAR_MULA(mul - 1)
			| CKGR_PLLAR_DIVA(div);
		/* Wait for PLL stabilization */
		while( !(PMC->PMC_SR & PMC_SR_LOCKA) );
	} else {
		PMC->CKGR_PLLAR = CKGR_PLLAR_ONE; /* disable PLL A */
	}
}
void SAMA5D3X_ClockInit()
{
	PMC_SelectExt12M_Osc();
	PMC_SwitchMck2Main();
	PMC_SetPllA(CKGR_PLLAR_STUCKTO1 |
		CKGR_PLLAR_PLLACOUNT(0x3F) |
		CKGR_PLLAR_OUTA(0x0) |
		CKGR_PLLAR_MULA(65) |
		CKGR_PLLAR_DIVA(1),
		0x3u << 8);
	PMC_SetMckPllaDiv(PMC_MCKR_PLLADIV2_DIV2);
	PMC_SetMckPrescaler(PMC_MCKR_PRES_CLOCK);
	PMC_SetMckDivider(PMC_MCKR_MDIV_PCK_DIV3);
	PMC_SwitchMck2Pll();
}
Exemple #10
0
/**
 * \brief Enable PLLB clock.
 *
 * \param mulb PLLB multiplier.
 * \param pllbcount PLLB counter.
 * \param divb Divider.
 */
void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb)
{
	/* first disable the PLL to unlock the lock */
	pmc_disable_pllbck();

#if SAMG55
	PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(divb) |
		CKGR_PLLAR_PLLACOUNT(pllbcount) | CKGR_PLLAR_MULA(mulb);
#else
	PMC->CKGR_PLLBR =
			CKGR_PLLBR_DIVB(divb) | CKGR_PLLBR_PLLBCOUNT(pllbcount)
			| CKGR_PLLBR_MULB(mulb);
#endif
	while ((PMC->PMC_SR & PMC_SR_LOCKB) == 0);
}
Exemple #11
0
//-----------------------------------------------------------------------------
static void sys_init(void)
{
  // Disable watchdog
  WDT->WDT_MR = WDT_MR_WDDIS;

  // Set flash wait states to maximum for 150 MHz operation
  EFC->EEFC_FMR = EEFC_FMR_FWS(5) | EEFC_FMR_CLOE;

  // Enable 32 kHz Xtal
  SUPC->SUPC_CR |= SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL;

  // Enable 12 MHz Xtal
  PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTST(8) |
      CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
  while (!(PMC->PMC_SR & PMC_SR_MOSCXTS));
    
  PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTST(8) |
      CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
  while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));

  // Setup PLL (12 MHz * 25 = 300 MHz)
  PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(25-1) |
      CKGR_PLLAR_PLLACOUNT(0x3f) | CKGR_PLLAR_DIVA(1);
  while (!(PMC->PMC_SR & PMC_SR_LOCKA));

  // Switch main clock to PLL (two step process)
  PMC->PMC_MCKR = PMC_MCKR_CSS_MAIN_CLK | PMC_MCKR_MDIV_PCK_DIV2;
  while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

  PMC->PMC_MCKR = PMC_MCKR_CSS_PLLA_CLK | PMC_MCKR_MDIV_PCK_DIV2;
  while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

  // Enable PIOA, PIOB, PIOC, PIOD and PIOE
  PMC->PMC_PCER0 = PMC_PCER0_PID10 | PMC_PCER0_PID11 | PMC_PCER0_PID12 |
      PMC_PCER0_PID16 | PMC_PCER0_PID17;

  // Disable altenate functions on some pins
  MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4;

  // Enable interrupts
  asm volatile ("cpsie i");
}
Exemple #12
0
void reset_vector(void)
{
  g_stack[0] = 0; // need to put a reference in here to the stack array
                  // to make sure the linker brings it in. I'm sure there
                  // is a more elegant way to do this, but this seems to work
  EFC->EEFC_FMR = EEFC_FMR_FWS(5); // slow down flash for our blazing speed
  WDT->WDT_MR = WDT_MR_WDDIS; // disable watchdog for now
  // TODO: a block of code which can be ifdef'd in and out to source the
  // slow clock from a 32 kHz crystal rather than the (relatively) inaccurate
  // internal RC oscillator
  PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) |
                  PMC_MCKR_CSS_MAIN_CLK;
  PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD |
                  CKGR_MOR_MOSCXTST(0x10) | // startup time: slowclock*8*this
                  CKGR_MOR_MOSCRCEN | // keep main on-chip RC oscillator on !
                  CKGR_MOR_MOSCXTEN; // crystal oscillator enable (not select)
  while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)) { } // spin until stable
  while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) { } // spin until selected
  PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD |     // "password" hard-wired in logic
                  CKGR_MOR_MOSCXTST(0x10) | // startup time: slowclock*8*this
                  CKGR_MOR_MOSCRCEN | // keep main on-chip RC oscillator on !
                  CKGR_MOR_MOSCXTEN; // main crystal oscillator enable
  while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)) { } // busy wait
  // switch to main crystal oscillator
  PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD     |
                  CKGR_MOR_MOSCXTST(0x10) |
                  CKGR_MOR_MOSCRCEN       | // keep on-chip RC oscillator on !
                  CKGR_MOR_MOSCXTEN       |
                  CKGR_MOR_MOSCSEL;
  while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) ||
         !(PMC->PMC_SR & PMC_SR_MCKRDY)       ) { } // spin until stable
  PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) |
                  PMC_MCKR_CSS_MAIN_CLK;
  while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) { } // spin until selected
  // now, let's measure the frequency of the main crystal oscillator
  PMC->CKGR_MCFR = CKGR_MCFR_CCSS   | // measure the crystal oscillator
                   CKGR_MCFR_RCMEAS ; // start a new measurement
  // PLLA must output between 150 MHz and 500 MHz
  // board has 12 MHz crystal; let's multiply by 24 for 288 MHz PLL freq
  #define MUL 23
  PMC->CKGR_PLLAR = CKGR_PLLAR_ONE         | // per datasheet, must set 1<<29
                    CKGR_PLLAR_MULA(MUL)   | // pll = crystal * (mul+1)/div
                    CKGR_PLLAR_DIVA(1)     |
                    CKGR_PLLAR_PLLACOUNT(0x3f);
  while (!(PMC->PMC_SR & PMC_SR_LOCKA)) { } // spin until lock
  // don't use a divider... use the PLL output as CPU clock and divide CPU
  // clock by 2 to get 144 MHz for the master clock
  PMC->PMC_MCKR =  PMC_MCKR_CSS_MAIN_CLK | // | 
                   PMC_MCKR_MDIV_PCK_DIV2;
  while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) { } // spin until ready
  // finally, dividers are all set up, so let's switch CPU to the PLLA output
  PMC->PMC_MCKR =  PMC_MCKR_CSS_PLLA_CLK | 
                   PMC_MCKR_MDIV_PCK_DIV2;
  while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) { } // spin until selected
  // now we're running the CPU at 288 MHz and the system at 144 MHz

  uint32_t *pSrc, *pDest;
  // set up data segment
  pSrc = &_etext;
  pDest = &_srelocate;
  if (pSrc != pDest)
    for (; pDest < &_erelocate; )
      *pDest++ = *pSrc++;
  // set up bss segment
  for (pDest = &_szero; pDest < &_ezero; )
    *pDest++ = 0;
  // set vector table base address (if needed)
  pSrc = (uint32_t *)&_sfixed;
  SCB->VTOR = ( (uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk ); // 7 LSB's are 0
  if (((uint32_t)pSrc >= IRAM_ADDR) && ((uint32_t)pSrc < IRAM_ADDR+IRAM_SIZE))
    SCB->VTOR |= 1 << 29; // TBLBASE bit 
  enable_fpu();
  __libc_init_array();
  static char metal_stdout_buf[1024];
  setvbuf(stdout, metal_stdout_buf, _IOLBF, sizeof(metal_stdout_buf));
  systime_init();
  led_init();
  console_init();
  main();
  while (1) { } // hopefully we never get here...
}
/**
 * \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));
}
Exemple #14
0
/**
 * @brief   SAMA clocks and PLL initialization.
 * @note    All the involved constants come from the file @p board.h.
 * @note    This function should be invoked just after the system reset.
 *
 * @special
 */
void sama_clock_init(void) {
#if !SAMA_NO_INIT
  uint32_t mor, pllar, mckr, mainf;
  /* Disabling PMC write protection. */
  pmcDisableWP();

  /* 
   * Enforcing the reset default configuration of clock tree. 
   */  
  /* Setting Slow Clock source to OSCRC. */
  SCKC->SCKC_CR = 0U;

  /* Enabling MOSCRC. */
  PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN);
  while (!(PMC->PMC_SR & PMC_SR_MOSCRCS))
    ;                                       /* Waits until MOSCRC is stable.*/

  /* Switching Main Oscillator Source to MOSRC. */
  mor = PMC->CKGR_MOR | CKGR_MOR_KEY_PASSWD;
  mor &= ~CKGR_MOR_MOSCSEL;
  mor |= SAMA_MOSC_MOSCRC;
  PMC->CKGR_MOR = mor;

  while (!(PMC->PMC_SR & PMC_SR_MOSCSELS))
    ;                                       /* Waits until MOSCSEL has changed.*/

  /* 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;

  while (!(PMC->PMC_SR & PMC_SR_MCKRDY))
    ;                                       /* Waits until Master Clock is stable.*/

  /* Counter Clock Source to MOSCRC. */
  PMC->CKGR_MCFR &= ~CKGR_MCFR_CCSS;


  /*
   * Main oscillator configuration block.
   */
  /* Setting Slow clock source. */
  SCKC->SCKC_CR = SAMA_OSC_SEL;
  while ((SAMA_OSC_SEL && !(PMC->PMC_SR & PMC_SR_OSCSELS)) ||
        (!SAMA_OSC_SEL &&  (PMC->PMC_SR & PMC_SR_OSCSELS)))
    ;                                       /* Waits until MOSCxxS switch is done.*/
  mor = PMC->CKGR_MOR | CKGR_MOR_KEY_PASSWD;
#if SAMA_MOSCXT_ENABLED
  mor |= CKGR_MOR_MOSCXTEN;
  PMC->CKGR_MOR = mor;
  while (!(PMC->PMC_SR & PMC_SR_MOSCXTS))
    ;                                       /* Waits until MOSCXT is stable.*/
  /* Counter Clock Source to MOSCXT. */
  PMC->CKGR_MCFR |= CKGR_MCFR_CCSS;
#else
  mor &= ~CKGR_MOR_MOSCXTEN;
  PMC->CKGR_MOR = mor;
#endif

  PMC->CKGR_MCFR |= CKGR_MCFR_RCMEAS;
  while (!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY))
    ;
  mainf = CKGR_MCFR_MAINF(PMC->CKGR_MCFR);
  /*
   * @TODO: add mainf check and eventual clock source fallback. This mechanism
   * should be activable through a switch.
   */
  (void)mainf;

  /* Switching Main Clock source. */
  mor &= ~CKGR_MOR_MOSCSEL;
  mor |= SAMA_MOSC_SEL;
  PMC->CKGR_MOR = mor;

  /* Eventually disabling MOSCRC. */
#if !SAMA_MOSCRC_ENABLED
  PMC->CKGR_MOR &= ~ CKGR_MOR_MOSCRCEN;
#endif

/*
 * PLLA configuration block.
 */
  pllar = SAMA_PLLA_ONE | CKGR_PLLAR_PLLACOUNT(0x3F);
#if SAMA_ACTIVATE_PLLA
  pllar |= CKGR_PLLAR_DIVA_BYPASS | SAMA_PLLA_MUL;
#endif
  PMC->CKGR_PLLAR = pllar;                  /* Writing PLLA register.       */

#if SAMA_ACTIVATE_PLLA
  while (!(PMC->PMC_SR & PMC_SR_LOCKA))
    ;                                       /* Waits until PLLA is locked.  */
#endif

/*
 * Master clock configuration block.
 */
  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 &= ~(PMC_MCKR_PRES_Msk | PMC_MCKR_MDIV_Msk | PMC_MCKR_H32MXDIV);
  
  /* Note that prescaler and divider must be changed with separate accesses.*/
  mckr |= SAMA_MCK_PRES;
  mckr |= SAMA_MCK_MDIV;
  mckr |= SAMA_H64MX_H32MX_DIV;
#if SAMA_PLLADIV2_EN
  mckr |= PMC_MCKR_PLLADIV2;
#else
  mckr &= ~PMC_MCKR_PLLADIV2;
#endif
  PMC->PMC_MCKR = mckr;
  while (!(PMC->PMC_SR & PMC_SR_MCKRDY))
    ;                                       /* Waits until MCK is stable.   */

  /* Enabling write protection.  */
  pmcEnableWP();

#endif /* !SAMA_NO_INIT */
}
Exemple #15
0
/** Set up the main clock (MAINCK), PLL clock, and master clock (MCK).   */
static int
mcu_clock_init (void)
{
    /* To minimize the power required to start up the system, the main
       oscillator is disabled after reset and slow clock is
       selected. 

       There are four clock sources: SLCK (the 32 kHz internal RC
       oscillator or 32 kHz external crystal slow clock), MAINCK (the
       external 3-20 MHz crystal or internal 4/8/12 MHz internal fast
       RC oscillator main clock), PLLACK, and PLLBCK.  The two PLL
       clocks are the outputs of the the phase locked loop driven by
       MAINCK).  One of these four clock sources can be fed to a
       prescaler (with divisors 2^0 ... 2^6) to drive MCK (master
       clock).
       
       The main oscillator (external crystal) can range from 3--20 MHz.
       The PLL frequency can range from 80--240 MHz.

       Here we assume that an external crystal is used for the MAINCK
       and this is multiplied by PLLA to drive MCK.

       PLLB is not touched here.  Currently, the USB clock is derived
       from PLLA; this restricts MCK to be a multiple of 48 MHz
       required for the USB clock.  This restriction could be relaxed
       using PLLB for the USB.

       Initially MCK is driven from the 4 MHz internal fast RC oscillator.
    */

    /* Hack to handle JTAG reset when the PLLA is still operating.
       Without this call to mcu_reset, the PLLA is not enabled after
       every second reset.  */
    if ((PMC->PMC_MCKR & PMC_MCKR_CSS_Msk) == PMC_MCKR_CSS_PLLA_CLK)
        mcu_reset ();

    /* Start xtal oscillator and select as MAINCK.  */
    mcu_xtal_mainck_start ();
    
    /* Select MAINCK for MCK (this should already be selected).  */
    PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk))
        | PMC_MCKR_CSS_MAIN_CLK;
    if (!mcu_mck_ready_wait ())
        return 0;

    /* Set prescaler to 2.  */
    PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | PMC_MCKR_PRES_CLK_2;
    if (!mcu_mck_ready_wait ())
        return 0;

    /* Could disable internal fast RC oscillator here.  */


    /* Disable PLLA if it is running and reset fields.  */
    PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA (0);

    /* Configure and start PLLA.  The PLL start delay is MCU_PLL_COUNT
       SLCK cycles.  Note, PLLA (but not PLBB) needs the mysterious
       bit CKGR_PLLAR_ONE set.  */
    PMC->CKGR_PLLAR = CKGR_PLLAR_MULA (MCU_PLL_MUL - 1) 
        | CKGR_PLLAR_DIVA (MCU_PLL_DIV) 
        | CKGR_PLLAR_PLLACOUNT (MCU_PLL_COUNT) | CKGR_PLLAR_ONE;

    /* Wait for PLLA to start up.  */
    while (! (PMC->PMC_SR & PMC_SR_LOCKA))
        continue;

    /* Switch to PLLA_CLCK for MCK.  */
    PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) 
        | PMC_MCKR_CSS_PLLA_CLK;
    if (!mcu_mck_ready_wait ())
        return 0;
    
    return 1;
}
Exemple #16
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();
}
Exemple #17
0
		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)
//		| CKGR_PLLAR_DIVA(3),



	{
		32768,		//freq for slow clk
		MHz(12),	// freq for main clk
		MHz(48),	//freq for PLLA
		MHz(96)		//freq for PLLB
	},
/**
 * \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 i;
    if ((uint32_t)LowLevelInit < DDR_CS_ADDR) /* Code not in external mem */ {
        PMC_SelectExt12M_Osc();
        PMC_SwitchMck2Main();
        PMC_SetPllA( CKGR_PLLAR_STUCKTO1 |
                     CKGR_PLLAR_PLLACOUNT(0x3F) |
                     CKGR_PLLAR_OUTA(0x0) |
                     CKGR_PLLAR_MULA(65) |
                     CKGR_PLLAR_DIVA(1),
                     0x3u << 8);
        PMC_SetMckPllaDiv(PMC_MCKR_PLLADIV2_DIV2);
        PMC_SetMckPrescaler(PMC_MCKR_PRES_CLOCK);
        PMC_SetMckDivider(PMC_MCKR_MDIV_PCK_DIV3);
        PMC_SwitchMck2Pll();
    }

#if 0
    uint32_t abcdsr;
    /* Configure PCK1 to measure MCK */
    PIOD->PIO_IDR = (1<<31);
    abcdsr = PIOD->PIO_ABCDSR[0];
    PIOD->PIO_ABCDSR[0] = ((1<<31) | abcdsr);
    abcdsr = PIOD->PIO_ABCDSR[1];
    PIOD->PIO_ABCDSR[1] &= (~(1<<31) & abcdsr);
    PIOD->PIO_PDR = (1<<31);

    /* Disable programmable clock 1 output */
    REG_PMC_SCDR = PMC_SCER_PCK1;
    /* Enable the DAC master clock */
    PMC->PMC_PCK[1] = PMC_PCK_CSS_MCK_CLK | PMC_PCK_PRES_CLOCK;
    /* Enable programmable clock 1 output */
    REG_PMC_SCER = PMC_SCER_PCK1;
    /* Wait for the PCKRDY1 bit to be set in the PMC_SR register*/
    while ((REG_PMC_SR & PMC_SR_PCKRDY1) == 0);
#endif

    /* select FIQ */
    AIC->AIC_SSR = 0;
    AIC->AIC_SVR = (unsigned int) defaultFiqHandler;

    for (i = 1; i < 31; i++)
    {
        AIC->AIC_SSR = i;
        AIC->AIC_SVR =  (unsigned int) defaultIrqHandler;
    }

    AIC->AIC_SPU =  (unsigned int) defaultSpuriousHandler;

    /* Disable all interrupts */
    for (i = 1; i < 31; i++)
    {
        AIC->AIC_SSR  = i;
        AIC->AIC_IDCR = 1 ;
    }
    /* Clear All pending interrupts flags */
    for (i = 1; i < 31; i++)
    {
        AIC->AIC_SSR  = i;
        AIC->AIC_ICCR = 1 ;
    }
    /* Perform 8 IT acknoledge (write any value in EOICR) */
    for (i = 0; i < 8 ; i++)
    {
        AIC->AIC_EOICR = 0;
    }
    /* Remap */
    BOARD_RemapRam();
}
/**
 * \brief Setup the microcontroller system.
 *
 * Initialize the System and update the SystemFrequency variable.
 */
void SystemInit( void )
{
{
  /* Set 6 FWS for Embedded Flash Access according to 120MHz configuration */
  EFC0->EEFC_FMR = EEFC_FMR_FWS(5)|EEFC_FMR_CLOE;
#if defined(EFC1) // Only valid for products with two flash banks
  EFC1->EEFC_FMR = EEFC_FMR_FWS(5)|EEFC_FMR_CLOE;
#endif // EFC1

  /*
   * We are coming from a Hard Reset or Backup mode.
   * The core is clocked by Internal Fast RC @ 4MHz.
   * We intend to use the device @120MHz from external Oscillator.
   * Steps are (cf datasheet chapter '29.14 Programming Sequence'):
   * 1- Activation of external oscillator
   * 2- Switch the MAINCK to the main crystal oscillator
   * 3- Wait for the MOSCSELS to be set
   * 4- Check the main clock frequency
   * 5- Set PLLx and Divider
   * 6- Select the master clock and processor clock
   * 7- Select the programmable clocks (optional)
   */

  /* Step 1 - Activation of external oscillator
   * As we are clocking the core from internal Fast RC, we keep the bit CKGR_MOR_MOSCRCEN.
   * Main Crystal Oscillator Start-up Time (CKGR_MOR_MOSCXTST) is set to maximum value.
   * Then, we wait the startup time to be finished by checking PMC_SR_MOSCXTS in PMC_SR.
   */
  PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTST(0xfful) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
  for ( ; (PMC->PMC_SR & PMC_SR_MOSCXTS) != PMC_SR_MOSCXTS ; );

  /* Step 2 - Switch the MAINCK to the main crystal oscillator
   * We add the CKGR_MOR_MOSCSEL bit.
   * Then we wait for the selection to be done by checking PMC_SR_MOSCSELS in PMC_SR.
   */
  PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTST(0xfful) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
  /* Step 3 - Wait for the MOSCSELS to be set */
  for ( ; (PMC->PMC_SR & PMC_SR_MOSCSELS) != PMC_SR_MOSCSELS ; );

  /* Step 4 - Check the main clock frequency */
  /* As written in the DS, we could check the MAINF value here (0x18a2) */

  /* Step 5 - Set PLLx and Divider
   * The external oscillator is 12MHz. As we intend to clock the system @120MHz,
   * we need to multiply the oscillator frequency by 10.
   * This can be done by setting MULx to value 9 and DIV to 1.
   * We set the maximum PLL Lock time to maximum in CKGR_PLLAR_PLLACOUNT.
   */
  //PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | (CKGR_PLLAR_MULA(0x1dul) | CKGR_PLLAR_DIVA(3ul) | CKGR_PLLAR_PLLACOUNT(0x1ul));
  PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | (CKGR_PLLAR_MULA(0x9ul) | CKGR_PLLAR_DIVA(1ul) | CKGR_PLLAR_PLLACOUNT(0x3ful));
  for ( ; (PMC->PMC_SR & PMC_SR_LOCKA) != PMC_SR_LOCKA ; );

  /* Step 6 - Select the master clock and processor clock
   * Source for MasterClock will be PLLA output (PMC_MCKR_CSS_PLLA_CLK), without frequency division.
   */
  PMC->PMC_MCKR = PMC_MCKR_PRES_CLK_1 | PMC_MCKR_CSS_PLLA_CLK;
  for ( ; (PMC->PMC_SR & PMC_SR_MCKRDY) != PMC_SR_MCKRDY ; );

  /*
   * Step 7 - Select the programmable clocks
   * *
   * Output MCK on PCK1/pin PA17
   * Used to validate Master Clock settings
   */
//  PMC->PMC_SCER = PMC_SCER_PCK1 ;

  SystemCoreClock=__SYSTEM_CLOCK_120MHZ;
}

}
Exemple #20
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.
}
// ペリフェラルの初期化
// RTX RTOSの開始前に呼ばれる
extern "C" void init(void){
	// WDTを無効にする
	WDT->WDT_MR		= WDT_MR_WDIDLEHLT | WDT_MR_WDDBGHLT | (0xFFF << WDT_MR_WDD_Pos) | WDT_MR_WDDIS | (0xFFF << WDT_MR_WDV_Pos);
	
	// RSWDTは標準で無効になっている
	
	// BODリセットは標準で有効になっている
	
	// 1度、強制的にリセットする(OpenOCDによるデバッグのため)
	if (RESET_GPBR == 0){
		RESET_GPBR = 1;
		RSTC->RSTC_CR = RSTC_CR_KEY_PASSWD | RSTC_CR_PERRST | RSTC_CR_PROCRST;
	}else{
		RESET_GPBR = 0;
	}
	
	// FPUを有効にする
	SCB->CPACR		= 0x00F00000;
	
	// キャッシュを有効にする(キャッシュはROMとFlash領域のみ有効)
	//CMCC->CMCC_CTRL	= CMCC_CTRL_CEN;
	
	// フラッシュのウェイト数を設定
	EFC->EEFC_FMR	= EEFC_FMR_CLOE | EEFC_FMR_FWS(5);	// 最大129MHz
	
	// システムクロックを設定
	// SLCK=32kHz, MAINCK=12MHz, PLLACK=240MHz, USB_48M=48MHz, MCK=120MHz
	PMC->CKGR_MOR	= CKGR_MOR_MOSCSEL | CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCF_4_MHz | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTBY;
	while(~PMC->PMC_SR & PMC_SR_MOSCSELS);
	PMC->CKGR_MOR	= CKGR_MOR_MOSCSEL | CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY;
	PMC->CKGR_PLLAR	= CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(20) | CKGR_PLLAR_PLLACOUNT(16) | CKGR_PLLAR_DIVA(1);
	while(~PMC->PMC_SR & PMC_SR_LOCKA);
	PMC->PMC_USB	= PMC_USB_USBDIV(5 - 1);
	PMC->PMC_MCKR	= PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_MAIN_CLK;
	while(~PMC->PMC_SR & PMC_SR_MCKRDY);
	PMC->PMC_MCKR	= PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK;
	while(~PMC->PMC_SR & PMC_SR_MCKRDY);
	
	// クロック供給を有効にする
	// 31:AFEC1, 30:AFEC0, 23:TC2, 22:TC1, 21:TC0, 20:DMAC, 12:PIOD, 10:PIOB, 9:PIOA, 7:UART0
	// 36:PWM, 35:UDP
	PMC->PMC_PCER0	= PMC_PCER0_PID31 | PMC_PCER0_PID30 | PMC_PCER0_PID23 | PMC_PCER0_PID22 | PMC_PCER0_PID21 | PMC_PCER0_PID20 | PMC_PCER0_PID12 | PMC_PCER0_PID10 | PMC_PCER0_PID9 | PMC_PCER0_PID7;
	PMC->PMC_PCER1	= PMC_PCER1_PID36 | PMC_PCER1_PID35;
	PMC->PMC_SCER	= PMC_SCER_UDP;
	
	// NVICのベクターをRAMに移動
	NVIC_Migration();
	
	// I/Oピンの初期化
	clDigitalIOInitializer IOInitializer;
	IOInitializer.Set(PIN_HOST_TX, DIR_IN, OUT_LOW, PINMODE_PU);
	IOInitializer.Set(PIN_HOST_RX, DIR_OUT, OUT_HIGH);
	IOInitializer.Set(PIN_CAM1_CLK, DIR_OUT, OUT_LOW);
	IOInitializer.Set(PIN_CAM2_CLK, DIR_OUT, OUT_LOW);
	IOInitializer.Set(PIN_CAM1_SI, DIR_OUT, OUT_LOW);
	IOInitializer.Set(PIN_CAM2_SI, DIR_OUT, OUT_LOW);
	IOInitializer.Set(PIN_CAM1_A0P, DIR_IN, OUT_LOW, PINMODE_PU);
	IOInitializer.Set(PIN_CAM2_A0P, DIR_IN, OUT_LOW, PINMODE_PU);
	IOInitializer.Set(PIN_USB_VBUS, DIR_IN, OUT_LOW);
	IOInitializer.Set(PIN_nSW1, DIR_IN, OUT_LOW, PINMODE_PU);
	IOInitializer.Set(PIN_LED1, DIR_OUT, OUT_LOW);
	IOInitializer.Set(PIN_LED_ENABLE, DIR_OUT, OUT_LOW);
	IOInitializer.Mux(PIN_HOST_TX, PINMUX_A, PIO_DISABLE);
	IOInitializer.Mux(PIN_HOST_RX, PINMUX_A, PIO_DISABLE);
	IOInitializer.Mux(PIN_CAM1_CLK, PINMUX_A, PIO_DISABLE);
	IOInitializer.Mux(PIN_CAM2_CLK, PINMUX_B, PIO_DISABLE);
	IOInitializer.Apply();
	
	/* OSリソースの作成を伴わないデバイスインスタンスの初期化を行う */
	
	
	
	
	
}