uart: add support for REF_TICK

This commit is contained in:
Ivan Grokhotkov
2017-08-21 22:30:23 +08:00
parent bfeecd2b56
commit fba9678c56
4 changed files with 43 additions and 18 deletions

View File

@@ -106,7 +106,8 @@ typedef struct {
uart_parity_t parity; /*!< UART parity mode*/ uart_parity_t parity; /*!< UART parity mode*/
uart_stop_bits_t stop_bits; /*!< UART stop bits*/ uart_stop_bits_t stop_bits; /*!< UART stop bits*/
uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode (cts/rts)*/ 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; } uart_config_t;
/** /**

View File

@@ -18,6 +18,7 @@
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_clk.h"
#include "malloc.h" #include "malloc.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/semphr.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) 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((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
UART_CHECK((baud_rate <= UART_BITRATE_MAX), "baud_rate error", ESP_FAIL); esp_err_t ret = ESP_OK;
uint32_t clk_div = (((UART_CLK_FREQ) << 4) / baud_rate);
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
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_int = clk_div >> 4;
UART[uart_num]->clk_div.div_frag = clk_div & 0xf; UART[uart_num]->clk_div.div_frag = clk_div & 0xf;
}
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); 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) 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) { } else if(uart_num == UART_NUM_2) {
periph_module_enable(PERIPH_UART2_MODULE); periph_module_enable(PERIPH_UART2_MODULE);
} }
r=uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); r = uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh);
if (r!=ESP_OK) return r; 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[uart_num]->conf0.val =
(uart_config->parity << UART_PARITY_S) (uart_config->parity << UART_PARITY_S)
| (uart_config->data_bits << UART_BIT_NUM_S) | (uart_config->data_bits << UART_BIT_NUM_S)
| ((uart_config->flow_ctrl & UART_HW_FLOWCTRL_CTS) ? UART_TX_FLOW_EN : 0x0) | ((uart_config->flow_ctrl & UART_HW_FLOWCTRL_CTS) ? UART_TX_FLOW_EN : 0x0)
| UART_TICK_REF_ALWAYS_ON_M); | (uart_config->use_ref_tick ? 0 : UART_TICK_REF_ALWAYS_ON_M);
r=uart_set_stop_bits(uart_num, uart_config->stop_bits);
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; return r;
} }

View File

@@ -289,9 +289,18 @@ void start_cpu0_default(void)
esp_clk_init(); esp_clk_init();
esp_perip_clk_init(); esp_perip_clk_init();
intr_matrix_clear(); intr_matrix_clear();
#ifndef CONFIG_CONSOLE_UART_NONE #ifndef CONFIG_CONSOLE_UART_NONE
uart_div_modify(CONFIG_CONSOLE_UART_NUM, (rtc_clk_apb_freq_get() << 4) / CONFIG_CONSOLE_UART_BAUDRATE); #ifdef CONFIG_PM_ENABLE
#endif 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 #if CONFIG_BROWNOUT_DET
esp_brownout_init(); esp_brownout_init();
#endif #endif

View File

@@ -266,6 +266,7 @@
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM #define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ APB_CLK_FREQ #define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz #define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz
#define REF_CLK_FREQ ( 1000000 )
#define UART_CLK_FREQ APB_CLK_FREQ #define UART_CLK_FREQ APB_CLK_FREQ
#define WDT_CLK_FREQ APB_CLK_FREQ #define WDT_CLK_FREQ APB_CLK_FREQ
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16 #define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16