Updated UART API documentation and examples. Included a fix of #1091 from GitHub

This commit is contained in:
krzychb 2017-09-27 22:03:22 +02:00
parent 58a5d883f4
commit 9107b47deb
7 changed files with 375 additions and 383 deletions

View file

@ -35,7 +35,7 @@ extern "C" {
#include "soc/uart_channel.h"
#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */
#define UART_INTR_MASK 0x1ff /*!< mask of all UART interrupts */
#define UART_INTR_MASK 0x1ff /*!< Mask of all UART interrupts */
#define UART_LINE_INV_MASK (0x3f << 19) /*!< TBD */
#define UART_BITRATE_MAX 5000000 /*!< Max bit rate supported by UART */
#define UART_PIN_NO_CHANGE (-1) /*!< Constant for uart_set_pin function which indicates that UART pin should not be changed */
@ -73,7 +73,7 @@ typedef enum {
typedef enum {
UART_NUM_0 = 0x0, /*!< UART base address 0x3ff40000*/
UART_NUM_1 = 0x1, /*!< UART base address 0x3ff50000*/
UART_NUM_2 = 0x2, /*!< UART base address 0x3ff6E000*/
UART_NUM_2 = 0x2, /*!< UART base address 0x3ff6e000*/
UART_NUM_MAX,
} uart_port_t;
@ -81,7 +81,7 @@ typedef enum {
* @brief UART parity constants
*/
typedef enum {
UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/
UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/
UART_PARITY_EVEN = 0x2, /*!< Enable UART even parity*/
UART_PARITY_ODD = 0x3 /*!< Enable UART odd parity*/
} uart_parity_t;
@ -101,11 +101,11 @@ typedef enum {
* @brief UART configuration parameters for uart_param_config function
*/
typedef struct {
int baud_rate; /*!< UART baudrate*/
int baud_rate; /*!< UART baud rate*/
uart_word_length_t data_bits; /*!< UART byte size*/
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)*/
uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode (cts/rts)*/
uint8_t rx_flow_ctrl_thresh ; /*!< UART HW RTS threshold*/
} uart_config_t;
@ -114,13 +114,13 @@ typedef struct {
*/
typedef struct {
uint32_t intr_enable_mask; /*!< UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator*/
uint8_t rx_timeout_thresh; /*!< UART timeout interrupt threshold(unit: time of sending one byte)*/
uint8_t rx_timeout_thresh; /*!< UART timeout interrupt threshold (unit: time of sending one byte)*/
uint8_t txfifo_empty_intr_thresh; /*!< UART TX empty interrupt threshold.*/
uint8_t rxfifo_full_thresh; /*!< UART RX full interrupt threshold.*/
} uart_intr_config_t;
/**
* @brief UART event types used in the ringbuffer
* @brief UART event types used in the ring buffer
*/
typedef enum {
UART_DATA, /*!< UART data event*/
@ -181,7 +181,7 @@ esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bi
esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits);
/**
* @brief Set UART stop bits.
* @brief Get UART stop bits.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param stop_bits Pointer to accept value of UART stop bits.
@ -193,7 +193,7 @@ esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits);
esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bits);
/**
* @brief Set UART parity.
* @brief Set UART parity mode.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param parity_mode the enum of uart parity configuration
@ -230,7 +230,7 @@ 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 baudrate);
/**
* @brief Get UART bit-rate.
* @brief Get UART baud rate.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param baudrate Pointer to accept value of UART baud rate
@ -247,7 +247,9 @@ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate);
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param inverse_mask Choose the wires that need to be inverted.
* Inverse_mask should be chosen from UART_INVERSE_RXD/UART_INVERSE_TXD/UART_INVERSE_RTS/UART_INVERSE_CTS, combine with OR operation.
* Inverse_mask should be chosen from
UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
combined with OR operation.
*
* @return
* - ESP_OK Success
@ -260,8 +262,8 @@ esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask);
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param flow_ctrl Hardware flow control mode
* @param rx_thresh Threshold of Hardware RX flow control(0 ~ UART_FIFO_LEN).
* Only when UART_HW_FLOWCTRL_RTS is set, will the rx_thresh value be set.
* @param rx_thresh Threshold of Hardware RX flow control (0 ~ UART_FIFO_LEN).
* Only when UART_HW_FLOWCTRL_RTS is set, will the rx_thresh value be set.
*
* @return
* - ESP_OK Success
@ -298,9 +300,9 @@ esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flo
/**
* @brief Clear UART interrupt status
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param clr_mask Bit mask of the status that to be cleared.
* enable_mask should be chosen from the fields of register UART_INT_CLR_REG.
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param clr_mask Bit mask of the interrupt status to be cleared.
* The bit mask should be composed from the fields of register UART_INT_CLR_REG.
*
* @return
* - ESP_OK Success
@ -311,9 +313,9 @@ esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask);
/**
* @brief Set UART interrupt enable
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param enable_mask Bit mask of the enable bits.
* enable_mask should be chosen from the fields of register UART_INT_ENA_REG.
* The bit mask should be composed from the fields of register UART_INT_ENA_REG.
*
* @return
* - ESP_OK Success
@ -324,9 +326,9 @@ esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask);
/**
* @brief Clear UART interrupt enable bits
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param disable_mask Bit mask of the disable bits.
* disable_mask should be chosen from the fields of register UART_INT_ENA_REG.
* The bit mask should be composed from the fields of register UART_INT_ENA_REG.
*
* @return
* - ESP_OK Success
@ -334,9 +336,8 @@ esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask);
*/
esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask);
/**
* @brief Enable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT)
* @brief Enable UART RX interrupt (RX_FULL & RX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
*
@ -347,7 +348,7 @@ esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask);
esp_err_t uart_enable_rx_intr(uart_port_t uart_num);
/**
* @brief Disable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT)
* @brief Disable UART RX interrupt (RX_FULL & RX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
*
@ -358,7 +359,7 @@ esp_err_t uart_enable_rx_intr(uart_port_t uart_num);
esp_err_t uart_disable_rx_intr(uart_port_t uart_num);
/**
* @brief Disable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT)
* @brief Disable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
*
@ -369,7 +370,7 @@ esp_err_t uart_disable_rx_intr(uart_port_t uart_num);
esp_err_t uart_disable_tx_intr(uart_port_t uart_num);
/**
* @brief Enable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT)
* @brief Enable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param enable 1: enable; 0: disable
@ -382,15 +383,15 @@ esp_err_t uart_disable_tx_intr(uart_port_t uart_num);
esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh);
/**
* @brief register UART interrupt handler(ISR).
* @brief Register UART interrupt handler (ISR).
*
* @note UART ISR handler will be attached to the same CPU core that this function is running on.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param fn Interrupt handler function.
* @param arg parameter for handler function
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
* @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will
* be returned here.
*
@ -400,7 +401,6 @@ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh);
*/
esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg, int intr_alloc_flags, uart_isr_handle_t *handle);
/**
* @brief Free UART interrupt handler registered by uart_isr_register. Must be called on the same core as
* uart_isr_register was called.
@ -417,13 +417,16 @@ esp_err_t uart_isr_free(uart_port_t uart_num);
* @brief Set UART pin number
*
* @note Internal signal can be output to multiple GPIO pads.
* Only one GPIO pad can connect with input signal.
* Only one GPIO pad can connect with input signal.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param tx_io_num UART TX pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin.
* @param rx_io_num UART RX pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin.
* @param rts_io_num UART RTS pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin.
* @param cts_io_num UART CTS pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin.
* @note Instead of GPIO number a macro 'UART_PIN_NO_CHANGE' may be provided
to keep the currently allocated pin.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param tx_io_num UART TX pin GPIO number.
* @param rx_io_num UART RX pin GPIO number.
* @param rts_io_num UART RTS pin GPIO number.
* @param cts_io_num UART CTS pin GPIO number.
*
* @return
* - ESP_OK Success
@ -432,11 +435,11 @@ esp_err_t uart_isr_free(uart_port_t uart_num);
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num);
/**
* @brief UART set RTS level (before inverse)
* UART rx hardware flow control should not be set.
* @brief Manually set the UART RTS pin level.
* @note UART must be configured with hardware flow control disabled.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param level 1: RTS output low(active); 0: RTS output high(block)
* @param level 1: RTS output low (active); 0: RTS output high (block)
*
* @return
* - ESP_OK Success
@ -445,9 +448,9 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
esp_err_t uart_set_rts(uart_port_t uart_num, int level);
/**
* @brief UART set DTR level (before inverse)
* @brief Manually set the UART DTR pin level.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param level 1: DTR output low; 0: DTR output high
*
* @return
@ -457,9 +460,9 @@ esp_err_t uart_set_rts(uart_port_t uart_num, int level);
esp_err_t uart_set_dtr(uart_port_t uart_num, int level);
/**
* @brief UART parameter configure
* @brief Set UART configuration parameters.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_config UART parameter settings
*
* @return
@ -469,9 +472,9 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level);
esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config);
/**
* @brief UART interrupt configure
* @brief Configure UART interrupts.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param intr_conf UART interrupt settings
*
* @return
@ -485,18 +488,18 @@ esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_
*
* UART ISR handler will be attached to the same CPU core that this function is running on.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param rx_buffer_size UART RX ring buffer size, rx_buffer_size should be greater than UART_FIFO_LEN.
* @param tx_buffer_size UART TX ring buffer size.
* If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out..
* @note tx_buffer_size should be greater than UART_FIFO_LEN.
* @note Rx_buffer_size should be greater than UART_FIFO_LEN. Tx_buffer_size should be either zero or greater than UART_FIFO_LEN.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param rx_buffer_size UART RX ring buffer size.
* @param tx_buffer_size UART TX ring buffer size.
* If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out.
* @param queue_size UART event queue size/depth.
* @param uart_queue UART event queue handle (out param). On success, a new queue handle is written here to provide
* access to UART events. If set to NULL, driver will not use an event queue.
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. Do not set ESP_INTR_FLAG_IRAM here
* (the driver's ISR handler is not located in IRAM)
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. Do not set ESP_INTR_FLAG_IRAM here
* (the driver's ISR handler is not located in IRAM)
*
* @return
* - ESP_OK Success
@ -507,7 +510,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
/**
* @brief Uninstall UART driver.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
*
* @return
* - ESP_OK Success
@ -516,9 +519,9 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
esp_err_t uart_driver_delete(uart_port_t uart_num);
/**
* @brief Wait UART TX FIFO empty
* @brief Wait until UART TX FIFO is empty.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param ticks_to_wait Timeout, count in RTOS ticks
*
* @return
@ -531,59 +534,59 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait);
/**
* @brief Send data to the UART port from a given buffer and length.
*
* This function will not wait for the space in TX FIFO, just fill the TX FIFO and return when the FIFO is full.
* This function will not wait for enough space in TX FIFO. It will just fill the available TX FIFO and return when the FIFO is full.
* @note This function should only be used when UART TX buffer is not enabled.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param buffer data buffer address
* @param len data length to send
* @param buffer data buffer address
* @param len data length to send
*
* @return
* - (-1) Parameter error
* - OTHERS(>=0) The number of data that pushed to the TX FIFO
* - OTHERS (>=0) The number of bytes pushed to the TX FIFO
*/
int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len);
/**
* @brief Send data to the UART port from a given buffer and length,
*
* If parameter tx_buffer_size is set to zero:
* If the UART driver's parameter 'tx_buffer_size' is set to zero:
* This function will not return until all the data have been sent out, or at least pushed into TX FIFO.
*
* Otherwise, if tx_buffer_size > 0, this function will return after copying all the data to tx ringbuffer,
* then, UART ISR will move data from ring buffer to TX FIFO gradually.
* Otherwise, if the 'tx_buffer_size' > 0, this function will return after copying all the data to tx ring buffer,
* UART ISR will then move data from the ring buffer to TX FIFO gradually.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param src data buffer address
* @param size data length to send
* @param src data buffer address
* @param size data length to send
*
* @return
* - (-1) Parameter error
* - OTHERS(>=0) The number of data that pushed to the TX FIFO
* - OTHERS (>=0) The number of bytes pushed to the TX FIFO
*/
int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size);
/**
* @brief Send data to the UART port from a given buffer and length,
* @brief Send data to the UART port from a given buffer and length.
*
* If parameter tx_buffer_size is set to zero:
* If the UART driver's parameter 'tx_buffer_size' is set to zero:
* This function will not return until all the data and the break signal have been sent out.
* After all data send out, send a break signal.
* After all data is sent out, send a break signal.
*
* Otherwise, if tx_buffer_size > 0, this function will return after copying all the data to tx ringbuffer,
* then, UART ISR will move data from ring buffer to TX FIFO gradually.
* After all data send out, send a break signal.
* Otherwise, if the 'tx_buffer_size' > 0, this function will return after copying all the data to tx ring buffer,
* UART ISR will then move data from the ring buffer to TX FIFO gradually.
* After all data sent out, send a break signal.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param src data buffer address
* @param size data length to send
* @param brk_len break signal length (unit: time of one data bit at current_baudrate)
* @param brk_len break signal length (unit: the time it takes to send a complete byte
including start, stop and parity bits at current_baudrate)
*
* @return
* - (-1) Parameter error
* - OTHERS(>=0) The number of data that pushed to the TX FIFO
* - OTHERS (>=0) The number of bytes pushed to the TX FIFO
*/
int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len);
/**
@ -596,7 +599,7 @@ int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t si
*
* @return
* - (-1) Error
* - Others return a char data from uart fifo.
* - OTHERS (>=0) The number of bytes read from UART FIFO
*/
int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait);
@ -612,10 +615,10 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp
esp_err_t uart_flush(uart_port_t uart_num);
/**
* @brief UART get RX ring buffer cached data length
* @brief UART get RX ring buffer cached data length
*
* @param uart_num UART port number.
* @param size Pointer of size_t to accept cached data length
* @param uart_num UART port number.
* @param size Pointer of size_t to accept cached data length
*
* @return
* - ESP_OK Success
@ -624,11 +627,11 @@ esp_err_t uart_flush(uart_port_t uart_num);
esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size);
/**
* @brief UART disable pattern detect function.
* Designed for applications like 'AT commands'.
* When the hardware detect a series of one same character, the interrupt will be triggered.
* @brief UART disable pattern detect function.
* Designed for applications like 'AT commands'.
* When the hardware detects a series of one same character, the interrupt will be triggered.
*
* @param uart_num UART port number.
* @param uart_num UART port number.
*
* @return
* - ESP_OK Success
@ -637,183 +640,22 @@ esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size);
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.
* @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 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.
* @param post_idle idle time after the last pattern character, 24bit value, unit is APB(80Mhz) clock cycle.
* @param pre_idle idle time before the first pattern character, 24bit value, unit is APB(80Mhz) clock cycle.
* @param chr_tout timeout of the interval between each pattern characters, 24bit value, unit is APB (80Mhz) clock cycle.
* @param post_idle idle time after the last pattern character, 24bit value, unit is APB (80Mhz) clock cycle.
* @param pre_idle idle time before the first pattern character, 24bit value, unit is APB (80Mhz) clock cycle.
*
* @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);
/***************************EXAMPLE**********************************
*
*
* ----------------EXAMPLE OF UART SETTING ---------------------
* @code{c}
* //1. Setup UART
* #include "freertos/queue.h"
* //a. Set UART parameter
* int uart_num = 0; //uart port number
* uart_config_t uart_config = {
* .baud_rate = 115200, //baudrate
* .data_bits = UART_DATA_8_BITS, //data bit mode
* .parity = UART_PARITY_DISABLE, //parity mode
* .stop_bits = UART_STOP_BITS_1, //stop bit mode
* .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //hardware flow control(cts/rts)
* .rx_flow_ctrl_thresh = 120, //flow control threshold
* };
* uart_param_config(uart_num, &uart_config);
* //b1. Setup UART driver(with UART queue)
* QueueHandle_t uart_queue;
* //parameters here are just an example, tx buffer size is 2048
* uart_driver_install(uart_num, 1024 * 2, 1024 * 2, 10, &uart_queue, 0);
* //b2. Setup UART driver(without UART queue)
* //parameters here are just an example, tx buffer size is 0
* uart_driver_install(uart_num, 1024 * 2, 0, 10, NULL, 0);
*@endcode
*-----------------------------------------------------------------------------*
* @code{c}
* //2. Set UART pin
* //set UART pin, not needed if use default pins.
* uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 15, 13);
* @endcode
*-----------------------------------------------------------------------------*
* @code{c}
* //3. Read data from UART.
* uint8_t data[128];
* int length = 0;
* length = uart_read_bytes(uart_num, data, sizeof(data), 100);
* @endcode
*-----------------------------------------------------------------------------*
* @code{c}
* //4. Write data to UART.
* char* test_str = "This is a test string.\n"
* uart_write_bytes(uart_num, (const char*)test_str, strlen(test_str));
* @endcode
*-----------------------------------------------------------------------------*
* @code{c}
* //5. Write data to UART, end with a break signal.
* uart_write_bytes_with_break(0, "test break\n",strlen("test break\n"), 100);
* @endcode
*-----------------------------------------------------------------------------*
* @code{c}
* //6. an example of echo test with hardware flow control on UART1
* void uart_loop_back_test()
* {
* int uart_num = 1;
* uart_config_t uart_config = {
* .baud_rate = 115200,
* .data_bits = UART_DATA_8_BITS,
* .parity = UART_PARITY_DISABLE,
* .stop_bits = UART_STOP_BITS_1,
* .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
* .rx_flow_ctrl_thresh = 122,
* };
* //Configure UART1 parameters
* uart_param_config(uart_num, &uart_config);
* //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19)
* uart_set_pin(uart_num, 16, 17, 18, 19);
* //Install UART driver( We don't need an event queue here)
* uart_driver_install(uart_num, 1024 * 2, 1024*4, 0, NULL, 0);
* uint8_t data[1000];
* while(1) {
* //Read data from UART
* int len = uart_read_bytes(uart_num, data, sizeof(data), 10);
* //Write data back to UART
* uart_write_bytes(uart_num, (const char*)data, len);
* }
* }
* @endcode
*-----------------------------------------------------------------------------*
* @code{c}
* //7. An example of using UART event queue on UART0.
* #include "freertos/queue.h"
* //A queue to handle UART event.
* QueueHandle_t uart0_queue;
* static const char *TAG = "uart_example";
* void uart_task(void *pvParameters)
* {
* int uart_num = (int)pvParameters;
* uart_event_t event;
* size_t size = 1024;
* uint8_t* dtmp = (uint8_t*)malloc(size);
* for(;;) {
* //Waiting for UART event.
* if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
* ESP_LOGI(TAG, "uart[%d] event:", uart_num);
* switch(event.type) {
* memset(dtmp, 0, size);
* //Event of UART receving data
* case UART_DATA:
* ESP_LOGI(TAG,"data, len: %d", event.size);
* int len = uart_read_bytes(uart_num, dtmp, event.size, 10);
* ESP_LOGI(TAG, "uart read: %d", len);
* break;
* //Event of HW FIFO overflow detected
* case UART_FIFO_OVF:
* ESP_LOGI(TAG, "hw fifo overflow\n");
* break;
* //Event of UART ring buffer full
* case UART_BUFFER_FULL:
* ESP_LOGI(TAG, "ring buffer full\n");
* break;
* //Event of UART RX break detected
* case UART_BREAK:
* ESP_LOGI(TAG, "uart rx break\n");
* break;
* //Event of UART parity check error
* case UART_PARITY_ERR:
* ESP_LOGI(TAG, "uart parity error\n");
* break;
* //Event of UART frame error
* case UART_FRAME_ERR:
* ESP_LOGI(TAG, "uart frame error\n");
* break;
* //Others
* default:
* ESP_LOGI(TAG, "uart event type: %d\n", event.type);
* break;
* }
* }
* }
* free(dtmp);
* dtmp = NULL;
* vTaskDelete(NULL);
* }
*
* void uart_queue_test()
* {
* int uart_num = 0;
* uart_config_t uart_config = {
* .baud_rate = 115200,
* .data_bits = UART_DATA_8_BITS,
* .parity = UART_PARITY_DISABLE,
* .stop_bits = UART_STOP_BITS_1,
* .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
* .rx_flow_ctrl_thresh = 122,
* };
* //Set UART parameters
* uart_param_config(uart_num, &uart_config);
* //Set UART pins,(-1: default pin, no change.)
* uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
* //Set UART log level
* esp_log_level_set(TAG, ESP_LOG_INFO);
* //Install UART driver, and get the queue.
* uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, &uart0_queue, 0);
* //Create a task to handler UART event from ISR
* xTaskCreate(uart_task, "uTask", 1024, (void*)uart_num, 10, NULL);
* }
* @endcode
*
***************************END OF EXAMPLE**********************************/
#ifdef __cplusplus
}

View file

@ -874,7 +874,7 @@ int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t si
int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1));
UART_CHECK((buf), "uart_num error", (-1));
UART_CHECK((buf), "uart data null", (-1));
UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1));
uint8_t* data = NULL;
size_t size;

View file

@ -4,31 +4,157 @@ UART
Overview
--------
`Instructions`_
An Universal Asynchronous Receiver/Transmitter (UART) is a component known to handle the timing requirements for a variety of widely-adapted protocols (RS232, RS485, RS422, ...). An UART provides a widely adopted and cheap method to realize full-duplex data exchange among different devices.
.. _Instructions: ../template.html
There are three UART controllers available on the ESP32 chip. They are compatible with UART-enabled devices from various manufacturers. All UART controllers integrated in the ESP32 feature an identical set of registers for ease of programming and flexibility. In this documentation, these controllers are referred to as UART0, UART1, and UART2.
Application Example
Functional Overview
-------------------
Configure uart settings and install uart driver to read/write using UART0 and UART1 interfaces: :example:`peripherals/uart`.
The following overview describes functions and data types used to establish communication between ESP32 and some other UART device. The overview reflects a typical workflow when programming ESP32's UART driver and is broken down into the following sections:
1. :ref:`uart-api-setting-communication-parameters` - baud rate, data bits, stop bits, etc,
2. :ref:`uart-api-setting-communication-pins` - pins the other UART is connected to
3. :ref:`uart-api-driver-installation` - allocate ESP32's resources for the UART driver
4. :ref:`uart-api-running-uart-communication` - send / receive the data
5. :ref:`uart-api-using-interrupts` - trigger interrupts on specific communication events
6. :ref:`uart-api-deleting-driver` - release ESP32's resources, if UART communication is not required anymore
The minimum to make the UART working is to complete the first four steps, the last two steps are optional.
The driver is identified by :cpp:type:`uart_port_t`, that corresponds to one of the tree UART controllers. Such identification is present in all the following function calls.
.. _uart-api-setting-communication-parameters:
Setting Communication Parameters
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are two ways to set the communications parameters for UART. One is to do it in one shot by calling :cpp:func:`uart_param_config` provided with configuration parameters in :cpp:type:`uart_config_t` structure.
The alternate way is to configure specific parameters individually by calling dedicated functions:
* Baud rate - :cpp:func:`uart_set_baudrate`
* Number of transmitted bits - :cpp:func:`uart_set_word_length` selected out of :cpp:type:`uart_word_length_t`
* Parity control - :cpp:func:`uart_set_parity` selected out of :cpp:type:`uart_parity_t`
* Number of stop bits - :cpp:func:`uart_set_stop_bits` selected out of :cpp:type:`uart_stop_bits_t`
* Hardware flow control mode - :cpp:func:`uart_set_hw_flow_ctrl` selected out of `uart_hw_flowcontrol_t`
All the above functions have a ``_get_`` equivalent to retrieve the current setting, e.g. :cpp:func:`uart_get_baudrate`.
.. _uart-api-setting-communication-pins:
Setting Communication Pins
^^^^^^^^^^^^^^^^^^^^^^^^^^
In next step, after configuring communication parameters, we are setting physical GPIO pin numbers the other UART will be connected to. This is done in a single step by calling function :cpp:func:`uart_set_pin` and providing it with GPIO numbers, that driver should use for the Tx, Rx, RTS and CTS signals.
Instead of GPIO pin number we can enter a macro :cpp:type:`UART_PIN_NO_CHANGE` and the currently allocated pin will not be changed. The same macro should be entered if certain pin will not be used.
.. _uart-api-driver-installation:
Driver Installation
^^^^^^^^^^^^^^^^^^^
Once configuration of driver is complete, we can install it by calling :cpp:func:`uart_driver_install`. As result several resources required by the UART will be allocated. The type / size of resources are specified as function call parameters and concern:
* size of the send buffer
* size of the receive buffer
* the event queue handle and size
* flags to allocate an interrupt
If all above steps have been complete, we are ready to connect the other UART device and check the communication.
.. _uart-api-running-uart-communication:
Running UART Communication
^^^^^^^^^^^^^^^^^^^^^^^^^^
The processes of serial communication are under control of UART's hardware FSM. The data to be sent should be put into Tx FIFO buffer, FSM will serialize them and sent out. A similar process, but in reverse order, is done to receive the data. Incoming serial stream is processed by FSM and moved to the Rx FIFO buffer. Therefore the task of API's communication functions is limited to writing and reading the data to / from the respective buffer. This is reflected in some function names, e.g.: :cpp:func:`uart_write_bytes` to transmit the data out, or :cpp:func:`uart_read_bytes` to read the incoming data.
Transmitting
""""""""""""
The basic API function to write the data to Tx FIFO buffer is :cpp:func:`uart_tx_chars`. If the buffer contains not sent characters, this function will write what fits into the empty space and exit reporting the number of bytes actually written.
There is a 'companion' function :cpp:func:`uart_wait_tx_done` that waits until all the data are transmitted out and the Tx FIFO is empty.
An easier to work with function is :cpp:func:`uart_write_bytes`. It sets up an intermediate ring buffer and exits after copying the data to this buffer. When there is an empty space in the FIFO, the data are moved from the ring buffer to the FIFO in the background by an ISR.
There is a similar function as above that adds a serial break signal after sending the data - :cpp:func:`uart_write_bytes_with_break`. The 'serial break signal' means holding TX line low for period longer than one data frame.
Receiving
"""""""""
To retrieve the data received by UART and saved in Rx FIFO, use function :cpp:func:`uart_read_bytes`. You can check in advance what is the number of bytes available in Rx FIFO by calling :cpp:func:`uart_get_buffered_data_len`.
If the data in Rx FIFO is not required and should be discarded, call :cpp:func:`uart_flush`.
Software Flow Control
"""""""""""""""""""""
When the hardware flow control is disabled, then use :cpp:func:`uart_set_rts` and :cpp:func:`uart_set_dtr` to manually set the levels of the RTS and DTR signals.
.. _uart-api-using-interrupts:
Using Interrupts
^^^^^^^^^^^^^^^^
There are nineteen interrupts reported on specific states of UART or on detected errors. The full list of available interrupts is described in `ESP32 Technical Reference Manual <https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf>`_ (PDF). To enable specific interrupts call :cpp:func:`uart_enable_intr_mask`, to disable call :cpp:func:`uart_disable_intr_mask`. The mask of all interrupts is available as :cpp:type:`UART_INTR_MASK`. Registration of an handler to service interrupts is done with :cpp:func:`uart_isr_register`, freeing the handler with :cpp:func:`uart_isr_free`. To clear the interrupt status bits once the handler is called use :cpp:func:`uart_clear_intr_status`.
The API provides a convenient way to handle specific interrupts discussed above by wrapping them into dedicated functions:
* **Event detection** - there are several events defined in :cpp:type:`uart_event_type_t` that may be reported to user application using FreeRTOS queue functionality. You can enable this functionality when calling :cpp:func:`uart_driver_install` described in :ref:`uart-api-driver-installation`. Example how to use it is covered in :example:`peripherals/uart_events`.
* **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 uart_disable_pattern_det_intr`.
Macros
^^^^^^
The API provides several macros to define configuration parameters, e.g. :cpp:type:`UART_FIFO_LEN` to define the length of the hardware FIFO buffers, :cpp:type:`UART_BITRATE_MAX` that gives the maximum baud rate supported by UART, etc.
.. _uart-api-deleting-driver:
Deleting Driver
^^^^^^^^^^^^^^^
If communication is established with :cpp:func:`uart_driver_install` for some specific period of time and then not required, the driver may be removed to free allocated resources by calling :cpp:func:`uart_driver_delete`.
Application Examples
--------------------
Configure UART settings and install UART driver to read/write using UART1 interface: :example:`peripherals/uart_echo`.
Demonstration how report report various communication events and how to use patern detection interrupts: :example:`peripherals/uart_events`.
API Reference
-------------
.. include:: /_build/inc/uart.inc
GPIO Lookup Macros
^^^^^^^^^^^^^^^^^^
Some useful macros can be used to specified the **direct** GPIO (UART module connected to pads through direct IO mux without the GPIO mux) number of a UART channel, or vice versa.
The pin name can be omitted if specify the channel of a GPIO num.
e.g.
You can use macros to specify the **direct** GPIO (UART module connected to pads through direct IO mux without the GPIO mux) number of a UART channel, or vice versa. The pin name can be omitted if the channel of a GPIO number is specified, e.g.:
1. ``UART_NUM_2_TXD_DIRECT_GPIO_NUM`` is the GPIO number of UART channel 2 TXD pin (17);
2. ``UART_GPIO19_DIRECT_CHANNEL`` is the UART channel number of GPIO 19 (channel 0);
3. ``UART_CTS_GPIO19_DIRECT_CHANNEL`` is the UART channel number of GPIO 19, and GPIO 19 must be a CTS pin (channel 0).
.. include:: /_build/inc/uart_channel.inc

View file

@ -0,0 +1,36 @@
# UART Echo Example
This is an example which echoes any data it receives on UART1 back to the sender.
## Setup
1. Connect an external serial interface to an ESP32 board. The external interface should have 3.3V outputs. You may use e.g. 3.3V compatible USB-to-serial dongle:
| ESP32 Interface | #define | ESP32 Pin | External UART Pin |
| --- | --- | --- | --- |
| Transmit Data (TxD) | ECHO_TEST_TXD | GPIO4 | RxD |
| Receive Data (RxD) | ECHO_TEST_RXD | GPIO5 | TxD |
| Ground | n/a | GND | GND |
2. Compile and load the example to the ESP32 board
3. Refer to the example and set up a serial terminal program to the same settings as of UART1 in ESP32
4. Open the external serial interface in the terminal
5. When typing any character in the terminal you should see it echoed back
6. Verify if echo indeed comes from ESP32 by disconnecting either 'TxD' or 'RxD' pin. There should be no any echo once any pin is disconnected.
## Using a hardware flow control
This is an optional check to verify if the hardware flow control works. To set it up you need an external serial interface that has RTS and CTS signals.
1. Connect the extra RTS/CTS signals as below
| ESP32 Interface | #define | ESP32 Pin | External UART Pin |
| --- | --- | --- | --- |
| Request to Send (RTS) | ECHO_TEST_RTS | GPIO18 | CTS |
| Clear to Send (CTS) | ECHO_TEST_CTS | GPIO19 | RTS |
2. Configure both extra pins in the example code by replacing existing `UART_PIN_NO_CHANGE` macros with the above pin numbers
3. Configure UART1 driver to use the hardware flow control by setting `.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS` and adding `.rx_flow_ctrl_thresh = 122`
4. Repeat tests described in 'Setup' above starting from step 3
See the README.md file in the upper level 'examples' directory for more information about examples.

View file

@ -1,4 +1,4 @@
/* Uart Events Example
/* UART Echo Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
@ -7,67 +7,56 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "soc/uart_struct.h"
/**
* This is a example exaple which echos any data it receives on UART1 back to the sender, with hardware flow control
* turned on. It does not use UART driver event queue.
* This is an example which echos any data it receives on UART1 back to the sender,
* with hardware flow control turned off. It does not use UART driver event queue.
*
* - port: UART1
* - rx buffer: on
* - tx buffer: off
* - flow control: on
* - event queue: off
* - pin assignment: txd(io4), rxd(io5), rts(18), cts(19)
* - Port: UART1
* - Receive (Rx) buffer: on
* - Transmit (Tx) buffer: off
* - Flow control: off
* - Event queue: off
* - Pin assignment: see defines below
*/
#define ECHO_TEST_TXD (4)
#define ECHO_TEST_RXD (5)
#define ECHO_TEST_RTS (18)
#define ECHO_TEST_CTS (19)
#define ECHO_TEST_TXD (GPIO_NUM_4)
#define ECHO_TEST_RXD (GPIO_NUM_5)
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE)
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)
#define BUF_SIZE (1024)
//an example of echo test with hardware flow control on UART1
static void echo_task()
{
const int uart_num = UART_NUM_1;
/* Configure parameters of an UART driver,
* communication pins and install the driver */
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
.rx_flow_ctrl_thresh = 122,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
//Configure UART1 parameters
uart_param_config(uart_num, &uart_config);
//Set UART1 pins(TX: IO4, RX: I05, RTS: IO18, CTS: IO19)
uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);
//Install UART driver (we don't need an event queue here)
//In this example we don't even use a buffer for sending data.
uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0);
uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);
uart_driver_install(UART_NUM_1, BUF_SIZE * 2, 0, 0, NULL, 0);
uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
while(1) {
//Read data from UART
int len = uart_read_bytes(uart_num, data, BUF_SIZE, 20 / portTICK_RATE_MS);
//Write data back to UART
uart_write_bytes(uart_num, (const char*) data, len);
// Configure a temporary buffer for the incoming data
uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
while (1) {
// Read data from the UART
int len = uart_read_bytes(UART_NUM_1, data, BUF_SIZE, 20 / portTICK_RATE_MS);
// Write data back to the UART
uart_write_bytes(UART_NUM_1, (const char *) data, len);
}
}
void app_main()
{
//A uart read/write example without event queue;
xTaskCreate(echo_task, "uart_echo_task", 1024, NULL, 10, NULL);
}

View file

@ -0,0 +1,10 @@
# UART Events Example
This example shows how to use the UART driver to handle special UART events. It also reads data from UART0 directly, and echoes it to console.
# How to use it?
1. Compile and load example from terminl running `make flash monitor`
2. Being in 'monotor' type samething to see the `UART_DATA` events and the typed data displayed.
See the README.md file in the upper level 'examples' directory for more information about examples.

View file

@ -1,4 +1,4 @@
/* Uart Example
/* UART Events Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
@ -7,16 +7,11 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "soc/uart_struct.h"
static const char *TAG = "uart_events";
@ -25,12 +20,12 @@ static const char *TAG = "uart_events";
*
* It also reads data from UART0 directly, and echoes it to console.
*
* - port: UART0
* - rx buffer: on
* - tx buffer: on
* - flow control: off
* - event queue: on
* - pin assignment: txd(default), rxd(default)
* - Port: UART0
* - Receive (Rx) buffer: on
* - Transmit (Tx) buffer: off
* - Flow control: off
* - Event queue: on
* - Pin assignment: TxD (default), RxD (default)
*/
#define EX_UART_NUM UART_NUM_0
@ -42,55 +37,50 @@ static void uart_event_task(void *pvParameters)
{
uart_event_t event;
size_t buffered_size;
uint8_t* dtmp = (uint8_t*) malloc(BUF_SIZE);
for(;;) {
//Waiting for UART event.
if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
uint8_t *dtmp = (uint8_t *) malloc(BUF_SIZE);
while (1) {
/* Waiting for UART event.
If it happens then print out information what is it */
if (xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
switch(event.type) {
//Event of UART receving data
/*We'd better handler data event fast, there would be much more data events than
other types of events. If we take too much time on data event, the queue might
be full.
in this example, we don't process data in event, but read data outside.*/
case UART_DATA:
uart_get_buffered_data_len(EX_UART_NUM, &buffered_size);
ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size);
break;
//Event of HW FIFO overflow detected
case UART_FIFO_OVF:
ESP_LOGI(TAG, "hw fifo overflow\n");
//If fifo overflow happened, you should consider adding flow control for your application.
//We can read data out out the buffer, or directly flush the rx buffer.
uart_flush(EX_UART_NUM);
break;
//Event of UART ring buffer full
case UART_BUFFER_FULL:
ESP_LOGI(TAG, "ring buffer full\n");
//If buffer full happened, you should consider encreasing your buffer size
//We can read data out out the buffer, or directly flush the rx buffer.
uart_flush(EX_UART_NUM);
break;
//Event of UART RX break detected
case UART_BREAK:
ESP_LOGI(TAG, "uart rx break\n");
break;
//Event of UART parity check error
case UART_PARITY_ERR:
ESP_LOGI(TAG, "uart parity error\n");
break;
//Event of UART frame error
case UART_FRAME_ERR:
ESP_LOGI(TAG, "uart frame error\n");
break;
//UART_PATTERN_DET
case UART_PATTERN_DET:
ESP_LOGI(TAG, "uart pattern detected\n");
break;
//Others
default:
ESP_LOGI(TAG, "uart event type: %d\n", event.type);
break;
switch (event.type) {
case UART_DATA:
/* Event of UART receiving data
* We'd better handler data event fast, there would be much more data events
* than other types of events.
* If we take too much time on data event, the queue might be full.
* In this example, we don't process data in event, but read data outside.
*/
uart_get_buffered_data_len(EX_UART_NUM, &buffered_size);
ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size);
break;
case UART_FIFO_OVF:
ESP_LOGE(TAG, "hw fifo overflow");
// If fifo overflow happened, you should consider adding flow control for your application.
// We can read data out out the buffer, or directly flush the Rx buffer.
uart_flush(EX_UART_NUM);
break;
case UART_BUFFER_FULL:
ESP_LOGE(TAG, "ring buffer full");
// If buffer full happened, you should consider increasing your buffer size
// We can read data out out the buffer, or directly flush the Rx buffer.
uart_flush(EX_UART_NUM);
break;
case UART_BREAK:
ESP_LOGI(TAG, "uart rx break detected");
break;
case UART_PARITY_ERR:
ESP_LOGE(TAG, "uart parity error");
break;
case UART_FRAME_ERR:
ESP_LOGE(TAG, "uart frame error");
break;
case UART_PATTERN_DET:
ESP_LOGI(TAG, "uart pattern detected");
break;
default:
ESP_LOGE(TAG, "not serviced uart event type: %d\n", event.type);
break;
}
}
}
@ -99,38 +89,37 @@ static void uart_event_task(void *pvParameters)
vTaskDelete(NULL);
}
/* Configure the UART events example */
void app_main()
{
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 122,
};
//Set UART parameters
uart_param_config(EX_UART_NUM, &uart_config);
//Set UART log level
esp_log_level_set(TAG, ESP_LOG_INFO);
//Install UART driver, and get the queue.
/* Configure parameters of an UART driver,
* communication pins and install the driver */
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(EX_UART_NUM, &uart_config);
// Set UART pins using UART0 default pins i.e. no changes
uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0);
//Set UART pins (using UART0 default pins ie no changes.)
uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
//Set uart pattern detect function.
// Set uart pattern detection function
uart_enable_pattern_det_intr(EX_UART_NUM, '+', 3, 10000, 10, 10);
//Create a task to handler UART event from ISR
// Create a task to handle uart event from ISR
xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);
//process data
uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
do {
// Reserve a buffer and process incoming data
uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
while (1) {
int len = uart_read_bytes(EX_UART_NUM, data, BUF_SIZE, 100 / portTICK_RATE_MS);
if(len > 0) {
if (len > 0) {
ESP_LOGI(TAG, "uart read : %d", len);
uart_write_bytes(EX_UART_NUM, (const char*)data, len);
uart_write_bytes(EX_UART_NUM, (const char *)data, len);
}
} while(1);
}
}