atsam: Add get_pclock_frequency() helper function

Add get_pclock_frequency() and use it to calculate peripheral clocks.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2021-11-20 13:47:17 -05:00
parent 92ca111986
commit bb08dc7ae9
7 changed files with 22 additions and 12 deletions

View File

@ -47,7 +47,7 @@ gpio_adc_setup(uint8_t pin)
if (!is_enabled_pclock(ID_ADC)) {
// Setup ADC
enable_pclock(ID_ADC);
uint32_t prescal = SystemCoreClock / (2 * ADC_FREQ_MAX) - 1;
uint32_t prescal = get_pclock_frequency(ID_ADC) / (2*ADC_FREQ_MAX) - 1;
ADC->ADC_MR = (ADC_MR_PRESCAL(prescal)
| ADC_MR_STARTUP_SUT768
| ADC_MR_TRANSFER(1));

View File

@ -48,8 +48,9 @@ i2c_init(Twi *p_twi, uint32_t rate)
p_twi->TWI_CR = TWI_CR_SVDIS;
p_twi->TWI_CR = TWI_CR_MSEN;
uint32_t pclk = get_pclock_frequency(p_twi == TWI0 ? ID_TWI0 : ID_TWI1);
uint32_t cldiv = 0, chdiv = 0, ckdiv = 0;
cldiv = SystemCoreClock / ((rate > 384000 ? 384000 : rate) * 2) - 4;
cldiv = pclk / ((rate > 384000 ? 384000 : rate) * 2) - 4;
while ((cldiv > 255) && (ckdiv < 7)) {
ckdiv++;
@ -57,7 +58,7 @@ i2c_init(Twi *p_twi, uint32_t rate)
}
if (rate > 348000) {
chdiv = SystemCoreClock / ((2 * rate - 384000) * 2) - 4;
chdiv = pclk / ((2 * rate - 384000) * 2) - 4;
while ((chdiv > 255) && (ckdiv < 7)) {
ckdiv++;
chdiv /= 2;

View File

@ -20,5 +20,6 @@
void gpio_peripheral(uint32_t gpio, char ptype, int32_t pull_up);
int is_enabled_pclock(uint32_t id);
void enable_pclock(uint32_t id);
uint32_t get_pclock_frequency(uint32_t id);
#endif // internal.h

View File

@ -56,6 +56,13 @@ enable_pclock(uint32_t id)
PMC->PMC_PCER1 = 1 << (id - 32);
}
// Return the frequency of the given peripheral clock
uint32_t
get_pclock_frequency(uint32_t id)
{
return CONFIG_CLOCK_FREQ;
}
/****************************************************************
* Resets

View File

@ -72,8 +72,9 @@ init_afec(Afec* afec) {
afec->AFE_CR = AFE_CR_SWRST;
// Configure afec
uint32_t pclk = get_pclock_frequency(afec == AFEC0 ? ID_AFEC0 : ID_AFEC1);
afec->AFE_MR = AFE_MR_ANACH_ALLOWED | \
AFE_MR_PRESCAL (SystemCoreClock / (2 * ADC_FREQ_MAX) -1) | \
AFE_MR_PRESCAL(pclk / (2 * ADC_FREQ_MAX) - 1) | \
AFE_MR_SETTLING_AST3 | \
AFE_MR_TRACKTIM(2) | \
AFE_MR_TRANSFER(1) | \

View File

@ -68,7 +68,7 @@ serial_init(void)
// Enable uart
Port->UART_MR = (UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL);
Port->UART_BRGR = SystemCoreClock / (16 * CONFIG_SERIAL_BAUD);
Port->UART_BRGR = get_pclock_frequency(Pmc_id) / (16 * CONFIG_SERIAL_BAUD);
Port->UART_IER = UART_IER_RXRDY;
armcm_enable_irq(UARTx_Handler, UARTx_IRQn, 0);
Port->UART_CR = UART_CR_RXEN | UART_CR_TXEN;

View File

@ -123,19 +123,18 @@ spihw_setup(uint32_t bus, uint8_t mode, uint32_t rate)
// Make sure bus is enabled
spihw_init(bus);
uint32_t config = 0;
uint32_t clockDiv;
if (rate < (CHIP_FREQ_CPU_MAX / 255)) {
uint32_t clockDiv, pclk = get_pclock_frequency(ID_USART0);
if (rate < pclk / 255) {
clockDiv = 255;
} else if (rate >= (CHIP_FREQ_CPU_MAX / 2)) {
} else if (rate >= pclk / 2) {
clockDiv = 2;
} else {
clockDiv = (CHIP_FREQ_CPU_MAX / (rate + 1)) + 1;
clockDiv = pclk / (rate + 1) + 1;
}
/****** Will be written to SPI_CSRx register ******/
// CSAAT : Chip Select Active After Transfer
config = SPI_CSR_CSAAT;
uint32_t config = SPI_CSR_CSAAT;
config |= SPI_CSR_BITS_8_BIT; // TODO: support for SPI_CSR_BITS_16_BIT
// NOTE: NCPHA is inverted, CPHA normal!!
switch(mode) {
@ -208,7 +207,8 @@ usart_setup(uint32_t bus, uint8_t mode, uint32_t rate)
p_usart->US_CR = US_CR_RSTTX | US_CR_RSTRX | US_CR_TXDIS | US_CR_RXDIS;
uint32_t br = DIV_ROUND_UP(CHIP_FREQ_CPU_MAX, rate);
uint32_t pclk = get_pclock_frequency(ID_USART0);
uint32_t br = DIV_ROUND_UP(pclk, rate);
p_usart->US_BRGR = br << US_BRGR_CD_Pos;
uint32_t reg = US_MR_CHRL_8_BIT |