enjoy-digital / litex

Build your hardware, easily!
Other
3.03k stars 573 forks source link

feat: add uart_with_dynamic_baudrate to SoCCore #2122

Closed jwise closed 2 weeks ago

jwise commented 3 weeks ago

In our application, we would like our default UART to have a configurable baud rate based on other system parameters. Sample code to drive this:

static uint32_t current_uart_baudrate = 921600;

static struct tuning {
    uint32_t baudrate;
    uint32_t tuning;
} predefined_tunings[] = {
    { 1500000, 85899346 },
    { 921600, 52776558 },
    { 115200, 6597070 }
};

static void update_uart_baudrate(uint32_t desired_baudrate) {
    uint32_t new_tuning = 0;
    for (int i = 0; i < sizeof(predefined_tunings) / sizeof(predefined_tunings[0]); i++) {
        if (predefined_tunings[i].baudrate == desired_baudrate) {
            new_tuning = predefined_tunings[i].tuning;
        }
    }

    if (new_tuning == 0) {
        uint64_t new_baudrate = (uint64_t)desired_baudrate << 32;
        new_tuning = new_baudrate / 75000000l;
    }
    if (new_tuning) {
        uartbone_phy_tuning_word_write(new_tuning);
        current_uart_baudrate = desired_baudrate;
    }
}

static void baud_cmd(char *arg)
{
    int baud = atoi(arg);
    update_uart_baudrate(baud);
    printf("baud rate is now %d\n", baud);
}
DEFINE_COMMAND(baud_cmd, "baud", "set UART baud rate");

cc: @jameyhicks