/* * samd10_pokusy2.c * * Created: 16.11.2016 11:21:11 * Author : misa */ #include "sam.h" #define EXTCLK_FREQ 8000000 #define F_CPU 48000000 #define F_INTERM 32000 #define EXTCLK_DIV ((EXTCLK_FREQ/(2*F_INTERM)) - 1) void clock_init(void); void USART_init(void); void SERCOM0_sync(); volatile uint32_t i; int main(void) { SystemInit(); clock_init(); PORT->Group[0].PINCFG[10].reg |= PORT_PINCFG_PMUXEN; // alt fce zapnuta PORT->Group[0].PINCFG[11].reg |= PORT_PINCFG_PMUXEN; // alt fce zapnuta PORT->Group[0].PMUX[10/2].reg |= PORT_PMUX_PMUXE(PORT_PMUX_PMUXE_C_Val); // výběr alt fce PORT->Group[0].PMUX[11/2].reg |= PORT_PMUX_PMUXO(PORT_PMUX_PMUXO_C_Val); // výběr alt fce USART_init(); while (1){ while(!(SERCOM0->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)){} // počkej až je odesráno SERCOM0->USART.DATA.reg = 'a'; // pošli "a" for(i=0;i<5000;i++){i=i;} // chvíli počkej ať se to líp hledá na oscilu } } void SERCOM0_sync(){ while (SERCOM0->USART.SYNCBUSY.reg); // čekání na synchronizaci zápisu (doladit) } void USART_init(void){ PM->APBCMASK.reg = PM_APBCMASK_SERCOM0; // enable clock to SERCOM0 // SERCOM0 as USART, Asynchronous, Tx atd PAD2 (PA10), RX PAD3 (PA11), LSB first, Frame without parity, arithmetic baud rate gen + 16x oversampl; SERCOM0->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE_USART_INT_CLK | SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1) | SERCOM_USART_CTRLA_DORD; SERCOM0_sync(); // enable transmitter and receiver SERCOM0->USART.CTRLB.reg = SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN; SERCOM0_sync(); // set baudrate fbaud = fref/S*(1-BAUD/65536) ... S = oversampling (16,8 or 3) SERCOM0->USART.BAUD.reg = 65326; SERCOM0_sync(); // enable USART SERCOM0->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; SERCOM0_sync(); } // GCLK_MAIN 48MHz void clock_init(void){ SYSCTRL->XOSC.reg = (SYSCTRL_XOSC_ENABLE); // enable 8MHz oscillator at input while((SYSCTRL->PCLKSR.reg & (SYSCTRL_PCLKSR_XOSCRDY)) == 0); // wait until start-up REG_NVMCTRL_CTRLB |= (NVMCTRL_CTRLB_RWS(1)); // flash wait state to 1 // config DPLL, DPLL jede ze 32kHz (vstup nesmi byt vetsi nez 33kHz), je potreba tedy 8MHz externi clock podělit ! SYSCTRL->DPLLCTRLA.reg = 0; // default values SYSCTRL->DPLLRATIO.reg = SYSCTRL_DPLLRATIO_LDR(2*F_CPU/F_INTERM); // PLL output can be 2*48 (2*F_CPU) => 96MHz SYSCTRL->DPLLCTRLB.reg = SYSCTRL_DPLLCTRLB_DIV(EXTCLK_DIV) | SYSCTRL_DPLLCTRLB_REFCLK(SYSCTRL_DPLLCTRLB_REFCLK_REF1_Val); // vybíráme externí clock SYSCTRL->DPLLCTRLA.reg = SYSCTRL_DPLLCTRLA_ENABLE; // spouštíme DPLL while((SYSCTRL->DPLLSTATUS.reg & (SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK)) != (SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK)); // čekáme než naskočí //For generic clock generator 0, select the DPLL Clock as input, divide by 2 GCLK->GENDIV.reg = ((2 << GCLK_GENDIV_DIV_Pos) | (0 << GCLK_GENDIV_ID_Pos)); GCLK->GENCTRL.reg = ((0 << GCLK_GENCTRL_ID_Pos) | (GCLK_SOURCE_FDPLL << GCLK_GENCTRL_SRC_Pos)| (GCLK_GENCTRL_GENEN)); GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID_SERCOM0_CORE ; // pustí clock mimo jiné i do SECOM0 // optionaly config prescalers for CPU,AHB,APBs (PM - power manager) }