Skip to content

Commit

Permalink
ESP32: Use REF_TICK for UART, when possible
Browse files Browse the repository at this point in the history
REF_TICK is a 1 mhz clock source that remains stable when dynamic
clock scaling is enabled.

We can use it to generate baud rates up to certain threshold.
Experimentally tested threshold to be ~500K (with FTDI232 and CP2102).
This covers standard baud rates up to and including 460800.

Fixes #511
  • Loading branch information
rojer committed Oct 27, 2020
1 parent bbbec02 commit 5b937f0
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions platforms/esp32/src/esp32_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,13 @@ bool mgos_uart_hal_init(struct mgos_uart_state *us) {
return true;
}

static inline void calc_clkdiv(uint32_t freq, uint32_t baud_rate, uint32_t *div,
uint32_t *frac) {
uint32_t v = ((freq << 4) / baud_rate);
*div = v >> 4;
*frac = v & 0xf;
}

bool mgos_uart_hal_configure(struct mgos_uart_state *us,
const struct mgos_uart_config *cfg) {
int uart_no = us->uart_no;
Expand All @@ -410,10 +417,21 @@ bool mgos_uart_hal_configure(struct mgos_uart_state *us,

DPORT_WRITE_PERI_REG(UART_INT_ENA_REG(uart_no), 0);

uint32_t conf0 =
DPORT_READ_PERI_REG(UART_CONF0_REG(uart_no)) & UART_TICK_REF_ALWAYS_ON;

if (cfg->baud_rate > 0) {
uint32_t clk_div = (((UART_CLK_FREQ) << 4) / cfg->baud_rate);
uint32_t clkdiv_v = ((clk_div & UART_CLKDIV_FRAG_V) << UART_CLKDIV_FRAG_S) |
(((clk_div >> 4) & UART_CLKDIV_V) << UART_CLKDIV_S);
/* Try to use REF_TICK if possible, fall back to APB. */
uint32_t div, frac;
calc_clkdiv(REF_CLK_FREQ, cfg->baud_rate, &div, &frac);
if (div >= 2) {
conf0 &= ~UART_TICK_REF_ALWAYS_ON;
} else {
calc_clkdiv(APB_CLK_FREQ, cfg->baud_rate, &div, &frac);
conf0 |= UART_TICK_REF_ALWAYS_ON;
}
uint32_t clkdiv_v = ((frac & UART_CLKDIV_FRAG_V) << UART_CLKDIV_FRAG_S) |
((div & UART_CLKDIV_V) << UART_CLKDIV_S);
DPORT_WRITE_PERI_REG(UART_CLKDIV_REG(uart_no), clkdiv_v);
}

Expand All @@ -426,8 +444,6 @@ bool mgos_uart_hal_configure(struct mgos_uart_state *us,
return false;
}

uint32_t conf0 = UART_TICK_REF_ALWAYS_ON;

if (cfg->dev.tx_inverted) {
conf0 |= UART_TXD_INV;
}
Expand Down

0 comments on commit 5b937f0

Please sign in to comment.