/* funkční vzorové příklady na použití Generic clock Controlleru a oscilátorů GCLK_IO[n] - může sloužit jako vstup nebo výstup Generic Clock Generátoru GCLK_IO[0] - PA08 (8MHz input from mEDBG) - takže může na desce sloužit jen jako vstup ! GCLK_IO[0] - PA30, PA31, PA24, PA25 GCLK_IO[1] - PA09, PA22 GCLK_IO[2] - PA16, PA23 GCLK_IO[4] - PA14 GCLK_IO[5] - PA15 na ATSAMD10 je generátoru 6 (n=0..5) vstupem Generátorů může být nejen pin GCLK_IO[n] ale také libovolný oscilátor (vnější i vnitřní), nebo PLL */ /* Celkem je 6 clock generátorů (s ID 0..5) Každý z nich může mít různé vstupy hodin, buď z oscilátorů (externích i interních), z PLL, z generátoru 1 a nebo z pinu GCLK_IO[n] Většina oscilátorů po startu neběží, takže je potřeba je nastartovat konfigurace generátoru se stává ze dvou kroků V každém kroku je potřeba při zápisu do registrů speicifkovat pomocí ID který generátor nastavujeme 1. nastavit dělící poměr 2. Spustit generátor (případně nastavit výstup na GCLK_IO a podobně) pokud má clock putovat do periferie je potřeba konfigurovat a povolit ještě multiplexer, který směruje signál z jednoho z generátorů na peripheral clock - tedy k příslušné periferii (až 16) pokud nám stačí vypustit clock na GCLK_IO tak není konfigurace multiplexeru nutná je ale přirozeně potřeba konfigurovat výstupní pin ... */ // Nastaví Generic Clock Controller 5 se vstupem interního 32KHz oscilátoru a výstup přivede na GCLK_IO[5] (PA15) void gclk5_init(void){ uint32_t calibration; // načíst z flash paměti kalibrační konstantu (nahrátou při výrobě) pro OSC32K - bez ní je frekvence úplně mimo calibration = ((*(uint32_t *)FUSES_OSC32K_ADDR) & FUSES_OSC32K_Msk) >>FUSES_OSC32K_Pos; // nastartovat OSC32K s 32kHz výstupem a nahrát kalibrační konstantu SYSCTRL->OSC32K.reg = SYSCTRL_OSC32K_ENABLE | SYSCTRL_OSC32K_EN32K | SYSCTRL_OSC32K_CALIB(calibration); while(!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC32KRDY)){}; // počkat na nastartování OSC32K // nastavit parametry generátoru 5 GCLK->GENDIV.reg = GCLK_GENDIV_ID(5) | GCLK_GENDIV_DIV(0); // generátor 5, bez předděličky (dělíme /1) // vybrat clock generátoru 5 (OSC32K) GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(5) | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC32K; // povolit výstup na pin GCLK_IO[5], povolit generátor 5, zdroj 32kHz. // nastavení pinu PORT->Group[0].PINCFG[15].reg |= PORT_PINCFG_PMUXEN; // nastavit PA15 jako Alternativní fci PORT->Group[0].DIRSET.reg = PORT_PA15; // nasatvit PA15 jako výstup PORT->Group[0].PMUX[15/2].reg = PORT_PMUX_PMUXO(PORT_PMUX_PMUXO_H_Val) ; // vybrat příslušnou alternativní fci (PA15 ... H - GCLK_IO) } // Nastaví Generic Clock Controller 4 se vstupem XOSC (zde externí clock na XIN - PA08), dělí signál 8, a přivede na GCLK_IO[4] (PA14) void gclk4_init(void){ // spustit XOSC s externím clockem (s krystalem by bylo potřeba XTALEN a nastavit gain...) SYSCTRL->XOSC.reg = SYSCTRL_XOSC_ENABLE; while(!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSCRDY)){}; // počkat na naběhnutí XOSCK // nastavit parametry generátoru 4 GCLK->GENDIV.reg = GCLK_GENDIV_ID(4) | GCLK_GENDIV_DIV(8); // generátor 4, dělíme /8 // vybrat clock generátoru 4 - XOSC GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(4) | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC_Val; // povolit výstup na pin GCLK_IO[4], povolit generátor 4, zdroj XOSC // nastavení pinu PORT->Group[0].PINCFG[14].reg |= PORT_PINCFG_PMUXEN; // nastavit PA14 jako Alternativní fci PORT->Group[0].DIRSET.reg = PORT_PA14; // nasatvit PA14 jako výstup PORT->Group[0].PMUX[14/2].reg = PORT_PMUX_PMUXE(PORT_PMUX_PMUXE_H_Val) ; // vybrat příslušnou alternativní fci (PA14 ... H - GCLK_IO) } // Nastaví Generic Clock Controller 2: Zdroj FDPLL, výstupní frekvence 50MHz, frekvenci podělenou na 2MHz vypustíme na GCLK_IO[2] void gclk2_init(void){ // spustit XOSC s externím clockem (s krystalem by bylo potřeba XTALEN a nastavit gain...), Na Xmini desce přivedeno 8MHz z programátoru SYSCTRL->XOSC.reg = SYSCTRL_XOSC_ENABLE; while(!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSCRDY)){}; // počkat na naběhnutí XOSCK // nastavit FDPLL // vstupní frekvence pro FDPLL musí ležet v intervalu 32kHz - 2MHz // výstupní frekvence FDPLL musí ležet v rozsahu 48-96MHz. SYSCTRL->DPLLRATIO.reg = SYSCTRL_DPLLRATIO_LDR(49) | SYSCTRL_DPLLRATIO_LDRFRAC(0); // nastavit násobící poměr i se zlomkovou částí SYSCTRL->DPLLCTRLB.reg = SYSCTRL_DPLLCTRLB_REFCLK_REF1 | SYSCTRL_DPLLCTRLB_DIV(3); // vybrat zdroj pro PLL + nastavit dělící poměr pro signál z XOSC SYSCTRL->DPLLCTRLA.reg = SYSCTRL_DPLLCTRLA_ENABLE; // spustit FDPLL while(!(SYSCTRL->DPLLSTATUS.reg & SYSCTRL_DPLLSTATUS_LOCK)){}; // počkat na naběhnutí FDPLL // nastavit parametry generátoru 2 GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(25); // generátor 2, dělíme /25 // vybrat clock generátoru 2 - FDPLL GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_FDPLL; // povolit výstup na pin GCLK_IO[2], povolit generátor 2, zdroj FDPLL // nastavení pinu PORT->Group[0].PINCFG[16].reg |= PORT_PINCFG_PMUXEN; // nastavit PA16 jako Alternativní fci PORT->Group[0].DIRSET.reg = PORT_PA16; // nasatvit PA16 jako výstup PORT->Group[0].PMUX[16/2].reg = PORT_PMUX_PMUXE(PORT_PMUX_PMUXE_H_Val); // vybrat příslušnou alternativní fci (PA16 ... H - GCLK_IO) } // Nastaví Generic Clock Controller 2: Zdroj FDPLL, výstupní frekvence 50MHz, frekvenci podělenou na 2MHz vypustíme na GCLK_IO[2] void gclk1_init(void){ // spustit XOSC s externím clockem (s krystalem by bylo potřeba XTALEN a nastavit gain...), Na Xmini desce přivedeno 8MHz z programátoru SYSCTRL->XOSC.reg = SYSCTRL_XOSC_ENABLE; while(!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSCRDY)){}; // počkat na naběhnutí XOSCK // nastavit FDPLL SYSCTRL->DPLLRATIO.reg = SYSCTRL_DPLLRATIO_LDR(49) | SYSCTRL_DPLLRATIO_LDRFRAC(0); // nastavit násobící poměr i se zlomkovou částí SYSCTRL->DPLLCTRLB.reg = SYSCTRL_DPLLCTRLB_REFCLK_REF1 | SYSCTRL_DPLLCTRLB_DIV(3); // vybrat zdroj pro PLL + nastavit dělící poměr pro signál z XOSC SYSCTRL->DPLLCTRLA.reg = SYSCTRL_DPLLCTRLA_ENABLE; // spustit FDPLL while(!(SYSCTRL->DPLLSTATUS.reg & SYSCTRL_DPLLSTATUS_LOCK)){}; // počkat na naběhnutí FDPLL // nastavit parametry generátoru 2 GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(25); // generátor 2, dělíme /25 // vybrat clock generátoru 2 - FDPLL GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(1) | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_FDPLL; // povolit výstup na pin GCLK_IO[2], povolit generátor 2, zdroj FDPLL // nastavení pinu PORT->Group[0].PINCFG[22].reg |= PORT_PINCFG_PMUXEN; // nastavit PA22 jako Alternativní fci PORT->Group[0].DIRSET.reg = PORT_PA22; // nasatvit PA22 jako výstup PORT->Group[0].PMUX[22/2].reg = PORT_PMUX_PMUXE(PORT_PMUX_PMUXE_H_Val); // vybrat příslušnou alternativní fci (PA22 ... H - GCLK_IO) }