Skip to content

Commit

Permalink
fix uart baudrate calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
lcgamboa committed Jul 1, 2024
1 parent 256a179 commit 25496d3
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 13 deletions.
34 changes: 24 additions & 10 deletions hw/char/esp32_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,23 @@ static uint64_t uart_read(void *opaque, hwaddr addr, unsigned int size)
return r;
}

static unsigned int uart_calc_baud(ESP32UARTState *s)
{
unsigned clkdiv = (FIELD_EX32(s->reg[R_UART_CLKDIV], UART_CLKDIV, CLKDIV) << 4) +
FIELD_EX32(s->reg[R_UART_CLKDIV], UART_CLKDIV, CLKDIV_FRAG);
unsigned baud_rate = 115200;
if (clkdiv != 0) {
/* FIXME: this should depend on the APB frequency */
if(FIELD_EX32(s->reg[R_UART_CONF0], UART_CONF0, TICK_REF_ALWAYS_ON)){
baud_rate = (unsigned) ((80000000ULL << 4) / clkdiv);
}
else{
baud_rate = (unsigned) ((1000000ULL << 4) / clkdiv); //REF_TICK
}
}
return baud_rate;
}


static void uart_write(void *opaque, hwaddr addr,
uint64_t value, unsigned int size)
Expand Down Expand Up @@ -162,18 +179,11 @@ static void uart_write(void *opaque, hwaddr addr,
s->reg[addr / 4] = value;
break;

case A_UART_CLKDIV: {
case A_UART_CONF0:
case A_UART_CLKDIV:
s->reg[addr / 4] = value;
unsigned clkdiv = (FIELD_EX32(s->reg[R_UART_CLKDIV], UART_CLKDIV, CLKDIV) << 4) +
FIELD_EX32(s->reg[R_UART_CLKDIV], UART_CLKDIV, CLKDIV_FRAG);
unsigned baud_rate = 115200;
if (clkdiv != 0) {
/* FIXME: this should depend on the APB frequency */
baud_rate = (unsigned) ((80000000ULL << 4) / clkdiv);
}
s->baud_rate = baud_rate;
s->baud_rate = uart_calc_baud(s);
break;
}

case A_UART_AUTOBAUD:
/* If autobaud is enabled, pretend that sufficient number of edges on the RXD line
Expand Down Expand Up @@ -336,6 +346,10 @@ static void esp32_uart_reset(DeviceState *dev)
s->reg[R_UART_AUTOBAUD] = 0;
/* Default baud rate divider after reset */
s->reg[R_UART_CLKDIV] = FIELD_DP32(0, UART_CLKDIV, CLKDIV, 0x2B6);
s->reg[R_UART_CONF0] = FIELD_DP32(0 , UART_CONF0, TICK_REF_ALWAYS_ON, 1);
s->reg[R_UART_CONF0] = FIELD_DP32(s->reg[R_UART_CONF0] , UART_CONF0, STOP_BIT_NUM, 1);
s->reg[R_UART_CONF0] = FIELD_DP32(s->reg[R_UART_CONF0] , UART_CONF0, BIT_NUM, 3);

s->baud_rate = 115200;
fifo8_reset(&s->tx_fifo);
fifo8_reset(&s->rx_fifo);
Expand Down
6 changes: 3 additions & 3 deletions hw/char/esp32c3_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ static unsigned int esp32c3_uart_calc_baud(ESP32C3UARTState *s)
unsigned baud_rate = 115200;
unsigned int sclk_div_num = FIELD_EX32(s->parent.reg[R_ESP32C3_UART_CLK_CONF], ESP32C3_UART_CLK_CONF, UART_SCLK_DIV_NUM);
if (clkdiv != 0) {

switch( FIELD_EX32(s->parent.reg[R_ESP32C3_UART_CLK_CONF], ESP32C3_UART_CLK_CONF, UART_SCLK_SEL)){
int clk_sel = FIELD_EX32(s->parent.reg[R_ESP32C3_UART_CLK_CONF], ESP32C3_UART_CLK_CONF, UART_SCLK_SEL);
switch( clk_sel){
case 0:
case 1: // APB_CLK
baud_rate = (unsigned) ((80000000ULL << 4) / (clkdiv * (sclk_div_num + 1 )));
break;
Expand Down Expand Up @@ -84,7 +85,6 @@ static void esp32c3_uart_write(void *opaque, hwaddr addr,
* register, poke that register instead */
autobaud = FIELD_EX32(value, ESP32C3_UART_CONF0, AUTOBAUD_EN) ? 1 : 0;
class->parent_uart_write(opaque, ESP32_UART_AUTOBAUD, autobaud, sizeof(uint32_t));
class->parent_uart_write(opaque, addr, value, size);
s->parent.reg[addr / 4] = value;
break;

Expand Down
25 changes: 25 additions & 0 deletions include/hw/char/esp32_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,31 @@ REG32(UART_RXD_CNT, 0x30)

/* TODO: implement */
REG32(UART_CONF0, 0x20)
FIELD(UART_CONF0, TICK_REF_ALWAYS_ON, 27, 1);
FIELD(UART_CONF0, DTR_INV, 24, 1);
FIELD(UART_CONF0, RTS_INV, 23, 1);
FIELD(UART_CONF0, TXD_INV, 22, 1);
FIELD(UART_CONF0, DSR_INV, 21, 1);
FIELD(UART_CONF0, CTS_INV, 20, 1);
FIELD(UART_CONF0, RXD_INV, 19, 1);
FIELD(UART_CONF0, TXFIFO_RST, 18, 1);
FIELD(UART_CONF0, RXFIFO_RST, 17, 1);
FIELD(UART_CONF0, IRDA_EN, 16, 1);
FIELD(UART_CONF0, TX_FLOW_EN, 15, 1);
FIELD(UART_CONF0, LOOPBACK, 14, 1);
FIELD(UART_CONF0, IRDA_RX_INV, 13, 1);
FIELD(UART_CONF0, IRDA_TX_INV, 12, 1);
FIELD(UART_CONF0, IRDA_WCTL, 11, 1);
FIELD(UART_CONF0, IRDA_TX_EN, 10, 1);
FIELD(UART_CONF0, IRDA_DPLX, 9, 1);
FIELD(UART_CONF0, TXD_BRK, 8, 1);
FIELD(UART_CONF0, SW_DTR, 7, 1);
FIELD(UART_CONF0, SW_RTS, 6, 1);
FIELD(UART_CONF0, STOP_BIT_NUM, 4, 2);
FIELD(UART_CONF0, BIT_NUM, 2, 2);
FIELD(UART_CONF0, PARITY_EN, 1, 1);
FIELD(UART_CONF0, PARITY, 0, 1);

REG32(UART_CONF1, 0x24)
FIELD(UART_CONF1, TOUT_EN, 31, 1)
FIELD(UART_CONF1, TOUT_THRD, 24, 7)
Expand Down

0 comments on commit 25496d3

Please sign in to comment.