mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
bugfix(uart): uniform AT_CMD char configuration
This commit is contained in:
@@ -680,44 +680,46 @@ esp_err_t uart_disable_pattern_det_intr(uart_port_t uart_num);
|
||||
* @brief UART enable pattern detect function.
|
||||
* Designed for applications like 'AT commands'.
|
||||
* When the hardware detect a series of one same character, the interrupt will be triggered.
|
||||
* @note This function only works for esp32. And this function is deprecated, please use
|
||||
* uart_enable_pattern_det_baud_intr instead.
|
||||
*
|
||||
* @param uart_num UART port number.
|
||||
* @param pattern_chr character of the pattern
|
||||
* @param pattern_chr character of the pattern.
|
||||
* @param chr_num number of the character, 8bit value.
|
||||
* @param chr_tout timeout of the interval between each pattern characters, 24bit value, unit is APB (80Mhz) clock cycle.
|
||||
* When the duration is less than this value, it will not take this data as at_cmd char
|
||||
* When the duration is less than this value, it will not take this data as at_cmd char.
|
||||
* @param post_idle idle time after the last pattern character, 24bit value, unit is APB (80Mhz) clock cycle.
|
||||
* When the duration is less than this value, it will not take the previous data as the last at_cmd char
|
||||
* @param pre_idle idle time before the first pattern character, 24bit value, unit is APB (80Mhz) clock cycle.
|
||||
* When the duration is less than this value, it will not take this data as the first at_cmd char
|
||||
* When the duration is less than this value, it will not take this data as the first at_cmd char.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Parameter error
|
||||
*/
|
||||
esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle) __attribute__((deprecated));
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief UART enable pattern detect function.
|
||||
* Designed for applications like 'AT commands'.
|
||||
* When the hardware detect a series of one same character, the interrupt will be triggered.
|
||||
*
|
||||
* @param uart_num UART port number.
|
||||
* @param pattern_chr character of the pattern
|
||||
* @param pattern_chr character of the pattern.
|
||||
* @param chr_num number of the character, 8bit value.
|
||||
* @param chr_tout timeout of the interval between each pattern characters, 16bit value, unit is baud rate.
|
||||
* When the duration is more than this value, it will not take this data as at_cmd char
|
||||
* @param post_idle idle time after the last pattern character, 16bit value, unit is baud rate.
|
||||
* @param chr_tout timeout of the interval between each pattern characters, 16bit value, unit is the baud-rate cycle you configured.
|
||||
* When the duration is more than this value, it will not take this data as at_cmd char.
|
||||
* @param post_idle idle time after the last pattern character, 16bit value, unit is the baud-rate cycle you configured.
|
||||
* When the duration is less than this value, it will not take the previous data as the last at_cmd char
|
||||
* @param pre_idle idle time before the first pattern character, 16bit value, unit is baud rate.
|
||||
* When the duration is less than this value, it will not take this data as the first at_cmd char
|
||||
* @param pre_idle idle time before the first pattern character, 16bit value, unit is the baud-rate cycle you configured.
|
||||
* When the duration is less than this value, it will not take this data as the first at_cmd char.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Parameter error
|
||||
*/
|
||||
esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle);
|
||||
#endif
|
||||
esp_err_t uart_enable_pattern_det_baud_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle);
|
||||
|
||||
/**
|
||||
* @brief Return the nearest detected pattern position in buffer.
|
||||
|
@@ -36,8 +36,6 @@
|
||||
|
||||
#define UART_NUM SOC_UART_NUM
|
||||
|
||||
#define UART_NUM SOC_UART_NUM
|
||||
|
||||
#define XOFF (char)0x13
|
||||
#define XON (char)0x11
|
||||
|
||||
@@ -161,7 +159,6 @@ esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit)
|
||||
UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error", ESP_FAIL);
|
||||
|
||||
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
|
||||
#if UART_NUM > 2
|
||||
//workaround for hardware bug, when uart stop bit set as 2-bit mode.
|
||||
if (stop_bit == UART_STOP_BITS_2) {
|
||||
stop_bit = UART_STOP_BITS_1;
|
||||
@@ -169,7 +166,6 @@ esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit)
|
||||
} else {
|
||||
UART[uart_num]->rs485_conf.dl1_en = 0;
|
||||
}
|
||||
#endif
|
||||
UART[uart_num]->conf0.stop_bit_num = stop_bit;
|
||||
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
|
||||
return ESP_OK;
|
||||
@@ -516,8 +512,10 @@ esp_err_t uart_pattern_queue_reset(uart_port_t uart_num, int queue_length)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle)
|
||||
{
|
||||
//This function is deprecated, please use uart_enable_pattern_det_baud_intr instead.
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||
UART_CHECK(chr_tout >= 0 && chr_tout <= UART_RX_GAP_TOUT_V, "uart pattern set error\n", ESP_FAIL);
|
||||
UART_CHECK(post_idle >= 0 && post_idle <= UART_POST_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL);
|
||||
@@ -529,6 +527,37 @@ esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, u
|
||||
UART[uart_num]->at_cmd_precnt.pre_idle_num = pre_idle;
|
||||
return uart_enable_intr_mask(uart_num, UART_AT_CMD_CHAR_DET_INT_ENA_M);
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t uart_enable_pattern_det_baud_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle)
|
||||
{
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||
UART_CHECK(chr_tout >= 0 && chr_tout <= UART_RX_GAP_TOUT_V, "uart pattern set error\n", ESP_FAIL);
|
||||
UART_CHECK(post_idle >= 0 && post_idle <= UART_POST_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL);
|
||||
UART_CHECK(pre_idle >= 0 && pre_idle <= UART_PRE_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL);
|
||||
UART[uart_num]->at_cmd_char.data = pattern_chr;
|
||||
UART[uart_num]->at_cmd_char.char_num = chr_num;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
int apb_clk_freq = 0;
|
||||
uint32_t uart_baud = 0;
|
||||
uint32_t uart_div = 0;
|
||||
|
||||
uart_get_baudrate(uart_num, &uart_baud);
|
||||
apb_clk_freq = esp_clk_apb_freq();
|
||||
uart_div = apb_clk_freq / uart_baud;
|
||||
|
||||
UART[uart_num]->at_cmd_gaptout.rx_gap_tout = chr_tout * uart_div;
|
||||
UART[uart_num]->at_cmd_postcnt.post_idle_num = post_idle * uart_div;
|
||||
UART[uart_num]->at_cmd_precnt.pre_idle_num = pre_idle * uart_div;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
UART[uart_num]->at_cmd_gaptout.rx_gap_tout = chr_tout;
|
||||
UART[uart_num]->at_cmd_postcnt.post_idle_num = post_idle;
|
||||
UART[uart_num]->at_cmd_precnt.pre_idle_num = pre_idle;
|
||||
#endif
|
||||
|
||||
return uart_enable_intr_mask(uart_num, UART_AT_CMD_CHAR_DET_INT_ENA_M);
|
||||
}
|
||||
|
||||
esp_err_t uart_disable_pattern_det_intr(uart_port_t uart_num)
|
||||
{
|
||||
@@ -590,7 +619,9 @@ esp_err_t uart_isr_free(uart_port_t uart_num)
|
||||
{
|
||||
esp_err_t ret;
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||
if (p_uart_obj[uart_num]->intr_handle==NULL) return ESP_ERR_INVALID_ARG;
|
||||
if (p_uart_obj[uart_num]->intr_handle == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
|
||||
ret = esp_intr_free(p_uart_obj[uart_num]->intr_handle);
|
||||
p_uart_obj[uart_num]->intr_handle = NULL;
|
||||
@@ -709,7 +740,9 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
UART[uart_num]->conf0.val =
|
||||
(uart_config->parity << UART_PARITY_S)
|
||||
@@ -718,9 +751,13 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
|
||||
| (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;
|
||||
if (r != ESP_OK) {
|
||||
return r;
|
||||
}
|
||||
r = uart_set_tx_idle_num(uart_num, UART_TX_IDLE_NUM_DEFAULT);
|
||||
if (r != ESP_OK) return r;
|
||||
if (r != ESP_OK) {
|
||||
return r;
|
||||
}
|
||||
r = uart_set_stop_bits(uart_num, uart_config->stop_bits);
|
||||
//A hardware reset does not reset the fifo,
|
||||
//so we need to reset the fifo manually.
|
||||
@@ -842,8 +879,7 @@ static void uart_rx_intr_handler_default(void *param)
|
||||
en_tx_flg = true;
|
||||
p_uart->tx_len_cur = size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//Can not get data from ring buffer, return;
|
||||
break;
|
||||
}
|
||||
@@ -901,8 +937,7 @@ static void uart_rx_intr_handler_default(void *param)
|
||||
uart_enable_intr_mask_from_isr(uart_num, UART_TXFIFO_EMPTY_INT_ENA_M);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M)
|
||||
} else if ((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M)
|
||||
|| (uart_intr_status & UART_RXFIFO_FULL_INT_ST_M)
|
||||
|| (uart_intr_status & UART_AT_CMD_CHAR_DET_INT_ST_M)
|
||||
) {
|
||||
@@ -1442,7 +1477,9 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
||||
}
|
||||
|
||||
r = uart_isr_register(uart_num, uart_rx_intr_handler_default, p_uart_obj[uart_num], intr_alloc_flags, &p_uart_obj[uart_num]->intr_handle);
|
||||
if (r!=ESP_OK) goto err;
|
||||
if (r != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
uart_intr_config_t uart_intr = {
|
||||
.intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M
|
||||
| UART_RXFIFO_TOUT_INT_ENA_M
|
||||
@@ -1455,7 +1492,9 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
||||
.txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT
|
||||
};
|
||||
r = uart_intr_config(uart_num, &uart_intr);
|
||||
if (r!=ESP_OK) goto err;
|
||||
if (r != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
return r;
|
||||
|
||||
err:
|
||||
|
@@ -11,8 +11,9 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _SOC_UART_CAPS_H_
|
||||
#define _SOC_UART_CAPS_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -22,5 +23,3 @@ extern "C" {
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SOC_UART_CAPS_H_ */
|
||||
|
@@ -27,11 +27,19 @@ static wl_handle_t test_wl_handle;
|
||||
|
||||
TEST_CASE("Can use access() for UART", "[vfs]")
|
||||
{
|
||||
const char *uarts[] = {"/dev/uart/0", "/dev/uart/1", "/dev/uart/2"};
|
||||
const char *uarts[] = {
|
||||
"/dev/uart/0",
|
||||
"/dev/uart/1",
|
||||
#if SOC_UART_NUM > 2
|
||||
"/dev/uart/2"
|
||||
#endif
|
||||
};
|
||||
|
||||
uart_driver_install(UART_NUM_0, 256, 0, 0, NULL, 0);
|
||||
uart_driver_install(UART_NUM_1, 256, 0, 0, NULL, 0);
|
||||
#if SOC_UART_NUM > 2
|
||||
uart_driver_install(UART_NUM_2, 256, 0, 0, NULL, 0);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < sizeof(uarts)/sizeof(uarts[0]); ++i) {
|
||||
TEST_ASSERT_EQUAL_MESSAGE(access(uarts[i], F_OK), 0, uarts[i]);
|
||||
@@ -55,7 +63,9 @@ TEST_CASE("Can use access() for UART", "[vfs]")
|
||||
|
||||
uart_driver_delete(UART_NUM_0);
|
||||
uart_driver_delete(UART_NUM_1);
|
||||
#if SOC_UART_NUM > 2
|
||||
uart_driver_delete(UART_NUM_2);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void test_spi_flash_setup()
|
||||
|
@@ -169,7 +169,7 @@ The API provides a convenient way to handle specific interrupts discussed above
|
||||
|
||||
* **FIFO space threshold or transmission timeout reached** - the interrupts on TX or Rx FIFO buffer being filled with specific number of characters or on a timeout of sending or receiving data. To use these interrupts, first configure respective threshold values of the buffer length and the timeout by entering them in :cpp:type:`uart_intr_config_t` structure and calling :cpp:func:`uart_intr_config`. Then enable interrupts with functions :cpp:func:`uart_enable_rx_intr` and :cpp:func:`uart_enable_tx_intr`. To disable these interrupts there are corresponding functions :cpp:func:`uart_disable_rx_intr` or :cpp:func:`uart_disable_tx_intr`.
|
||||
|
||||
* **Pattern detection** - an interrupt triggered on detecting a 'pattern' of the same character being sent number of times. The functions that allow to configure, enable and disable this interrupt are :cpp:func:`uart_enable_pattern_det_intr` and cpp:func:`uart_disable_pattern_det_intr`.
|
||||
* **Pattern detection** - an interrupt triggered on detecting a 'pattern' of the same character being sent number of times. The functions that allow to configure, enable and disable this interrupt are :cpp:func:`uart_enable_pattern_det_baud_intr` and cpp:func:`uart_disable_pattern_det_intr`.
|
||||
|
||||
Macros
|
||||
^^^^^^
|
||||
|
@@ -699,7 +699,7 @@ nmea_parser_handle_t nmea_parser_init(const nmea_parser_config_t *config)
|
||||
goto err_uart_install;
|
||||
}
|
||||
/* Set pattern interrupt, used to detect the end of a line */
|
||||
uart_enable_pattern_det_intr(esp_gps->uart_port, '\n', 1, 10000, 10, 10);
|
||||
uart_enable_pattern_det_baud_intr(esp_gps->uart_port, '\n', 1, 9, 0, 0);
|
||||
/* Set pattern queue size */
|
||||
uart_pattern_queue_reset(esp_gps->uart_port, config->uart.event_queue_size);
|
||||
uart_flush(esp_gps->uart_port);
|
||||
|
@@ -47,7 +47,7 @@
|
||||
#define PACKET_READ_TICS (100 / portTICK_RATE_MS)
|
||||
#define ECHO_TASK_STACK_SIZE (2048)
|
||||
#define ECHO_TASK_PRIO (10)
|
||||
#define ECHO_UART_PORT (UART_NUM_2)
|
||||
#define ECHO_UART_PORT (UART_NUM_MAX - 1)
|
||||
|
||||
static const char *TAG = "RS485_ECHO_APP";
|
||||
|
||||
|
@@ -140,11 +140,7 @@ void app_main()
|
||||
uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0);
|
||||
|
||||
//Set uart pattern detect function.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uart_enable_pattern_det_intr(EX_UART_NUM, '+', PATTERN_CHR_NUM, 10000, 10, 10);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
uart_enable_pattern_det_intr(EX_UART_NUM, '+', PATTERN_CHR_NUM, 9, 0, 0);
|
||||
#endif
|
||||
uart_enable_pattern_det_baud_intr(EX_UART_NUM, '+', PATTERN_CHR_NUM, 9, 0, 0);
|
||||
//Reset the pattern queue length to record at most 20 pattern positions.
|
||||
uart_pattern_queue_reset(EX_UART_NUM, 20);
|
||||
|
||||
|
@@ -28,9 +28,9 @@
|
||||
#define ESP_MODEM_LINE_BUFFER_SIZE (CONFIG_EXAMPLE_UART_RX_BUFFER_SIZE / 2)
|
||||
#define ESP_MODEM_EVENT_QUEUE_SIZE (16)
|
||||
|
||||
#define MIN_PATTERN_INTERVAL (10000)
|
||||
#define MIN_POST_IDLE (10)
|
||||
#define MIN_PRE_IDLE (10)
|
||||
#define MIN_PATTERN_INTERVAL (9)
|
||||
#define MIN_POST_IDLE (0)
|
||||
#define MIN_PRE_IDLE (0)
|
||||
|
||||
/**
|
||||
* @brief Macro defined for error checking
|
||||
@@ -264,12 +264,12 @@ static esp_err_t esp_modem_dte_send_wait(modem_dte_t *dte, const char *data, uin
|
||||
MODEM_CHECK(res >= len, "wait prompt [%s] timeout", err, prompt);
|
||||
MODEM_CHECK(!strncmp(prompt, (const char *)buffer, len), "get wrong prompt: %s", err, buffer);
|
||||
free(buffer);
|
||||
uart_enable_pattern_det_intr(esp_dte->uart_port, '\n', 1, MIN_PATTERN_INTERVAL, MIN_POST_IDLE, MIN_PRE_IDLE);
|
||||
uart_enable_pattern_det_baud_intr(esp_dte->uart_port, '\n', 1, MIN_PATTERN_INTERVAL, MIN_POST_IDLE, MIN_PRE_IDLE);
|
||||
return ESP_OK;
|
||||
err:
|
||||
free(buffer);
|
||||
err_write:
|
||||
uart_enable_pattern_det_intr(esp_dte->uart_port, '\n', 1, MIN_PATTERN_INTERVAL, MIN_POST_IDLE, MIN_PRE_IDLE);
|
||||
uart_enable_pattern_det_baud_intr(esp_dte->uart_port, '\n', 1, MIN_PATTERN_INTERVAL, MIN_POST_IDLE, MIN_PRE_IDLE);
|
||||
err_param:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -298,7 +298,7 @@ static esp_err_t esp_modem_dte_change_mode(modem_dte_t *dte, modem_mode_t new_mo
|
||||
case MODEM_COMMAND_MODE:
|
||||
uart_disable_rx_intr(esp_dte->uart_port);
|
||||
uart_flush(esp_dte->uart_port);
|
||||
uart_enable_pattern_det_intr(esp_dte->uart_port, '\n', 1, MIN_PATTERN_INTERVAL, MIN_POST_IDLE, MIN_PRE_IDLE);
|
||||
uart_enable_pattern_det_baud_intr(esp_dte->uart_port, '\n', 1, MIN_PATTERN_INTERVAL, MIN_POST_IDLE, MIN_PRE_IDLE);
|
||||
uart_pattern_queue_reset(esp_dte->uart_port, CONFIG_EXAMPLE_UART_PATTERN_QUEUE_SIZE);
|
||||
MODEM_CHECK(dce->set_working_mode(dce, new_mode) == ESP_OK, "set new working mode:%d failed", err, new_mode);
|
||||
break;
|
||||
@@ -392,7 +392,7 @@ modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config)
|
||||
CONFIG_EXAMPLE_UART_EVENT_QUEUE_SIZE, &(esp_dte->event_queue), 0);
|
||||
MODEM_CHECK(res == ESP_OK, "install uart driver failed", err_uart_config);
|
||||
/* Set pattern interrupt, used to detect the end of a line. */
|
||||
res = uart_enable_pattern_det_intr(esp_dte->uart_port, '\n', 1, MIN_PATTERN_INTERVAL, MIN_POST_IDLE, MIN_PRE_IDLE);
|
||||
res = uart_enable_pattern_det_baud_intr(esp_dte->uart_port, '\n', 1, MIN_PATTERN_INTERVAL, MIN_POST_IDLE, MIN_PRE_IDLE);
|
||||
/* Set pattern queue size */
|
||||
res |= uart_pattern_queue_reset(esp_dte->uart_port, CONFIG_EXAMPLE_UART_PATTERN_QUEUE_SIZE);
|
||||
MODEM_CHECK(res == ESP_OK, "config uart pattern failed", err_uart_pattern);
|
||||
|
Reference in New Issue
Block a user