| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- // SPDX-License-Identifier: Apache-2.0
- // Copyright 2015-2024 Espressif Systems (Shanghai) PTE LTD
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // 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.
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "driver/uart.h"
- #include "esp_hosted_config.h"
- #include "os_wrapper.h"
- #include "uart_wrapper.h"
- #include "esp_log.h"
- static const char TAG[] = "uart_wrapper";
- #if H_UART_START_BITS != 1
- #error "UART Start Bits must be 1 to communicate with ESP co-processor"
- #endif
- #if H_UART_FLOWCTRL
- #error "UART Flow Control must be disabled to communicate with ESP co-processor"
- #endif
- #if CONFIG_ESP_CONSOLE_UART
- #if CONFIG_ESP_CONSOLE_UART_NUM == H_UART_PORT
- #error "ESP Console UART and Hosted UART are the same. Select another UART port."
- #endif
- #endif
- #define UART_FAIL_IF_NULL_CTX(x) do { \
- if (!x) return ESP_FAIL; \
- } while (0);
- // these values should match ESP_UART_PARITY values in Hosted Kconfig
- enum {
- HOSTED_UART_PARITY_NONE = 0,
- HOSTED_UART_PARITY_EVEN = 1,
- HOSTED_UART_PARITY_ODD = 2,
- };
- // these values should match ESP_UART_STOP_BITS values in Hosted Kconfig
- enum {
- HOSTED_STOP_BITS_1 = 0,
- HOSTED_STOP_BITS_1_5 = 1,
- HOSTED_STOP_BITS_2 = 2,
- };
- // UART context structure
- typedef struct uart_ctx_t {
- int uart_port;
- } uart_ctx_t;
- static uart_ctx_t * ctx = NULL;
- int hosted_uart_read(void * ctx, uint8_t *data, uint16_t size)
- {
- uart_ctx_t * pctx;
- UART_FAIL_IF_NULL_CTX(ctx);
- pctx = (uart_ctx_t *)ctx;
- return uart_read_bytes(pctx->uart_port, data, size, portMAX_DELAY);
- }
- int hosted_uart_write(void * ctx, uint8_t *data, uint16_t size)
- {
- uart_ctx_t * pctx;
- UART_FAIL_IF_NULL_CTX(ctx);
- pctx = (uart_ctx_t *)ctx;
- return uart_write_bytes(pctx->uart_port, (const char*)data, size);
- }
- void * hosted_uart_init(void)
- {
- uart_word_length_t uart_word_length;
- uart_parity_t parity;
- uart_stop_bits_t stop_bits;
- ctx = (uart_ctx_t*)g_h.funcs->_h_malloc(sizeof(uart_ctx_t));
- assert(ctx);
- switch (H_UART_NUM_DATA_BITS) {
- case 5:
- uart_word_length = UART_DATA_5_BITS;
- break;
- case 6:
- uart_word_length = UART_DATA_6_BITS;
- break;
- case 7:
- uart_word_length = UART_DATA_7_BITS;
- break;
- case 8:
- // drop through to default
- default:
- uart_word_length = UART_DATA_8_BITS;
- break;
- }
- switch (H_UART_PARITY) {
- case HOSTED_UART_PARITY_EVEN: // even parity
- parity = UART_PARITY_EVEN;
- break;
- case HOSTED_UART_PARITY_ODD: // odd parity
- parity = UART_PARITY_ODD;
- break;
- case HOSTED_UART_PARITY_NONE: // none
- // drop through to default
- default:
- parity = UART_PARITY_DISABLE;
- break;
- }
- switch (H_UART_STOP_BITS) {
- case HOSTED_STOP_BITS_1_5: // 1.5 stop bits
- stop_bits = UART_STOP_BITS_1_5;
- break;
- case HOSTED_STOP_BITS_2: // 2 stop bits
- stop_bits = UART_STOP_BITS_2;
- break;
- case HOSTED_STOP_BITS_1: // 1 stop bits
- // drop through to default
- default:
- stop_bits = UART_STOP_BITS_1;
- break;
- }
- // initialise bus and device in ctx
- const uart_config_t uart_config = {
- .baud_rate = H_UART_BAUD_RATE,
- .data_bits = uart_word_length,
- .parity = parity,
- .stop_bits = stop_bits,
- .flow_ctrl = H_UART_FLOWCTRL,
- .source_clk = H_UART_CLK_SRC,
- };
- ESP_ERROR_CHECK(uart_driver_install(H_UART_PORT, MAX_UART_BUFFER_SIZE, MAX_UART_BUFFER_SIZE,
- 0, NULL, 0));
- ESP_ERROR_CHECK(uart_param_config(H_UART_PORT, &uart_config));
- ESP_ERROR_CHECK(uart_set_pin(H_UART_PORT, H_UART_TX_PIN, H_UART_RX_PIN,
- UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
- ESP_LOGI(TAG, "UART GPIOs: Tx: %"PRIu16 ", Rx: %"PRIu16 ", Baud Rate %i",
- H_UART_TX_PIN, H_UART_RX_PIN, H_UART_BAUD_RATE);
- ctx->uart_port = H_UART_PORT;
- return ctx;
- }
- esp_err_t hosted_uart_deinit(void *ctx)
- {
- esp_err_t ret;
- uart_ctx_t * pctx;
- UART_FAIL_IF_NULL_CTX(ctx);
- pctx = (uart_ctx_t *)ctx;
- ret = uart_flush_input(pctx->uart_port);
- if (ret != ESP_OK)
- ESP_LOGE(TAG, "%s: Failed to flush uart Rx", __func__);
- ret = uart_wait_tx_done(pctx->uart_port, 100); // wait 100 RTOS ticks for Tx to be empty
- if (ret != ESP_OK)
- ESP_LOGE(TAG, "%s: Failed to flush uart Tx", __func__);
- uart_driver_delete(pctx->uart_port);
- HOSTED_FREE(ctx);
- return ESP_OK;
- }
|