@@ -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+
7072static 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+
362397uint32_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
371406static void IRAM_ATTR uart0_write_char (char c )
0 commit comments