#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(24 / 2) * ((1+0)/2) | #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(24 / 2) * ((1+0)/2) | ||||
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/6) | #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/6) | ||||
#elif F_BUS == 16000000 | |||||
#define HAS_SPIFIFO | |||||
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz | |||||
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz | |||||
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz | |||||
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz | |||||
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz | |||||
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz | |||||
#elif F_BUS == 8000000 | |||||
#define HAS_SPIFIFO | |||||
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz | |||||
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz | |||||
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz | |||||
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz | |||||
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz | |||||
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz | |||||
#elif F_BUS == 4000000 | #elif F_BUS == 4000000 | ||||
#define HAS_SPIFIFO | #define HAS_SPIFIFO | ||||
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz | #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz |
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz | #define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz | ||||
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz | #define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz | ||||
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 24 MHz | #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 24 MHz | ||||
#elif F_BUS == 16000000 | |||||
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz | |||||
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz | |||||
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz | |||||
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 16 MHz | |||||
#elif F_BUS == 8000000 | |||||
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz | |||||
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz | |||||
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz | |||||
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz | |||||
#elif F_BUS == 4000000 | #elif F_BUS == 4000000 | ||||
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz | #define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz | ||||
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz | #define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz |
uint32_t n = usec << 4; | uint32_t n = usec << 4; | ||||
#elif F_CPU == 24000000 | #elif F_CPU == 24000000 | ||||
uint32_t n = usec << 3; | uint32_t n = usec << 3; | ||||
#elif F_CPU == 16000000 | |||||
uint32_t n = usec << 2; | |||||
#elif F_CPU == 8000000 | |||||
uint32_t n = usec << 1; | |||||
#elif F_CPU == 4000000 | #elif F_CPU == 4000000 | ||||
uint32_t n = usec; | uint32_t n = usec; | ||||
#elif F_CPU == 2000000 | #elif F_CPU == 2000000 | ||||
if (usec == 0) return; | if (usec == 0) return; | ||||
__asm__ volatile( | __asm__ volatile( | ||||
"L_%=_delayMicroseconds:" "\n\t" | "L_%=_delayMicroseconds:" "\n\t" | ||||
#if F_CPU < 10000000 | |||||
#if F_CPU < 24000000 | |||||
"nop" "\n\t" | "nop" "\n\t" | ||||
#endif | #endif | ||||
"subs %0, #1" "\n\t" | "subs %0, #1" "\n\t" |
// default all interrupts to medium priority level | // default all interrupts to medium priority level | ||||
for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128); | for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128); | ||||
// start in FEI mode | |||||
// hardware always starts in FEI mode | |||||
// C1[CLKS] bits are written to 00 | |||||
// C1[IREFS] bit is written to 1 | |||||
// C6[PLLS] bit is written to 0 | |||||
#if F_CPU <= 4000000 | |||||
// use the internal oscillator | |||||
MCG_C1 = MCG_C1_CLKS(1) | MCG_C2_IRCS; | |||||
// wait for MCGOUT to use oscillator | |||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(1)) ; | |||||
MCG_C2 = MCG_C2_IRCS; | |||||
// now in FBI mode: | |||||
// C1[CLKS] bits are written to 01 | |||||
// C1[IREFS] bit is written to 1 | |||||
// C6[PLLS] is written to 0 | |||||
// C2[LP] is written to 0 | |||||
MCG_C2 = MCG_C2_IRCS | MCG_C2_LP; | |||||
// now in BLPI mode: | |||||
// C1[CLKS] bits are written to 01 | |||||
// C1[IREFS] bit is written to 1 | |||||
// C6[PLLS] bit is written to 0 | |||||
// C2[LP] bit is written to 1 | |||||
#else | |||||
// enable capacitors for crystal | // enable capacitors for crystal | ||||
OSC0_CR = OSC_SC8P | OSC_SC2P; | OSC0_CR = OSC_SC8P | OSC_SC2P; | ||||
// enable osc, 8-32 MHz range, low power mode | // enable osc, 8-32 MHz range, low power mode | ||||
while ((MCG_S & MCG_S_IREFST) != 0) ; | while ((MCG_S & MCG_S_IREFST) != 0) ; | ||||
// wait for MCGOUT to use oscillator | // wait for MCGOUT to use oscillator | ||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; | while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; | ||||
// now we're in FBE mode | |||||
#if F_CPU == 72000000 | |||||
// now in FBE mode | |||||
// C1[CLKS] bits are written to 10 | |||||
// C1[IREFS] bit is written to 0 | |||||
// C1[FRDIV] must be written to divide xtal to 31.25-39 kHz | |||||
// C6[PLLS] bit is written to 0 | |||||
// C2[LP] is written to 0 | |||||
#if F_CPU <= 16000000 | |||||
// if the crystal is fast enough, use it directly (no FLL or PLL) | |||||
MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS | MCG_C2_LP; | |||||
// BLPE mode: | |||||
// C1[CLKS] bits are written to 10 | |||||
// C1[IREFS] bit is written to 0 | |||||
// C2[LP] bit is written to 1 | |||||
#else | |||||
// if we need faster than the crystal, turn on the PLL | |||||
#if F_CPU == 72000000 | |||||
MCG_C5 = MCG_C5_PRDIV0(5); // config PLL input for 16 MHz Crystal / 6 = 2.667 Hz | MCG_C5 = MCG_C5_PRDIV0(5); // config PLL input for 16 MHz Crystal / 6 = 2.667 Hz | ||||
#else | |||||
#else | |||||
MCG_C5 = MCG_C5_PRDIV0(3); // config PLL input for 16 MHz Crystal / 4 = 4 MHz | MCG_C5 = MCG_C5_PRDIV0(3); // config PLL input for 16 MHz Crystal / 4 = 4 MHz | ||||
#endif | |||||
#if F_CPU == 168000000 | |||||
#endif | |||||
#if F_CPU == 168000000 | |||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(18); // config PLL for 168 MHz output | MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(18); // config PLL for 168 MHz output | ||||
#elif F_CPU == 144000000 | |||||
#elif F_CPU == 144000000 | |||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(12); // config PLL for 144 MHz output | MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(12); // config PLL for 144 MHz output | ||||
#elif F_CPU == 120000000 | |||||
#elif F_CPU == 120000000 | |||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(6); // config PLL for 120 MHz output | MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(6); // config PLL for 120 MHz output | ||||
#elif F_CPU == 72000000 | |||||
#elif F_CPU == 72000000 | |||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(3); // config PLL for 72 MHz output | MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(3); // config PLL for 72 MHz output | ||||
#else | |||||
#else | |||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); // config PLL for 96 MHz output | MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); // config PLL for 96 MHz output | ||||
#endif | |||||
#endif | |||||
// wait for PLL to start using xtal as its input | // wait for PLL to start using xtal as its input | ||||
while (!(MCG_S & MCG_S_PLLST)) ; | while (!(MCG_S & MCG_S_PLLST)) ; | ||||
// wait for PLL to lock | // wait for PLL to lock | ||||
while (!(MCG_S & MCG_S_LOCK0)) ; | while (!(MCG_S & MCG_S_LOCK0)) ; | ||||
// now we're in PBE mode | // now we're in PBE mode | ||||
#endif | |||||
#endif | |||||
// now program the clock dividers | |||||
#if F_CPU == 168000000 | #if F_CPU == 168000000 | ||||
// config divisors: 168 MHz core, 56 MHz bus, 33.6 MHz flash | |||||
// config divisors: 168 MHz core, 56 MHz bus, 33.6 MHz flash, USB = 168 * 2 / 7 | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(2) | SIM_CLKDIV1_OUTDIV4(4); | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(2) | SIM_CLKDIV1_OUTDIV4(4); | ||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(6) | SIM_CLKDIV2_USBFRAC; | |||||
#elif F_CPU == 144000000 | #elif F_CPU == 144000000 | ||||
// config divisors: 144 MHz core, 48 MHz bus, 28.8 MHz flash | |||||
// config divisors: 144 MHz core, 48 MHz bus, 28.8 MHz flash, USB = 144 / 3 | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(2) | SIM_CLKDIV1_OUTDIV4(4); | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(2) | SIM_CLKDIV1_OUTDIV4(4); | ||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2); | |||||
#elif F_CPU == 120000000 | #elif F_CPU == 120000000 | ||||
// config divisors: 120 MHz core, 60 MHz bus, 24 MHz flash | |||||
// config divisors: 120 MHz core, 60 MHz bus, 24 MHz flash, USB = 128 * 2 / 5 | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(4); | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(4); | ||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(4) | SIM_CLKDIV2_USBFRAC; | |||||
#elif F_CPU == 96000000 | #elif F_CPU == 96000000 | ||||
// config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash | |||||
// config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash, USB = 96 / 2 | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); | ||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); | |||||
#elif F_CPU == 72000000 | #elif F_CPU == 72000000 | ||||
// config divisors: 72 MHz core, 36 MHz bus, 24 MHz flash | |||||
// config divisors: 72 MHz core, 36 MHz bus, 24 MHz flash, USB = 72 * 2 / 3 | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(2); | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(2); | ||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC; | |||||
#elif F_CPU == 48000000 | #elif F_CPU == 48000000 | ||||
// config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash | |||||
// config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash, USB = 96 / 2 | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); | ||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); | |||||
#elif F_CPU == 24000000 | #elif F_CPU == 24000000 | ||||
// config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash | |||||
// config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash, USB = 96 / 2 | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3); | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3); | ||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); | |||||
#elif F_CPU == 16000000 | |||||
// config divisors: 16 MHz core, 16 MHz bus, 16 MHz flash | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(0); | |||||
#elif F_CPU == 8000000 | |||||
// config divisors: 8 MHz core, 8 MHz bus, 8 MHz flash | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(1); | |||||
#elif F_CPU == 4000000 | |||||
// config divisors: 4 MHz core, 4 MHz bus, 2 MHz flash | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(1); | |||||
#elif F_CPU == 2000000 | |||||
// config divisors: 2 MHz core, 2 MHz bus, 1 MHz flash | |||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); | |||||
#else | #else | ||||
#error "Error, F_CPU must be 168, 144, 120, 96, 72, 48, or 24 MHz" | |||||
#error "Error, F_CPU must be 168, 144, 120, 96, 72, 48, 24, 16, 8, 4, or 2 MHz" | |||||
#endif | #endif | ||||
#if F_CPU > 16000000 | |||||
// switch to PLL as clock source, FLL input = 16 MHz / 512 | // switch to PLL as clock source, FLL input = 16 MHz / 512 | ||||
MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4); | MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4); | ||||
// wait for PLL clock to be used | // wait for PLL clock to be used | ||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ; | while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ; | ||||
// now we're in PEE mode | // now we're in PEE mode | ||||
// configure USB for 48 MHz clock | |||||
#if F_CPU == 168000000 | |||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(6) | SIM_CLKDIV2_USBFRAC; // USB = 168 MHz PLL * 2 / 7 | |||||
#elif F_CPU == 144000000 | |||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2); // USB = 144 MHz PLL / 3 | |||||
#elif F_CPU == 120000000 | |||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(4) | SIM_CLKDIV2_USBFRAC; // USB = 120 MHz PLL * 2 / 5 | |||||
#elif F_CPU == 72000000 | |||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC; // USB = 72 MHz PLL * 2 / 3 | |||||
#else | |||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // USB = 96 MHz PLL / 2 | |||||
#endif | |||||
// USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0 | // USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0 | ||||
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6); | SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6); | ||||
#else | |||||
SIM_SOPT2 = SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(3); | |||||
#endif | |||||
#if F_CPU <= 2000000 | |||||
// TODO: switch to VLPR mode.... | |||||
SMC_PMPROT = SMC_PMPROT_AVLP | SMC_PMPROT_ALLS | SMC_PMPROT_AVLLS; | |||||
SMC_PMCTRL = SMC_PMCTRL_RUNM(2) | SMC_PMCTRL_STOPM(2); // VLPR mode :-) | |||||
#endif | |||||
#if 0 | |||||
#if F_CPU == 2000000 | |||||
// select external reference clock as MCG_OUT | |||||
MCG_C1 |= MCG_C1_CLKS(2); | |||||
// wait for FLL clock to be used | |||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; | |||||
// now move to FBE mode | |||||
// make sure the FRDIV is configured to keep the FLL reference within spec. | |||||
MCG_C1 &= ~0x38; // clear FRDIV field | |||||
MCG_C1 |= MCG_C1_FRDIV(4); // set FLL ref divider to 512 | |||||
MCG_C6 &= ~MCG_C6_PLLS; // clear PLLS to select the FLL | |||||
while (MCG_S & MCG_S_PLLST){} // Wait for PLLST status bit to clear to | |||||
// indicate switch to FLL output | |||||
// now move to FBI mode | |||||
MCG_C2 |= MCG_C2_IRCS; // set the IRCS bit to select the fast IRC | |||||
// set CLKS to 1 to select the internal reference clock | |||||
// keep FRDIV at existing value to keep FLL ref clock in spec. | |||||
// set IREFS to 1 to select internal reference clock | |||||
MCG_C1 = MCG_C1_CLKS(1) | MCG_C1_FRDIV(4) | MCG_C1_IREFS; | |||||
// wait for internal reference to be selected | |||||
while (!(MCG_S & MCG_S_IREFST)){} | |||||
// wait for fast internal reference to be selected | |||||
while (!(MCG_S & MCG_S_IRCST)){} | |||||
// wait for clock to switch to IRC | |||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(1)) ; | |||||
// now move to BLPI | |||||
MCG_C2 |= MCG_C2_LP; | |||||
// now we're in BLPI mode | |||||
#elif F_CPU == 16000000 || F_CPU == 8000000 || F_CPU == 4000000 | |||||
// select external reference clock as MCG_OUT | |||||
MCG_C1 = MCG_C1_CLKS(2); | |||||
// wait for external clock to be used | |||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; | |||||
// set the LP bit to enter BLPE | |||||
MCG_C2 |= MCG_C2_LP; | |||||
// now we're in BLPE mode | |||||
#else | |||||
// switch to PLL as clock source, FLL input = 16 MHz / 512 | |||||
MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4); | |||||
// wait for PLL clock to be used | |||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ; | |||||
// now we're in PEE mode | |||||
// configure USB for 48 MHz clock | |||||
#endif | |||||
#endif | |||||
// initialize the SysTick counter | // initialize the SysTick counter | ||||
SYST_RVR = (F_CPU / 1000) - 1; | SYST_RVR = (F_CPU / 1000) - 1; |
#elif (F_CPU == 24000000) | #elif (F_CPU == 24000000) | ||||
#define F_BUS 24000000 | #define F_BUS 24000000 | ||||
#define F_MEM 24000000 | #define F_MEM 24000000 | ||||
#elif (F_CPU == 16000000) | |||||
#define F_BUS 16000000 | |||||
#define F_MEM 16000000 | |||||
#elif (F_CPU == 8000000) | |||||
#define F_BUS 8000000 | |||||
#define F_MEM 8000000 | |||||
#elif (F_CPU == 4000000) | |||||
#define F_BUS 4000000 | |||||
#define F_MEM 4000000 | |||||
#elif (F_CPU == 2000000) | |||||
#define F_BUS 2000000 | |||||
#define F_MEM 1000000 | |||||
#endif | #endif | ||||
#define DMA_DCHPRI2 *(volatile uint8_t *)0x40008101 // Channel n Priority Register | #define DMA_DCHPRI2 *(volatile uint8_t *)0x40008101 // Channel n Priority Register | ||||
#define DMA_DCHPRI1 *(volatile uint8_t *)0x40008102 // Channel n Priority Register | #define DMA_DCHPRI1 *(volatile uint8_t *)0x40008102 // Channel n Priority Register | ||||
#define DMA_DCHPRI0 *(volatile uint8_t *)0x40008103 // Channel n Priority Register | #define DMA_DCHPRI0 *(volatile uint8_t *)0x40008103 // Channel n Priority Register | ||||
#define DMA_DCHPRI_CHPRI(n) ((uint8_t)(n & 3)<<0) // Channel Arbitration Priority | |||||
#define DMA_DCHPRI_CHPRI(n) ((uint8_t)(n & 15)<<0) // Channel Arbitration Priority | |||||
#define DMA_DCHPRI_DPA ((uint8_t)1<<6) // Disable PreEmpt Ability | #define DMA_DCHPRI_DPA ((uint8_t)1<<6) // Disable PreEmpt Ability | ||||
#define DMA_DCHPRI_ECP ((uint8_t)1<<7) // Enable PreEmption | #define DMA_DCHPRI_ECP ((uint8_t)1<<7) // Enable PreEmption | ||||
#define DMA_DCHPRI7 *(volatile uint8_t *)0x40008104 // Channel n Priority Register | |||||
#define DMA_DCHPRI6 *(volatile uint8_t *)0x40008105 // Channel n Priority Register | |||||
#define DMA_DCHPRI5 *(volatile uint8_t *)0x40008106 // Channel n Priority Register | |||||
#define DMA_DCHPRI4 *(volatile uint8_t *)0x40008107 // Channel n Priority Register | |||||
#define DMA_DCHPRI11 *(volatile uint8_t *)0x40008108 // Channel n Priority Register | |||||
#define DMA_DCHPRI10 *(volatile uint8_t *)0x40008109 // Channel n Priority Register | |||||
#define DMA_DCHPRI9 *(volatile uint8_t *)0x4000810A // Channel n Priority Register | |||||
#define DMA_DCHPRI8 *(volatile uint8_t *)0x4000810B // Channel n Priority Register | |||||
#define DMA_DCHPRI15 *(volatile uint8_t *)0x4000810C // Channel n Priority Register | |||||
#define DMA_DCHPRI14 *(volatile uint8_t *)0x4000810D // Channel n Priority Register | |||||
#define DMA_DCHPRI13 *(volatile uint8_t *)0x4000810E // Channel n Priority Register | |||||
#define DMA_DCHPRI12 *(volatile uint8_t *)0x4000810F // Channel n Priority Register | |||||
#define DMA_TCD_ATTR_SMOD(n) (((n) & 0x1F) << 11) | #define DMA_TCD_ATTR_SMOD(n) (((n) & 0x1F) << 11) |
#elif F_BUS == 24000000 | #elif F_BUS == 24000000 | ||||
#define DEFAULT_FTM_MOD (49152 - 1) | #define DEFAULT_FTM_MOD (49152 - 1) | ||||
#define DEFAULT_FTM_PRESCALE 0 | #define DEFAULT_FTM_PRESCALE 0 | ||||
#elif F_BUS == 16000000 | |||||
#define DEFAULT_FTM_MOD (32768 - 1) | |||||
#define DEFAULT_FTM_PRESCALE 0 | |||||
#elif F_BUS == 8000000 | |||||
#define DEFAULT_FTM_MOD (16384 - 1) | |||||
#define DEFAULT_FTM_PRESCALE 0 | |||||
#elif F_BUS == 4000000 | #elif F_BUS == 4000000 | ||||
#define DEFAULT_FTM_MOD (8192 - 1) | #define DEFAULT_FTM_MOD (8192 - 1) | ||||
#define DEFAULT_FTM_PRESCALE 0 | #define DEFAULT_FTM_PRESCALE 0 | ||||
#define PULSEIN_LOOPS_PER_USEC 7 | #define PULSEIN_LOOPS_PER_USEC 7 | ||||
#elif F_CPU == 24000000 | #elif F_CPU == 24000000 | ||||
#define PULSEIN_LOOPS_PER_USEC 4 | #define PULSEIN_LOOPS_PER_USEC 4 | ||||
#elif F_CPU == 16000000 | |||||
#define PULSEIN_LOOPS_PER_USEC 1 | |||||
#elif F_CPU == 8000000 | |||||
#define PULSEIN_LOOPS_PER_USEC 1 | |||||
#elif F_CPU == 4000000 | #elif F_CPU == 4000000 | ||||
#define PULSEIN_LOOPS_PER_USEC 1 | #define PULSEIN_LOOPS_PER_USEC 1 | ||||
#elif F_CPU == 2000000 | #elif F_CPU == 2000000 |
* SOFTWARE. | * SOFTWARE. | ||||
*/ | */ | ||||
#if F_CPU >= 20000000 | |||||
#include "usb_desc.h" | #include "usb_desc.h" | ||||
#include "usb_names.h" | #include "usb_names.h" | ||||
#include "mk20dx128.h" | #include "mk20dx128.h" | ||||
#endif // F_CPU >= 20 MHz |
#ifndef _usb_desc_h_ | #ifndef _usb_desc_h_ | ||||
#define _usb_desc_h_ | #define _usb_desc_h_ | ||||
#if F_CPU >= 20000000 | |||||
// This header is NOT meant to be included when compiling | // This header is NOT meant to be included when compiling | ||||
// user sketches in Arduino. The low-level functions | // user sketches in Arduino. The low-level functions | ||||
// provided by usb_dev.c are meant to be called only by | // provided by usb_dev.c are meant to be called only by | ||||
extern const usb_descriptor_list_t usb_descriptor_list[]; | extern const usb_descriptor_list_t usb_descriptor_list[]; | ||||
#endif // F_CPU >= 20 MHz | |||||
#endif | #endif |
* SOFTWARE. | * SOFTWARE. | ||||
*/ | */ | ||||
#if F_CPU >= 20000000 | |||||
#include "mk20dx128.h" | #include "mk20dx128.h" | ||||
//#include "HardwareSerial.h" | //#include "HardwareSerial.h" | ||||
#include "usb_dev.h" | #include "usb_dev.h" | ||||
} | } | ||||
#else // F_CPU < 20 MHz | |||||
void usb_init(void) | |||||
{ | |||||
} | |||||
#endif // F_CPU >= 20 MHz |
#ifndef _usb_dev_h_ | #ifndef _usb_dev_h_ | ||||
#define _usb_dev_h_ | #define _usb_dev_h_ | ||||
#if F_CPU >= 20000000 | |||||
// This header is NOT meant to be included when compiling | // This header is NOT meant to be included when compiling | ||||
// user sketches in Arduino. The low-level functions | // user sketches in Arduino. The low-level functions | ||||
// provided by usb_dev.c are meant to be called only by | // provided by usb_dev.c are meant to be called only by | ||||
#endif | #endif | ||||
#endif // F_CPU >= 20 MHz | |||||
#endif | #endif |
#include "WProgram.h" | #include "WProgram.h" | ||||
#if F_CPU >= 20000000 | |||||
#ifdef USB_SERIAL | #ifdef USB_SERIAL | ||||
usb_serial_class Serial; | usb_serial_class Serial; | ||||
#endif | #endif | ||||
usb_seremu_class Serial; | usb_seremu_class Serial; | ||||
#endif | #endif | ||||
#else // F_CPU < 20 MHz | |||||
#if defined(USB_SERIAL) || defined(USB_SERIAL_HID) | |||||
usb_serial_class Serial; | |||||
#else | |||||
usb_seremu_class Serial; | |||||
#endif | |||||
#endif // F_CPU |
* SOFTWARE. | * SOFTWARE. | ||||
*/ | */ | ||||
#if F_CPU >= 20000000 | |||||
#include "mk20dx128.h" | #include "mk20dx128.h" | ||||
//#include "HardwareSerial.h" | //#include "HardwareSerial.h" | ||||
#include "usb_dev.h" | #include "usb_dev.h" | ||||
//serial_print("\n"); | //serial_print("\n"); | ||||
} | } | ||||
#endif // F_CPU >= 20 MHz |
* SOFTWARE. | * SOFTWARE. | ||||
*/ | */ | ||||
#if F_CPU >= 20000000 | |||||
//#include "mk20dx128.h" | //#include "mk20dx128.h" | ||||
#include "usb_dev.h" | #include "usb_dev.h" | ||||
#include "usb_seremu.h" | #include "usb_seremu.h" | ||||
} | } | ||||
#endif // SEREMU_INTERFACE | #endif // SEREMU_INTERFACE | ||||
#endif // F_CPU >= 20 MHz |
#include <inttypes.h> | #include <inttypes.h> | ||||
#if F_CPU >= 20000000 | |||||
// C language implementation | // C language implementation | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" { | extern "C" { | ||||
} | } | ||||
#endif | #endif | ||||
// C++ interface | // C++ interface | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
#include "Stream.h" | #include "Stream.h" | ||||
uint8_t rts(void) { return 1; } | uint8_t rts(void) { return 1; } | ||||
operator bool() { return usb_configuration; } | operator bool() { return usb_configuration; } | ||||
}; | }; | ||||
extern usb_seremu_class Serial; | extern usb_seremu_class Serial; | ||||
#endif // __cplusplus | |||||
#else // F_CPU < 20 MHz | |||||
// Allow Arduino programs using Serial to compile, but Serial will do nothing. | |||||
#ifdef __cplusplus | |||||
#include "Stream.h" | |||||
class usb_seremu_class : public Stream | |||||
{ | |||||
public: | |||||
void begin(long) { }; | |||||
void end() { }; | |||||
virtual int available() { return 0; } | |||||
virtual int read() { return -1; } | |||||
virtual int peek() { return -1; } | |||||
virtual void flush() { } | |||||
virtual size_t write(uint8_t c) { return 1; } | |||||
virtual size_t write(const uint8_t *buffer, size_t size) { return size; } | |||||
size_t write(unsigned long n) { return 1; } | |||||
size_t write(long n) { return 1; } | |||||
size_t write(unsigned int n) { return 1; } | |||||
size_t write(int n) { return 1; } | |||||
using Print::write; | |||||
void send_now(void) { } | |||||
uint32_t baud(void) { return 0; } | |||||
uint8_t stopbits(void) { return 1; } | |||||
uint8_t paritytype(void) { return 0; } | |||||
uint8_t numbits(void) { return 8; } | |||||
uint8_t dtr(void) { return 1; } | |||||
uint8_t rts(void) { return 1; } | |||||
operator bool() { return true; } | |||||
}; | |||||
extern usb_seremu_class Serial; | |||||
#endif // __cplusplus | #endif // __cplusplus | ||||
#endif // F_CPU >= 20 MHz | |||||
#endif // USB_HID | #endif // USB_HID | ||||
#endif // USBseremu_h_ | #endif // USBseremu_h_ |
#include <inttypes.h> | #include <inttypes.h> | ||||
#if F_CPU >= 20000000 | |||||
// C language implementation | // C language implementation | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" { | extern "C" { | ||||
#define USB_SERIAL_DTR 0x01 | #define USB_SERIAL_DTR 0x01 | ||||
#define USB_SERIAL_RTS 0x02 | #define USB_SERIAL_RTS 0x02 | ||||
// C++ interface | // C++ interface | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
#include "Stream.h" | #include "Stream.h" | ||||
} | } | ||||
}; | }; | ||||
extern usb_serial_class Serial; | extern usb_serial_class Serial; | ||||
#endif // __cplusplus | |||||
#else // F_CPU < 20 MHz | |||||
// Allow Arduino programs using Serial to compile, but Serial will do nothing. | |||||
#ifdef __cplusplus | |||||
#include "Stream.h" | |||||
class usb_serial_class : public Stream | |||||
{ | |||||
public: | |||||
void begin(long) { }; | |||||
void end() { }; | |||||
virtual int available() { return 0; } | |||||
virtual int read() { return -1; } | |||||
virtual int peek() { return -1; } | |||||
virtual void flush() { } | |||||
virtual size_t write(uint8_t c) { return 1; } | |||||
virtual size_t write(const uint8_t *buffer, size_t size) { return size; } | |||||
size_t write(unsigned long n) { return 1; } | |||||
size_t write(long n) { return 1; } | |||||
size_t write(unsigned int n) { return 1; } | |||||
size_t write(int n) { return 1; } | |||||
using Print::write; | |||||
void send_now(void) { } | |||||
uint32_t baud(void) { return 0; } | |||||
uint8_t stopbits(void) { return 1; } | |||||
uint8_t paritytype(void) { return 0; } | |||||
uint8_t numbits(void) { return 8; } | |||||
uint8_t dtr(void) { return 1; } | |||||
uint8_t rts(void) { return 1; } | |||||
operator bool() { return true; } | |||||
}; | |||||
extern usb_serial_class Serial; | |||||
#endif // __cplusplus | #endif // __cplusplus | ||||
#endif // F_CPU | |||||
#endif // USB_SERIAL || USB_SERIAL_HID | #endif // USB_SERIAL || USB_SERIAL_HID | ||||
#endif // USBserial_h_ | #endif // USBserial_h_ |