re-fix xtalless, add cache & freq fix

This commit is contained in:
ladyada 2018-05-05 16:27:29 -04:00 committed by dean
parent b517015248
commit 19e4a449f4
2 changed files with 145 additions and 137 deletions

View file

@ -325,12 +325,12 @@ adafruit_itsybitsy_m4.upload.use_1200bps_touch=true
adafruit_itsybitsy_m4.upload.wait_for_upload_port=true
adafruit_itsybitsy_m4.upload.native_usb=true
adafruit_itsybitsy_m4.build.mcu=cortex-m4
adafruit_itsybitsy_m4.build.f_cpu=48000000L
adafruit_itsybitsy_m4.build.f_cpu=120000000L
adafruit_itsybitsy_m4.build.usb_product="Adafruit ItsyBitsy M4"
adafruit_itsybitsy_m4.build.usb_manufacturer="Adafruit LLC"
adafruit_itsybitsy_m4.build.board=ITSYBITSY_M4
adafruit_itsybitsy_m4.build.core=arduino
adafruit_itsybitsy_m4.build.extra_flags=-D__SAMD51G19A__ -D__SAMD51__ {build.usb_flags} -D__FPU_PRESENT -DARM_MATH_CM4 -DCRYSTALLESS -mfloat-abi=hard -mfpu=fpv4-sp-d16
adafruit_itsybitsy_m4.build.extra_flags=-D__SAMD51G19A__ -DADAFRUIT_ITSYBITSY_M4_EXPRESS -D__SAMD51__ {build.usb_flags} -D__FPU_PRESENT -DARM_MATH_CM4 -DCRYSTALLESS -mfloat-abi=hard -mfpu=fpv4-sp-d16
adafruit_itsybitsy_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld
adafruit_itsybitsy_m4.build.openocdscript=openocd_scripts/arduino_zero.cfg
adafruit_itsybitsy_m4.build.variant=itsybitsy_m4
@ -340,6 +340,10 @@ adafruit_itsybitsy_m4.build.pid=0x802B
adafruit_itsybitsy_m4.bootloader.tool=openocd
adafruit_itsybitsy_m4.bootloader.file=metroM4/bootloader.bin
adafruit_itsybitsy_m4.compiler.arm.cmsis.ldflags="-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16
adafruit_itsybitsy_m4.menu.cache.on=Enabled
adafruit_itsybitsy_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE
adafruit_itsybitsy_m4.menu.cache.off=Disabled
adafruit_itsybitsy_m4.menu.cache.off.build.cache_flags=
# Adafruit Feather M4 (SAMD51)

View file

@ -57,129 +57,133 @@ void SystemInit( void )
#if defined(__SAMD51__)
NVMCTRL->CTRLA.reg |= NVMCTRL_CTRLA_RWS(0);
#if defined(CRYSTALLESS)
#ifndef CRYSTALLESS
/* ----------------------------------------------------------------------------------------------
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
*/
OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_CGM_XT | OSC32KCTRL_XOSC32K_XTALEN;
while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){
/* Wait for oscillator to be ready */
}
#else // has crystal
#endif //CRYSTALLESS
/* ----------------------------------------------------------------------------------------------
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
*/
OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_CGM_XT | OSC32KCTRL_XOSC32K_XTALEN;
while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){
/* Wait for oscillator to be ready */
}
#endif //CRYSTALLESS
//software reset
GCLK->CTRLA.bit.SWRST = 1;
while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_SWRST ){
/* wait for reset to complete */
}
/* ----------------------------------------------------------------------------------------------
* 2) Put XOSC32K as source of Generic Clock Generator 3
*/
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_XOSC32K].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_XOSC32K) | //generic clock gen 3
GCLK_GENCTRL_GENEN;
while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL3 ){
/* Wait for synchronization */
}
#ifndef CRYSTALLESS
/* ----------------------------------------------------------------------------------------------
* 2) Put XOSC32K as source of Generic Clock Generator 3
*/
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_XOSC32K].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_XOSC32K) | //generic clock gen 3
GCLK_GENCTRL_GENEN;
#else
/* ----------------------------------------------------------------------------------------------
* 2) Put OSCULP32K as source of Generic Clock Generator 3
*/
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_XOSC32K].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN; //generic clock gen 3
#endif
/* ----------------------------------------------------------------------------------------------
* 3) Put Generic Clock Generator 3 as source for Generic Clock Gen 0 (DFLL48M reference)
*/
GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN;
/* ----------------------------------------------------------------------------------------------
* 4) Enable DFLL48M clock
*/
while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL3 ){
/* Wait for synchronization */
}
/* ----------------------------------------------------------------------------------------------
* 3) Put Generic Clock Generator 3 as source for Generic Clock Gen 0 (DFLL48M reference)
*/
GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN;
/* ----------------------------------------------------------------------------------------------
* 4) Enable DFLL48M clock
*/
while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL0 ){
/* Wait for synchronization */
}
/* DFLL Configuration in Open Loop mode */
OSCCTRL->DFLLCTRLA.reg = 0;
//GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK3_Val);
OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP( 0x1 ) |
OSCCTRL_DFLLMUL_FSTEP( 0x1 ) |
OSCCTRL_DFLLMUL_MUL( 0 );
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL )
{
/* Wait for synchronization */
}
/* DFLL Configuration in Open Loop mode */
OSCCTRL->DFLLCTRLB.reg = 0;
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLCTRLB )
{
/* Wait for synchronization */
}
OSCCTRL->DFLLCTRLA.reg = 0;
//GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK3_Val);
OSCCTRL->DFLLCTRLA.reg |= OSCCTRL_DFLLCTRLA_ENABLE;
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_ENABLE )
{
/* Wait for synchronization */
}
OSCCTRL->DFLLVAL.reg = OSCCTRL->DFLLVAL.reg;
while( OSCCTRL->DFLLSYNC.bit.DFLLVAL );
OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP( 0x1 ) |
OSCCTRL_DFLLMUL_FSTEP( 0x1 ) |
OSCCTRL_DFLLMUL_MUL( 0 );
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL )
{
/* Wait for synchronization */
}
OSCCTRL->DFLLCTRLB.reg = 0;
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLCTRLB )
{
/* Wait for synchronization */
}
OSCCTRL->DFLLCTRLA.reg |= OSCCTRL_DFLLCTRLA_ENABLE;
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_ENABLE )
{
/* Wait for synchronization */
}
OSCCTRL->DFLLVAL.reg = OSCCTRL->DFLLVAL.reg;
while( OSCCTRL->DFLLSYNC.bit.DFLLVAL );
OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_WAITLOCK |
OSCCTRL_DFLLCTRLB_CCDIS | OSCCTRL_DFLLCTRLB_USBCRM ;
while ( !OSCCTRL->STATUS.bit.DFLLRDY )
{
/* Wait for synchronization */
}
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_1M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(24u);
while ( GCLK->SYNCBUSY.bit.GENCTRL5 ){
/* Wait for synchronization */
}
while ( !OSCCTRL->STATUS.bit.DFLLRDY )
{
/* Wait for synchronization */
}
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_1M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(24u);
while ( GCLK->SYNCBUSY.bit.GENCTRL5 ){
/* Wait for synchronization */
}
/* ------------------------------------------------------------------------
* Set up the PLLs
*/
//PLL0 is 120MHz
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val);
OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(59); //120 Mhz
while(OSCCTRL->Dpll[0].DPLLSYNCBUSY.bit.DPLLRATIO);
//MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51
OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK | OSCCTRL_DPLLCTRLB_LBYPASS;
OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE;
while( OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK == 0 );
//PLL1 is 100MHz
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val);
OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(49); //100 Mhz
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.DPLLRATIO);
//MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51
OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK | OSCCTRL_DPLLCTRLB_LBYPASS;
OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE;
while( OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[1].DPLLSTATUS.bit.LOCK == 0 );
//PLL0 is 120MHz
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val);
OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(59); //120 Mhz
while(OSCCTRL->Dpll[0].DPLLSYNCBUSY.bit.DPLLRATIO);
//MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51
OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK | OSCCTRL_DPLLCTRLB_LBYPASS;
OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE;
while( OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK == 0 );
//PLL1 is 100MHz
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val);
OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(49); //100 Mhz
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.DPLLRATIO);
//MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51
OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK | OSCCTRL_DPLLCTRLB_LBYPASS;
OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE;
while( OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[1].DPLLSTATUS.bit.LOCK == 0 );
/* ------------------------------------------------------------------------
* Set up the peripheral clocks
@ -187,67 +191,67 @@ void SystemInit( void )
//48MHZ CLOCK FOR USB AND STUFF
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_48M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) |
GCLK_GENCTRL_IDC |
//GCLK_GENCTRL_OE |
GCLK_GENCTRL_GENEN;
while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_48M_SYNC)
{
/* Wait for synchronization */
}
//100MHZ CLOCK FOR OTHER PERIPHERALS
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_100M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DPLL1_Val) |
GCLK_GENCTRL_IDC |
//GCLK_GENCTRL_OE |
GCLK_GENCTRL_GENEN;
while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_100M_SYNC)
{
/* Wait for synchronization */
}
GCLK_GENCTRL_IDC |
//GCLK_GENCTRL_OE |
GCLK_GENCTRL_GENEN;
while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_48M_SYNC)
{
/* Wait for synchronization */
}
//100MHZ CLOCK FOR OTHER PERIPHERALS
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_100M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DPLL1_Val) |
GCLK_GENCTRL_IDC |
//GCLK_GENCTRL_OE |
GCLK_GENCTRL_GENEN;
while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_100M_SYNC)
{
/* Wait for synchronization */
}
//12MHZ CLOCK FOR DAC
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_12M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) |
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_12M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) |
GCLK_GENCTRL_IDC |
GCLK_GENCTRL_DIV(4) |
GCLK_GENCTRL_DIVSEL |
//GCLK_GENCTRL_OE |
GCLK_GENCTRL_GENEN;
while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_12M_SYNC)
while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_12M_SYNC)
{
/* Wait for synchronization */
/* Wait for synchronization */
}
/*---------------------------------------------------------------------
* Set up main clock
*/
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_MAIN].reg = GCLK_GENCTRL_SRC(MAIN_CLOCK_SOURCE) |
GCLK_GENCTRL_IDC |
//GCLK_GENCTRL_OE |
GCLK_GENCTRL_GENEN;
* Set up main clock
*/
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_MAIN].reg = GCLK_GENCTRL_SRC(MAIN_CLOCK_SOURCE) |
GCLK_GENCTRL_IDC |
//GCLK_GENCTRL_OE |
GCLK_GENCTRL_GENEN;
while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL0 )
{
/* Wait for synchronization */
}
{
/* Wait for synchronization */
}
MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV_DIV1;
/* Use the LDO regulator by default */
SUPC->VREG.bit.SEL = 0;
/* If desired, enable cache! */
#if defined(ENABLE_CACHE)
__disable_irq();
CMCC->CTRL.reg = 1;
__enable_irq();
#endif
//*************** END SAMD51 *************************//
#else