/** * @brief Handle when a pattern has been detected by UART * * @param esp_dte ESP32 Modem DTE object */ static void esp_handle_uart_pattern(esp_modem_dte_t *esp_dte) { int pos = uart_pattern_pop_pos(esp_dte->uart_port); int read_len = 0; if (pos != -1) { if (pos < ESP_MODEM_LINE_BUFFER_SIZE - 1) { /* read one line(include '\n') */ read_len = pos + 1; } else { ESP_LOGW(MODEM_TAG, "ESP Modem Line buffer too small"); read_len = ESP_MODEM_LINE_BUFFER_SIZE - 1; } read_len = uart_read_bytes(esp_dte->uart_port, esp_dte->buffer, read_len, pdMS_TO_TICKS(100)); if (read_len) { /* make sure the line is a standard string */ esp_dte->buffer[read_len] = '\0'; /* Send new line to handle */ esp_dte_handle_line(esp_dte); } else { ESP_LOGE(MODEM_TAG, "uart read bytes failed"); } } else { ESP_LOGW(MODEM_TAG, "Pattern Queue Size too small"); uart_flush(esp_dte->uart_port); } }
/** * @brief Send data and wait for prompt from DCE * * @param dte Modem DTE object * @param data data buffer * @param length length of data to send * @param prompt pointer of specific prompt * @param timeout timeout value (unit: ms) * @return esp_err_t * ESP_OK on success * ESP_FAIL on error */ static esp_err_t esp_modem_dte_send_wait(modem_dte_t *dte, const char *data, uint32_t length, const char *prompt, uint32_t timeout) { MODEM_CHECK(data, "data is NULL", err_param); MODEM_CHECK(prompt, "prompt is NULL", err_param); esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent); // We'd better disable pattern detection here for a moment in case prompt string contains the pattern character uart_disable_pattern_det_intr(esp_dte->uart_port); // uart_disable_rx_intr(esp_dte->uart_port); MODEM_CHECK(uart_write_bytes(esp_dte->uart_port, data, length) >= 0, "uart write bytes failed", err_write); uint32_t len = strlen(prompt); uint8_t *buffer = calloc(len + 1, sizeof(uint8_t)); int res = uart_read_bytes(esp_dte->uart_port, buffer, len, pdMS_TO_TICKS(timeout)); 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); 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); err_param: return ESP_FAIL; }
/** * @brief Handle when new data received by UART * * @param esp_dte ESP32 Modem DTE object */ static void esp_handle_uart_data(esp_modem_dte_t *esp_dte) { size_t length = 0; uart_get_buffered_data_len(esp_dte->uart_port, &length); length = MIN(ESP_MODEM_LINE_BUFFER_SIZE, length); length = uart_read_bytes(esp_dte->uart_port, esp_dte->buffer, length, portMAX_DELAY); /* pass input data to the lwIP core thread */ if (length) { pppos_input_tcpip(esp_dte->ppp, esp_dte->buffer, length); } }
void init() { const 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(UART_NUM_1, &uart_config); uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); // We won't use a buffer for sending data. uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0); } int sendData(const char* logName, const char* data) { const int len = strlen(data); const int txBytes = uart_write_bytes(UART_NUM_1, data, len); ESP_LOGI(logName, "Wrote %d bytes", txBytes); return txBytes; } static void tx_task() { static const char *TX_TASK_TAG = "TX_TASK"; esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO); while (1) { sendData(TX_TASK_TAG, "Hello world"); vTaskDelay(2000 / portTICK_PERIOD_MS); } } static void rx_task() { static const char *RX_TASK_TAG = "RX_TASK"; esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO); uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1); while (1) { const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, 1000 / portTICK_RATE_MS); if (rxBytes > 0) { data[rxBytes] = 0; ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxBytes, data); ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO); } } free(data); } void app_main() { init(); xTaskCreate(rx_task, "uart_rx_task", 1024*2, NULL, configMAX_PRIORITIES, NULL); xTaskCreate(tx_task, "uart_tx_task", 1024*2, NULL, configMAX_PRIORITIES-1, NULL); }
static void uart_evt_task(void *pvParameters) { int uart_num = 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 log level esp_log_level_set(TAG, ESP_LOG_INFO); //Install UART driver, and get the queue. uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0); //Set UART pins,(-1: default pin, no change.) //For UART0, we can just use the default pins. //uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //Set uart pattern detect function. uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10); //Create a task to handler UART event from ISR xTaskCreate(uart_task, "uart_task", UART_TASK_STACK_SIZE, NULL, UART_TASK_PRIO, NULL); //process data uint8_t* data = (uint8_t*) malloc(BUF_SIZE); do { int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS); if(len > 0) { //ESP_LOGI(TAG, "uart read : %d", len); //uart_write_bytes(uart_num, (const char*)data, len); uart_input_handler((const char*)data, len); } } while(1); } void uart_init(void) { memset(&rcvMsg, 0, sizeof(rcvMsg)); rcvMsg.RcvBuffSize = RECV_BUF_SIZE; rcvMsg.pRcvMsgBuff = NULL; rcvMsg.pRcvMsgBuff = (uint8_t *) malloc(RECV_BUF_SIZE); if (rcvMsg.pRcvMsgBuff == NULL) { ESP_LOGE(TAG, "receive buffer alloc failed"); return; } rcvMsg.pReadPos = rcvMsg.pRcvMsgBuff; rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; xTaskCreate(uart_evt_task, "uart_evt_task", UART_EVT_TASK_STACK_SIZE, NULL, UART_EVT_TASK_PRIO, NULL); }
char *readLine(uart_port_t uart) { static char line[256]; int size; char *ptr = line; while(1) { size = uart_read_bytes(UART_NUM_1, (unsigned char *)ptr, 1, portMAX_DELAY); if (size == 1) { if (*ptr == '\n') { *ptr = 0; return line; } ptr++; } // End of read a character } // End of loop } // End of readLine
int main(int argc, char *argv[]){ char test_str[] = "Hello World"; int bytes = strlen(test_str); // get number of bytes in test string char buf[BUF_SIZE]; int ret; // return value int bus; // which bus to use // Parse arguments if(argc!=2){ //argc==2 actually means one argument given print_usage(); return -1; } else bus = atoi(argv[1]); if(!(bus==0||bus==1||bus==2||bus==5)){ print_usage(); return -1; } // Initialization initialize_board(); printf("\ntesting UART bus %d\n\n", bus); if(initialize_uart(bus, BAUDRATE, TIMEOUT_S)){ printf("Failed to initialize_uart%d\n", bus); cleanup_board(); return -1; } // Flush and Write printf("Sending %d bytes: %s \n", bytes, test_str); flush_uart(bus); uart_send_bytes(bus, bytes, &test_str[0]); // Read memset(buf, 0, BUF_SIZE); ret = uart_read_bytes(bus, bytes, &buf[0]); if(ret<0) printf("Error reading bus\n"); else if(ret==0)printf("timeout reached, %d bytes read\n", ret); else printf("Received %d bytes: %s \n", ret, buf); // close up close_uart(bus); cleanup_board(); return 0; }
static void btstack_stdin_task(void *arg){ UNUSED(arg); //Install UART driver, and get the queue. uart_driver_install(CONFIG_CONSOLE_UART_NUM, UART_FIFO_LEN * 2, UART_FIFO_LEN * 2, 0, NULL, 0); do { // read single byte uart_read_bytes(CONFIG_CONSOLE_UART_NUM, (uint8_t*) &stdin_character, 1, portMAX_DELAY); stdin_character_received = 1; // request poll btstack_run_loop_freertos_trigger(); // busy wait for input processed while (stdin_character_received){ vTaskDelay(10 / portTICK_PERIOD_MS); } } while(1); }