@@ -67,6 +67,8 @@ static uart_t _uart_bus_array[3] = {
67
67
};
68
68
#endif
69
69
70
+ static void uart_on_apb_change (void * arg , apb_change_ev_t ev_type , uint32_t old_apb , uint32_t new_apb );
71
+
70
72
static void IRAM_ATTR _uart_isr (void * arg )
71
73
{
72
74
uint8_t i , c ;
@@ -216,6 +218,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
216
218
uartAttachTx (uart , txPin , inverted );
217
219
}
218
220
221
+ addApbChangeCallback (uart , uart_on_apb_change );
219
222
return uart ;
220
223
}
221
224
@@ -224,6 +227,7 @@ void uartEnd(uart_t* uart)
224
227
if (uart == NULL ) {
225
228
return ;
226
229
}
230
+ removeApbChangeCallback (uart , uart_on_apb_change );
227
231
228
232
UART_MUTEX_LOCK ();
229
233
if (uart -> queue != NULL ) {
@@ -359,13 +363,44 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
359
363
UART_MUTEX_UNLOCK ();
360
364
}
361
365
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
+
362
397
uint32_t uartGetBaudRate (uart_t * uart )
363
398
{
364
399
if (uart == NULL ) {
365
400
return 0 ;
366
401
}
367
402
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 );
369
404
}
370
405
371
406
static void IRAM_ATTR uart0_write_char (char c )
0 commit comments