From: Ivan Grokhotkov Date: Mon, 21 Aug 2017 14:30:23 +0000 (+0800) Subject: uart: add support for REF_TICK X-Git-Tag: v3.1-dev~144^2~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fba9678c5660b463a7fbd2102d4b67d0d2442e18;p=esp-idf uart: add support for REF_TICK --- diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 6c17fd6566..a4227b3481 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -106,7 +106,8 @@ typedef struct { uart_parity_t parity; /*!< UART parity mode*/ uart_stop_bits_t stop_bits; /*!< UART stop bits*/ uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode (cts/rts)*/ - uint8_t rx_flow_ctrl_thresh ; /*!< UART HW RTS threshold*/ + uint8_t rx_flow_ctrl_thresh; /*!< UART HW RTS threshold*/ + bool use_ref_tick; /*!< Set to true if UART should be clocked from REF_TICK */ } uart_config_t; /** diff --git a/components/driver/uart.c b/components/driver/uart.c index 1d4503e97a..300a19ce8b 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -18,6 +18,7 @@ #include "esp_intr_alloc.h" #include "esp_log.h" #include "esp_err.h" +#include "esp_clk.h" #include "malloc.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" @@ -172,13 +173,25 @@ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode) esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((baud_rate <= UART_BITRATE_MAX), "baud_rate error", ESP_FAIL); - uint32_t clk_div = (((UART_CLK_FREQ) << 4) / baud_rate); + esp_err_t ret = ESP_OK; UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->clk_div.div_int = clk_div >> 4; - UART[uart_num]->clk_div.div_frag = clk_div & 0xf; + int uart_clk_freq; + if (UART[uart_num]->conf0.tick_ref_always_on == 0) { + /* this UART has been configured to use REF_TICK */ + uart_clk_freq = REF_CLK_FREQ; + } else { + uart_clk_freq = esp_clk_apb_freq(); + } + uint32_t clk_div = (((uart_clk_freq) << 4) / baud_rate); + if (clk_div < 16) { + /* baud rate is too high for this clock frequency */ + ret = ESP_ERR_INVALID_ARG; + } else { + UART[uart_num]->clk_div.div_int = clk_div >> 4; + UART[uart_num]->clk_div.div_frag = clk_div & 0xf; + } UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; + return ret; } esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate) @@ -468,17 +481,18 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf } else if(uart_num == UART_NUM_2) { periph_module_enable(PERIPH_UART2_MODULE); } - r=uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); - if (r!=ESP_OK) return r; - r=uart_set_baudrate(uart_num, uart_config->baud_rate); - if (r!=ESP_OK) return r; - - UART[uart_num]->conf0.val = ( - (uart_config->parity << UART_PARITY_S) - | (uart_config->data_bits << UART_BIT_NUM_S) - | ((uart_config->flow_ctrl & UART_HW_FLOWCTRL_CTS) ? UART_TX_FLOW_EN : 0x0) - | UART_TICK_REF_ALWAYS_ON_M); - r=uart_set_stop_bits(uart_num, uart_config->stop_bits); + r = uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); + if (r != ESP_OK) return r; + + UART[uart_num]->conf0.val = + (uart_config->parity << UART_PARITY_S) + | (uart_config->data_bits << UART_BIT_NUM_S) + | ((uart_config->flow_ctrl & UART_HW_FLOWCTRL_CTS) ? UART_TX_FLOW_EN : 0x0) + | (uart_config->use_ref_tick ? 0 : UART_TICK_REF_ALWAYS_ON_M); + + r = uart_set_baudrate(uart_num, uart_config->baud_rate); + if (r != ESP_OK) return r; + r = uart_set_stop_bits(uart_num, uart_config->stop_bits); return r; } diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 4a56143cfd..c839c14dde 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -289,9 +289,18 @@ void start_cpu0_default(void) esp_clk_init(); esp_perip_clk_init(); intr_matrix_clear(); + #ifndef CONFIG_CONSOLE_UART_NONE - uart_div_modify(CONFIG_CONSOLE_UART_NUM, (rtc_clk_apb_freq_get() << 4) / CONFIG_CONSOLE_UART_BAUDRATE); -#endif +#ifdef CONFIG_PM_ENABLE + const int uart_clk_freq = REF_CLK_FREQ; + /* When DFS is enabled, use REFTICK as UART clock source */ + CLEAR_PERI_REG_MASK(UART_CONF0_REG(CONFIG_CONSOLE_UART_NUM), UART_TICK_REF_ALWAYS_ON); +#else + const int uart_clk_freq = APB_CLK_FREQ; +#endif // CONFIG_PM_DFS_ENABLE + uart_div_modify(CONFIG_CONSOLE_UART_NUM, (uart_clk_freq << 4) / CONFIG_CONSOLE_UART_BAUDRATE); +#endif // CONFIG_CONSOLE_UART_NONE + #if CONFIG_BROWNOUT_DET esp_brownout_init(); #endif diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index 0e633821fd..d402262df9 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -266,6 +266,7 @@ #define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM #define CPU_CLK_FREQ APB_CLK_FREQ #define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz +#define REF_CLK_FREQ ( 1000000 ) #define UART_CLK_FREQ APB_CLK_FREQ #define WDT_CLK_FREQ APB_CLK_FREQ #define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16