mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-05 21:04:49 +00:00
Nimble/transport: HAL Support for UART transport
This commit is contained in:
committed by
Abhinav Kudnar
parent
396f1e6ebd
commit
0a0eeb985f
@@ -19,7 +19,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "driver/uart.h"
|
||||
|
||||
/**
|
||||
* Function prototype for UART driver to ask for more data to send.
|
||||
|
||||
@@ -28,7 +28,7 @@ struct os_mempool;
|
||||
struct os_mbuf_pool;
|
||||
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
int r_mem_malloc_mempool(struct os_mempool *mempool, uint16_t num_blocks,
|
||||
uint32_t block_size, char *name, void **out_buf);
|
||||
#define mem_malloc_mempool r_mem_malloc_mempool
|
||||
@@ -88,7 +88,7 @@ int mem_init_mbuf_pool(void *mem, struct os_mempool *mempool,
|
||||
typedef struct os_mbuf *mem_frag_alloc_fn(uint16_t frag_size, void *arg);
|
||||
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
struct os_mbuf *r_mem_split_frag(struct os_mbuf **om, uint16_t max_frag_sz,
|
||||
mem_frag_alloc_fn *alloc_cb, void *cb_arg);
|
||||
#define mem_split_frag r_mem_split_frag
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#define NIMBLE_HS_STACK_SIZE CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE
|
||||
#endif
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ extern "C" {
|
||||
|
||||
#endif
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
void r_put_le16(void *buf, uint16_t x);
|
||||
#define put_le16 r_put_le16
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ _os_mbuf_trailingspace(struct os_mbuf *om)
|
||||
#define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
|
||||
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
/**
|
||||
* Initializes an mqueue. An mqueue is a queue of mbufs that ties to a
|
||||
* particular task's event queue. Mqueues form a helper API around a common
|
||||
|
||||
@@ -170,7 +170,7 @@ typedef __uint128_t os_membuf_t;
|
||||
#define OS_MEMPOOL_BYTES(n,blksize) \
|
||||
(sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize)))
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
/**
|
||||
* Initialize a memory pool.
|
||||
*
|
||||
|
||||
+133
-346
@@ -3,382 +3,169 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "os/os.h"
|
||||
#include "hal/hal_uart.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "riscv/interrupt.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "driver/uart.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "hal/hal_uart.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
struct hal_uart {
|
||||
uint8_t u_open:1;
|
||||
uint8_t u_rx_stall:1;
|
||||
uint8_t u_tx_started:1;
|
||||
uint8_t u_tx_buf;
|
||||
hal_uart_rx_char u_rx_func;
|
||||
hal_uart_tx_char u_tx_func;
|
||||
hal_uart_tx_done u_tx_done;
|
||||
SemaphoreHandle_t u_rx_sem;
|
||||
static const char *TAG = "hal_uart";
|
||||
|
||||
#define BUF_SIZE (1024)
|
||||
#define RD_BUF_SIZE (BUF_SIZE)
|
||||
|
||||
typedef struct{
|
||||
bool uart_opened;
|
||||
uart_port_t port;
|
||||
uart_config_t cfg;
|
||||
QueueHandle_t evt_queue;
|
||||
TaskHandle_t rx_task_handler;
|
||||
hal_uart_tx_char tx_char;
|
||||
hal_uart_tx_done tx_done;
|
||||
hal_uart_rx_char rx_char;
|
||||
void *u_func_arg;
|
||||
};
|
||||
static struct hal_uart uart;
|
||||
|
||||
#define UART_FIFO_LEN (128)
|
||||
}hci_uart_t;
|
||||
|
||||
uint8_t rxbuffer[256];
|
||||
static uint16_t rd_ptr = 0;
|
||||
static uint16_t wr_ptr = 0;
|
||||
#define BUFFER_MASK (0xff)
|
||||
static hci_uart_t hci_uart;
|
||||
|
||||
static TaskHandle_t hci_uart_task_h;
|
||||
|
||||
void uart_init(uint32_t baud);
|
||||
void uart0_init(uint32_t baud);
|
||||
void uart0_tout_isr(void);
|
||||
void uart_tout_isr(void);
|
||||
void
|
||||
hal_uart_blocking_tx(int port, uint8_t data){
|
||||
|
||||
}
|
||||
int hal_uart_init(int uart_no, void *cfg)
|
||||
{
|
||||
// Uart_Init(uart_no, UART_CLK_FREQ_ROM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hal_uart_start_rx(int uart)
|
||||
{
|
||||
ets_printf("rx support???\n");
|
||||
}
|
||||
int hal_uart_init_cbs(int uart_no, hal_uart_tx_char tx_func,
|
||||
hal_uart_tx_done tx_done, hal_uart_rx_char rx_func, void *arg)
|
||||
hal_uart_tx_done tx_done, hal_uart_rx_char rx_func, void *arg)
|
||||
{
|
||||
struct hal_uart *u;
|
||||
|
||||
u = &uart;
|
||||
|
||||
if (u->u_open) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
u->u_rx_func = rx_func;
|
||||
u->u_tx_func = tx_func;
|
||||
u->u_tx_done = tx_done;
|
||||
u->u_func_arg = arg;
|
||||
hci_uart.tx_char=tx_func;
|
||||
hci_uart.rx_char=rx_func;
|
||||
hci_uart.tx_done=tx_done;
|
||||
hci_uart.u_func_arg = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hal_uart_config(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits,
|
||||
static void IRAM_ATTR hci_uart_rx_task(void *pvParameters)
|
||||
{
|
||||
uart_event_t event;
|
||||
uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
|
||||
while(hci_uart.uart_opened) {
|
||||
//Waiting for UART event.
|
||||
if(xQueueReceive(hci_uart.evt_queue, (void * )&event, (TickType_t)portMAX_DELAY)) {
|
||||
bzero(dtmp, RD_BUF_SIZE);
|
||||
ESP_LOGD(TAG, "uart[%d] event:", hci_uart.port);
|
||||
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.*/
|
||||
case UART_DATA:
|
||||
// ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
|
||||
uart_read_bytes(hci_uart.port, dtmp, event.size, portMAX_DELAY);
|
||||
for (int i = 0 ; i < event.size; i++) {
|
||||
hci_uart.rx_char(hci_uart.u_func_arg, dtmp[i]);
|
||||
}
|
||||
break;
|
||||
//Event of HW FIFO overflow detected
|
||||
case UART_FIFO_OVF:
|
||||
ESP_LOGI(TAG, "hw fifo overflow");
|
||||
// If fifo overflow happened, you should consider adding flow control for your application.
|
||||
// The ISR has already reset the rx FIFO,
|
||||
// As an example, we directly flush the rx buffer here in order to read more data.
|
||||
uart_flush_input(hci_uart.port);
|
||||
xQueueReset(hci_uart.evt_queue);
|
||||
break;
|
||||
//Event of UART ring buffer full
|
||||
case UART_BUFFER_FULL:
|
||||
ESP_LOGI(TAG, "ring buffer full");
|
||||
// If buffer full happened, you should consider encreasing your buffer size
|
||||
// As an example, we directly flush the rx buffer here in order to read more data.
|
||||
uart_flush_input(hci_uart.port);
|
||||
xQueueReset(hci_uart.evt_queue);
|
||||
break;
|
||||
//Event of UART RX break detected
|
||||
case UART_BREAK:
|
||||
ESP_LOGI(TAG, "uart rx break");
|
||||
break;
|
||||
//Event of UART parity check error
|
||||
case UART_PARITY_ERR:
|
||||
ESP_LOGI(TAG, "uart parity error");
|
||||
break;
|
||||
//Event of UART frame error
|
||||
case UART_FRAME_ERR:
|
||||
ESP_LOGI(TAG, "uart frame error");
|
||||
break;
|
||||
//Others
|
||||
default:
|
||||
ESP_LOGI(TAG, "uart event type: %d", event.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(dtmp);
|
||||
dtmp = NULL;
|
||||
hci_uart.rx_task_handler = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int hal_uart_config(int uart, int32_t speed, uint8_t data_bits, uint8_t stop_bits,
|
||||
enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl)
|
||||
{
|
||||
struct hal_uart *u;
|
||||
u = &uart;
|
||||
uart_config_t uart_cfg = {
|
||||
.baud_rate = speed,
|
||||
.data_bits = data_bits,
|
||||
.parity = parity,
|
||||
.stop_bits = stop_bits,
|
||||
.flow_ctrl = flow_ctl,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
};
|
||||
hci_uart.port = uart;
|
||||
hci_uart.cfg = uart_cfg;
|
||||
|
||||
if (u->u_open) {
|
||||
return -1;
|
||||
}
|
||||
if (uart_no) {
|
||||
uart_init(speed);
|
||||
} else {
|
||||
uart0_init(speed);
|
||||
}
|
||||
u->u_open = 1;
|
||||
int intr_alloc_flags = 0;
|
||||
#if CONFIG_UART_ISR_IN_IRAM
|
||||
intr_alloc_flags = ESP_INTR_FLAG_IRAM;
|
||||
#endif
|
||||
|
||||
ESP_ERROR_CHECK(uart_driver_install(uart, BUF_SIZE * 2, BUF_SIZE * 2, 20, &hci_uart.evt_queue, intr_alloc_flags));
|
||||
ESP_ERROR_CHECK(uart_param_config(uart, &hci_uart.cfg));
|
||||
ESP_ERROR_CHECK(uart_set_pin(uart, CONFIG_BT_NIMBLE_UART_TX_PIN, CONFIG_BT_NIMBLE_UART_RX_PIN, -1, -1));
|
||||
|
||||
hci_uart.uart_opened=true;
|
||||
ESP_LOGI(TAG, "set uart pin tx:%d, rx:%d.\n", CONFIG_BT_NIMBLE_UART_TX_PIN, CONFIG_BT_NIMBLE_UART_RX_PIN);
|
||||
ESP_LOGI(TAG, "set baud_rate:%d.\n", speed);
|
||||
|
||||
//Create a task to handler UART event from ISR
|
||||
xTaskCreate(hci_uart_rx_task, "hci_uart_rx_task", 2048, NULL, 12, &hci_uart.rx_task_handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
IRAM_ATTR_64MCPU hal_uart_tx_fill_buf(struct hal_uart *u, int uart_no)
|
||||
void IRAM_ATTR hal_uart_start_tx(int uart_no)
|
||||
{
|
||||
int data;
|
||||
int i;
|
||||
uart_dev_t *hw = &UART1;
|
||||
if(!uart_no){
|
||||
hw = &UART0;
|
||||
}
|
||||
i = 0;
|
||||
while(hw->status.txfifo_cnt < UART_FIFO_LEN){
|
||||
data = u->u_tx_func(u->u_func_arg);
|
||||
uint8_t u8_data=0;
|
||||
while(1){
|
||||
data = hci_uart.tx_char(hci_uart.u_func_arg);
|
||||
if (data >= 0) {
|
||||
hw->ahb_fifo.rw_byte = data;
|
||||
i++;
|
||||
u8_data = data;
|
||||
uart_tx_chars(uart_no,(char*)&u8_data,1);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void hal_uart_start_tx(int uart_no)
|
||||
{
|
||||
struct hal_uart *u;
|
||||
os_sr_t sr;
|
||||
uart_dev_t *hw = &UART1;
|
||||
if(!uart_no){
|
||||
hw = &UART0;
|
||||
if(hci_uart.tx_done) {
|
||||
hci_uart.tx_done(hci_uart.u_func_arg);
|
||||
}
|
||||
u = &uart;
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
if (u->u_tx_started == 0) {
|
||||
u->u_tx_started = 1;
|
||||
hw->int_ena.tx_done = 1;
|
||||
hal_uart_tx_fill_buf(u,uart_no);
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
int hal_uart0_close(int uart_no)
|
||||
{
|
||||
struct hal_uart *u;
|
||||
u = &uart;
|
||||
u->u_open = 0;
|
||||
|
||||
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_UART_CLK_EN);
|
||||
REG_SET_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_UART_RST);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hal_uart_close(int uart_no)
|
||||
{
|
||||
struct hal_uart *u;
|
||||
u = &uart;
|
||||
u->u_open = 0;
|
||||
hci_uart.uart_opened=false;
|
||||
// Stop uart rx task
|
||||
if(hci_uart.rx_task_handler != NULL) {
|
||||
ESP_LOGW(TAG,"Waiting for uart task finish...");
|
||||
}
|
||||
while (hci_uart.rx_task_handler != NULL);
|
||||
|
||||
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_UART1_CLK_EN);
|
||||
REG_SET_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_UART1_RST);
|
||||
uart_driver_delete(uart_no);
|
||||
ESP_LOGI(TAG,"hci uart close success.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IRAM_ATTR_64MCPU void uart0_tout_isr(void)
|
||||
{
|
||||
struct hal_uart *u;
|
||||
int rc;
|
||||
uint32_t ch;
|
||||
uart_dev_t *hw = &UART0;
|
||||
|
||||
u = &uart;
|
||||
uint32_t uart_int_st = hw->int_st.val;
|
||||
//clear
|
||||
hw->int_clr.val = uart_int_st;
|
||||
if (uart_int_st&UART_TX_DONE_INT_ST_M) {
|
||||
rc = hal_uart_tx_fill_buf(u,0);
|
||||
if (rc == 0) {
|
||||
if (u->u_tx_done) {
|
||||
u->u_tx_done(u->u_func_arg);
|
||||
}
|
||||
u->u_tx_started = 0;
|
||||
hw->int_ena.tx_done = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (hw->status.rxfifo_cnt) {
|
||||
int rd_len = hw->status.rxfifo_cnt;
|
||||
for (int i = 0; i < rd_len; i++) {
|
||||
ch = hw->ahb_fifo.rw_byte;
|
||||
rc = u->u_rx_func(u->u_func_arg, ch);
|
||||
if (rc < 0) {
|
||||
u->u_rx_stall = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
IRAM_ATTR_64MCPU void uart_tout_isr(void)
|
||||
{
|
||||
struct hal_uart *u;
|
||||
int rc;
|
||||
bool rx_update = false;
|
||||
uart_dev_t *hw = &UART1;
|
||||
u = &uart;
|
||||
uint32_t uart_int_st = hw->int_st.val;
|
||||
//clear
|
||||
hw->int_clr.val = uart_int_st;
|
||||
if (uart_int_st&UART_TX_DONE_INT_ST_M) {
|
||||
rc = hal_uart_tx_fill_buf(u,1);
|
||||
if (rc == 0) {
|
||||
if (u->u_tx_done) {
|
||||
u->u_tx_done(u->u_func_arg);
|
||||
}
|
||||
u->u_tx_started = 0;
|
||||
hw->int_ena.tx_done = 0;
|
||||
}
|
||||
}
|
||||
while (hw->status.rxfifo_cnt) {
|
||||
rxbuffer[(wr_ptr++)&BUFFER_MASK] = hw->ahb_fifo.rw_byte;
|
||||
rx_update = true;
|
||||
}
|
||||
if (rx_update) {
|
||||
xSemaphoreGiveFromISR(u->u_rx_sem, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IRAM_ATTR uart_rx_task(void *arg){
|
||||
int rc;
|
||||
struct hal_uart *u;
|
||||
u = &uart;
|
||||
while (1) {
|
||||
xSemaphoreTake(u->u_rx_sem, portMAX_DELAY);
|
||||
while (rd_ptr != wr_ptr){
|
||||
rc = u->u_rx_func(u->u_func_arg, rxbuffer[(rd_ptr++)&BUFFER_MASK]);
|
||||
if (rc < 0) {
|
||||
u->u_rx_stall = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uart0_init(uint32_t baud)
|
||||
{
|
||||
REG_SET_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_UART_RST);
|
||||
REG_CLR_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_UART_RST);
|
||||
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_UART_CLK_EN_M);
|
||||
REG_SET_BIT(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_UART_CLK_EN_M);
|
||||
|
||||
const int sclk_div = 1;
|
||||
uint32_t sclk_freq = XTAL_CLK_FREQ;
|
||||
uint32_t clk_div = ((sclk_freq) << 4) / baud;
|
||||
uart_dev_t *hw = &UART0;
|
||||
hw->clk_conf.sclk_en = 0;
|
||||
hw->clk_conf.rx_sclk_en = 0;
|
||||
hw->clk_conf.tx_sclk_en = 0;
|
||||
|
||||
|
||||
hw->clk_conf.sclk_en = 1;
|
||||
hw->clk_conf.rx_sclk_en = 1;
|
||||
hw->clk_conf.tx_sclk_en = 1;
|
||||
|
||||
hw->clk_div.div_int = clk_div >> 4;
|
||||
hw->clk_div.div_frag = clk_div & 0xf;
|
||||
hw->clk_conf.sclk_div_num = sclk_div - 1;//7;//255;
|
||||
|
||||
hw->conf0.parity_en = 0;
|
||||
|
||||
hw->conf0.irda_en = 0;
|
||||
hw->rs485_conf.en = 0;
|
||||
hw->rs485_conf.tx_rx_en = 0;
|
||||
hw->rs485_conf.rx_busy_tx_en = 0;
|
||||
|
||||
hw->conf0.bit_num = 3;
|
||||
hw->conf0.stop_bit_num = 1;
|
||||
|
||||
hw->conf1.rxfifo_full_thrhd = 80;
|
||||
|
||||
hw->mem_conf.rx_tout_thrhd = 20;
|
||||
hw->conf1.rx_tout_en = 1;
|
||||
|
||||
hw->conf1.rx_flow_en = 0;
|
||||
hw->conf0.tx_flow_en = 0;
|
||||
|
||||
hw->conf0.rxfifo_rst = 1;
|
||||
hw->conf0.rxfifo_rst = 0;
|
||||
hw->conf0.txfifo_rst = 1;
|
||||
hw->conf0.txfifo_rst = 0;
|
||||
hw->int_ena.rxfifo_full = 1;
|
||||
//enable rx fifo timeout interrupt
|
||||
hw->int_ena.rxfifo_tout = 1;
|
||||
|
||||
uint8_t tx_pin = 21, rx_pin = 20, ISR_ID = ETS_UART0_INUM;
|
||||
|
||||
ets_isr_mask((1<<ISR_ID)); //ETS_INTR_DISABLE
|
||||
|
||||
intr_handler_set(ISR_ID, (intr_handler_t)&uart0_tout_isr, NULL);
|
||||
intr_matrix_route(ETS_UART0_INTR_SOURCE, ISR_ID);
|
||||
esprv_intc_int_enable(BIT(ISR_ID));
|
||||
esprv_intc_int_set_type(ISR_ID, INTR_TYPE_LEVEL);
|
||||
esprv_intc_int_set_priority(ISR_ID, 1);
|
||||
|
||||
esp_intr_reserve(ISR_ID, xPortGetCoreID());
|
||||
|
||||
ESP_ERROR_CHECK(uart_set_pin(0, tx_pin, rx_pin, -1, -1));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void uart_init(uint32_t baud)
|
||||
{
|
||||
periph_module_enable(PERIPH_UART1_MODULE);
|
||||
|
||||
REG_SET_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_UART1_RST);
|
||||
REG_CLR_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_UART1_RST);
|
||||
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_UART1_CLK_EN_M);
|
||||
REG_SET_BIT(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_UART1_CLK_EN_M);
|
||||
|
||||
const int sclk_div = 1;
|
||||
uint32_t sclk_freq = XTAL_CLK_FREQ;
|
||||
|
||||
uint32_t clk_div = ((sclk_freq) << 4) / baud;
|
||||
struct hal_uart *u = &uart;
|
||||
|
||||
uart_dev_t *hw = &UART1;
|
||||
hw->clk_conf.sclk_en = 0;
|
||||
hw->clk_conf.rx_sclk_en = 0;
|
||||
hw->clk_conf.tx_sclk_en = 0;
|
||||
|
||||
|
||||
hw->clk_conf.sclk_en = 1;
|
||||
hw->clk_conf.rx_sclk_en = 1;
|
||||
hw->clk_conf.tx_sclk_en = 1;
|
||||
|
||||
hw->clk_div.div_int = clk_div >> 4;
|
||||
hw->clk_div.div_frag = clk_div & 0xf;
|
||||
hw->clk_conf.sclk_div_num = sclk_div - 1;//7;//255;
|
||||
|
||||
hw->conf0.parity_en = 0;
|
||||
|
||||
hw->conf0.irda_en = 0;
|
||||
hw->rs485_conf.en = 0;
|
||||
hw->rs485_conf.tx_rx_en = 0;
|
||||
hw->rs485_conf.rx_busy_tx_en = 0;
|
||||
|
||||
hw->conf0.bit_num = 3;
|
||||
hw->conf0.stop_bit_num = 1;
|
||||
|
||||
//set full threshold to (2/3)*FIFO_LEN
|
||||
hw->conf1.rxfifo_full_thrhd = 80;
|
||||
hw->mem_conf.rx_tout_thrhd = 20;
|
||||
|
||||
hw->conf1.rx_tout_en = 1;
|
||||
|
||||
hw->conf0.rxfifo_rst = 1;
|
||||
hw->conf0.rxfifo_rst = 0;
|
||||
hw->conf0.txfifo_rst = 1;
|
||||
hw->conf0.txfifo_rst = 0;
|
||||
hw->int_ena.rxfifo_full = 1;
|
||||
//enable rx fifo timeout interrupt
|
||||
hw->int_ena.rxfifo_tout = 1;
|
||||
|
||||
u->u_rx_sem = xSemaphoreCreateBinary();
|
||||
|
||||
uint8_t TX_IO = CONFIG_BT_LE_HCI_UART_TX_PIN, RX_IO = CONFIG_BT_LE_HCI_UART_RX_PIN, ISR_ID = ETS_UART1_INUM;
|
||||
printf("set nimble port tx:%d, rx:%d.\n", TX_IO, RX_IO);
|
||||
printf("set baud:%d.\n", baud);
|
||||
intr_handler_set(ISR_ID, (intr_handler_t)&uart_tout_isr, NULL);
|
||||
intr_matrix_route(ETS_UART1_INTR_SOURCE, ISR_ID);
|
||||
esprv_intc_int_enable(BIT(ISR_ID));
|
||||
esprv_intc_int_set_type(ISR_ID, INTR_TYPE_LEVEL);
|
||||
esprv_intc_int_set_priority(ISR_ID, 1);
|
||||
// TODO ESP32-C3 IDF-2126, maybe can use interrupt allocation API for all of the above? unsure...
|
||||
esp_intr_reserve(ISR_ID, xPortGetCoreID());
|
||||
|
||||
ESP_ERROR_CHECK(uart_set_pin(1, TX_IO, RX_IO, -1, -1));
|
||||
|
||||
//Enable hw flow control of UART1 for BQB test, which if not enabled, the tester takes quite long time to send a byte to DUT
|
||||
|
||||
|
||||
// uart_ll_set_hw_flow_ctrl(hw, UART_HW_FLOWCTRL_CTS_RTS, 110);
|
||||
|
||||
xTaskCreate(uart_rx_task, "uart_rx", CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE,
|
||||
NULL, 1, &hci_uart_task_h);
|
||||
}
|
||||
|
||||
@@ -35,10 +35,15 @@
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED
|
||||
#include "esp_bt.h"
|
||||
#if !SOC_ESP_NIMBLE_CONTROLLER
|
||||
#endif
|
||||
#if !SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
#include "esp_nimble_hci.h"
|
||||
#endif
|
||||
#if !CONFIG_BT_CONTROLLER_ENABLED
|
||||
#include "nimble/transport.h"
|
||||
#endif
|
||||
|
||||
#define NIMBLE_PORT_LOG_TAG "BLE_INIT"
|
||||
|
||||
@@ -80,16 +85,31 @@ nimble_port_stop_cb(struct ble_npl_event *ev)
|
||||
*/
|
||||
esp_err_t esp_nimble_init(void)
|
||||
{
|
||||
#if !SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if CONFIG_BT_CONTROLLER_DISABLED
|
||||
esp_err_t ret;
|
||||
#endif
|
||||
#if !SOC_ESP_NIMBLE_CONTROLLER || !CONFIG_BT_CONTROLLER_ENABLED
|
||||
/* Initialize the function pointers for OS porting */
|
||||
npl_freertos_funcs_init();
|
||||
|
||||
npl_freertos_mempool_init();
|
||||
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED
|
||||
if(esp_nimble_hci_init() != ESP_OK) {
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "hci inits failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#else
|
||||
ret = ble_buf_alloc();
|
||||
if (ret != ESP_OK) {
|
||||
ble_buf_free();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ble_transport_init();
|
||||
#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK)
|
||||
ble_adv_list_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Initialize default event queue */
|
||||
ble_npl_eventq_init(&g_eventq_dflt);
|
||||
@@ -100,6 +120,9 @@ esp_err_t esp_nimble_init(void)
|
||||
#endif
|
||||
/* Initialize the host */
|
||||
ble_transport_hs_init();
|
||||
#if CONFIG_BT_CONTROLLER_DISABLED && CONFIG_BT_NIMBLE_TRANSPORT_UART
|
||||
ble_transport_ll_init();
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -112,15 +135,23 @@ esp_err_t esp_nimble_init(void)
|
||||
esp_err_t esp_nimble_deinit(void)
|
||||
{
|
||||
#if !SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED
|
||||
if(esp_nimble_hci_deinit() != ESP_OK) {
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "hci deinit failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#else
|
||||
#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK)
|
||||
ble_adv_list_deinit();
|
||||
#endif
|
||||
ble_transport_deinit();
|
||||
ble_buf_free();
|
||||
#endif
|
||||
|
||||
ble_npl_eventq_deinit(&g_eventq_dflt);
|
||||
#endif
|
||||
ble_hs_deinit();
|
||||
#if !SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if !SOC_ESP_NIMBLE_CONTROLLER || !CONFIG_BT_CONTROLLER_ENABLED
|
||||
npl_freertos_funcs_deinit();
|
||||
#endif
|
||||
return ESP_OK;
|
||||
@@ -136,7 +167,7 @@ nimble_port_init(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#if CONFIG_IDF_TARGET_ESP32 && CONFIG_BT_CONTROLLER_ENABLED
|
||||
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
||||
#endif
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "nimble/nimble_port.h"
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED
|
||||
#include "esp_bt.h"
|
||||
#endif
|
||||
|
||||
static TaskHandle_t host_task_h = NULL;
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ static const char *TAG = "Timer";
|
||||
|
||||
#define BLE_TOTAL_MUTEX_COUNT (10)
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
|
||||
struct os_mempool ble_freertos_ev_pool;
|
||||
static os_membuf_t *ble_freertos_ev_buf = NULL;
|
||||
@@ -1145,7 +1145,7 @@ int npl_freertos_mempool_init(void)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
ble_freertos_ev_buf = malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos)) * sizeof(os_membuf_t));
|
||||
if(!ble_freertos_ev_buf) {
|
||||
goto _error;
|
||||
@@ -1205,7 +1205,7 @@ int npl_freertos_mempool_init(void)
|
||||
}
|
||||
_error:
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
if(ble_freertos_ev_buf) {
|
||||
free(ble_freertos_ev_buf);
|
||||
ble_freertos_ev_buf = NULL;
|
||||
@@ -1236,7 +1236,7 @@ _error:
|
||||
|
||||
void npl_freertos_mempool_deinit(void)
|
||||
{
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
if(ble_freertos_ev_buf) {
|
||||
free(ble_freertos_ev_buf);
|
||||
ble_freertos_ev_buf = NULL;
|
||||
|
||||
Reference in New Issue
Block a user