diff --git a/include/libopencm3/sam3x/pmc.h b/include/libopencm3/sam3x/pmc.h index b08bf51a..cff7ed0a 100644 --- a/include/libopencm3/sam3x/pmc.h +++ b/include/libopencm3/sam3x/pmc.h @@ -125,6 +125,8 @@ #define PMC_SR_LOCKA (0x01 << 1) #define PMC_SR_MOSCXTS (0x01 << 0) +extern u32 pmc_mck_frequency; + enum mck_src { MCK_SRC_SLOW = 0, MCK_SRC_MAIN = 1, @@ -137,5 +139,7 @@ void pmc_xtal_enable(bool en, u8 startup_time); void pmc_plla_config(u8 mul, u8 div); void pmc_peripheral_clock_enable(u8 pid); void pmc_peripheral_clock_disable(u8 pid); +void pmc_clock_setup_in_xtal_12mhz_out_84mhz(void); #endif + diff --git a/include/libopencm3/sam3x/usart.h b/include/libopencm3/sam3x/usart.h index 2eb99af0..bf5e4bf9 100644 --- a/include/libopencm3/sam3x/usart.h +++ b/include/libopencm3/sam3x/usart.h @@ -196,6 +196,7 @@ enum usart_flowcontrol { USART_FLOWCONTROL_RTS_CTS, }; +void usart_set_baudrate(u32 usart, u32 baud); void usart_set_databits(u32 usart, int bits); void usart_set_stopbits(u32 usart, enum usart_stopbits); void usart_set_parity(u32 usart, enum usart_parity); diff --git a/lib/sam3x/pmc.c b/lib/sam3x/pmc.c index cd0ad245..0086e177 100644 --- a/lib/sam3x/pmc.c +++ b/lib/sam3x/pmc.c @@ -18,6 +18,10 @@ */ #include +#include + +/** Default peripheral clock frequency after reset. */ +u32 pmc_mck_frequency = 4000000; void pmc_xtal_enable(bool en, u8 startup_time) { @@ -60,3 +64,18 @@ void pmc_mck_set_source(enum mck_src src) while (!(PMC_SR & PMC_SR_MCKRDY)); } +void pmc_clock_setup_in_xtal_12mhz_out_84mhz(void) +{ + eefc_set_latency(4); + + /* 12MHz external xtal, maximum possible startup time */ + pmc_xtal_enable(true, 0xff); + /* Select as main oscillator */ + CKGR_MOR |= CKGR_MOR_KEY | CKGR_MOR_MOSCSEL; + /* Multiply by 7 for 84MHz */ + pmc_plla_config(7, 1); + pmc_mck_set_source(MCK_SRC_PLLA); + + pmc_mck_frequency = 84000000; +} + diff --git a/lib/sam3x/usart.c b/lib/sam3x/usart.c index ebef382c..012a07e0 100644 --- a/lib/sam3x/usart.c +++ b/lib/sam3x/usart.c @@ -18,6 +18,12 @@ */ #include +#include + +void usart_set_baudrate(u32 usart, u32 baud) +{ + USART_BRGR(usart) = pmc_mck_frequency / (16 * baud); +} void usart_set_databits(u32 usart, int bits) {