Skip to content

Commit 344c76d

Browse files
committed
Add initial handling for UART baud change
1 parent 55c725f commit 344c76d

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

Diff for: cores/esp32/esp32-hal-cpu.c

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static void triggerApbChangeCallback(apb_change_ev_t ev_type, uint32_t old_apb,
5454
apb_change_t * r = apb_change_callbacks;
5555
while(r != NULL){
5656
r->cb(r->arg, ev_type, old_apb, new_apb);
57+
r=r->next;
5758
}
5859
xSemaphoreGive(apb_change_lock);
5960
}

Diff for: cores/esp32/esp32-hal-uart.c

+36-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ static uart_t _uart_bus_array[3] = {
6767
};
6868
#endif
6969

70+
static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb);
71+
7072
static void IRAM_ATTR _uart_isr(void *arg)
7173
{
7274
uint8_t i, c;
@@ -216,6 +218,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
216218
uartAttachTx(uart, txPin, inverted);
217219
}
218220

221+
addApbChangeCallback(uart, uart_on_apb_change);
219222
return uart;
220223
}
221224

@@ -224,6 +227,7 @@ void uartEnd(uart_t* uart)
224227
if(uart == NULL) {
225228
return;
226229
}
230+
removeApbChangeCallback(uart, uart_on_apb_change);
227231

228232
UART_MUTEX_LOCK();
229233
if(uart->queue != NULL) {
@@ -359,13 +363,44 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
359363
UART_MUTEX_UNLOCK();
360364
}
361365

366+
static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb)
367+
{
368+
uart_t* uart = (uart_t*)arg;
369+
if(ev_type == APB_BEFORE_CHANGE){
370+
//todo:
371+
UART_MUTEX_LOCK();
372+
// detach RX
373+
// read RX fifo
374+
uint8_t c;
375+
BaseType_t xHigherPriorityTaskWoken;
376+
while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
377+
c = uart->dev->fifo.rw_byte;
378+
if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) {
379+
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
380+
}
381+
}
382+
// wait TX empty
383+
while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out);
384+
} else {
385+
//todo:
386+
// set baudrate
387+
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
388+
uint32_t baud_rate = ((old_apb<<4)/clk_div);
389+
clk_div = ((new_apb<<4)/baud_rate);
390+
uart->dev->clk_div.div_int = clk_div>>4 ;
391+
uart->dev->clk_div.div_frag = clk_div & 0xf;
392+
// attach rx
393+
UART_MUTEX_UNLOCK();
394+
}
395+
}
396+
362397
uint32_t uartGetBaudRate(uart_t* uart)
363398
{
364399
if(uart == NULL) {
365400
return 0;
366401
}
367402
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
368-
return ((UART_CLK_FREQ<<4)/clk_div);
403+
return ((getApbFrequency()<<4)/clk_div);
369404
}
370405

371406
static void IRAM_ATTR uart0_write_char(char c)

0 commit comments

Comments
 (0)