mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-06 22:57:22 +00:00
nimble/transport: Update UART transport
This commit is contained in:
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef H_BLE_HCI_UART_
|
|
||||||
#define H_BLE_HCI_UART_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ble_hci_uart_init(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -18,20 +18,15 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
pkg.name: nimble/transport/uart
|
pkg.name: nimble/transport/uart
|
||||||
pkg.description: XXX
|
pkg.description: HCI H4 transport over UART
|
||||||
pkg.author: "Apache Mynewt <[email protected]>"
|
pkg.author: "Apache Mynewt <[email protected]>"
|
||||||
pkg.homepage: "http://mynewt.apache.org/"
|
pkg.homepage: "https://mynewt.apache.org/"
|
||||||
pkg.keywords:
|
|
||||||
- ble
|
|
||||||
- bluetooth
|
|
||||||
|
|
||||||
pkg.deps:
|
pkg.deps:
|
||||||
- "@apache-mynewt-core/hw/hal"
|
- "@apache-mynewt-core/hw/hal"
|
||||||
- "@apache-mynewt-core/kernel/os"
|
- "@apache-mynewt-core/kernel/os"
|
||||||
- nimble
|
- nimble
|
||||||
|
- nimble/transport/common/hci_h4
|
||||||
|
|
||||||
pkg.apis:
|
pkg.apis:
|
||||||
- ble_transport
|
- ble_transport
|
||||||
|
|
||||||
pkg.init:
|
|
||||||
ble_hci_uart_init: 'MYNEWT_VAL(BLE_TRANS_UART_SYSINIT_STAGE)'
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sysinit/sysinit.h>
|
||||||
|
#include <syscfg/syscfg.h>
|
||||||
|
#include "os/os_mbuf.h"
|
||||||
|
#include "os/os_mempool.h"
|
||||||
|
#include "hal/hal_uart.h"
|
||||||
|
#include "nimble/transport.h"
|
||||||
|
#include "nimble/transport/hci_h4.h"
|
||||||
|
|
||||||
|
#define TX_Q_SIZE (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) + \
|
||||||
|
MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) + \
|
||||||
|
MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT))
|
||||||
|
|
||||||
|
struct hci_uart_tx {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t sent_type;
|
||||||
|
uint16_t len;
|
||||||
|
uint16_t idx;
|
||||||
|
|
||||||
|
struct os_mbuf *om;
|
||||||
|
uint8_t *buf;
|
||||||
|
|
||||||
|
STAILQ_ENTRY(hci_uart_tx) tx_q_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static STAILQ_HEAD(, hci_uart_tx) tx_q;
|
||||||
|
|
||||||
|
static struct os_mempool pool_tx_q;
|
||||||
|
static uint8_t pool_tx_q_buf[ OS_MEMPOOL_BYTES(TX_Q_SIZE,
|
||||||
|
sizeof(struct hci_uart_tx)) ];
|
||||||
|
|
||||||
|
struct hci_h4_sm hci_uart_h4sm;
|
||||||
|
|
||||||
|
static int
|
||||||
|
hci_uart_frame_cb(uint8_t pkt_type, void *data)
|
||||||
|
{
|
||||||
|
switch (pkt_type) {
|
||||||
|
case HCI_H4_CMD:
|
||||||
|
return ble_transport_to_ll_cmd(data);
|
||||||
|
case HCI_H4_ACL:
|
||||||
|
return ble_transport_to_ll_acl(data);
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hci_uart_rx_char(void *arg, uint8_t data)
|
||||||
|
{
|
||||||
|
hci_h4_sm_rx(&hci_uart_h4sm, &data, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hci_uart_tx_char(void *arg)
|
||||||
|
{
|
||||||
|
struct hci_uart_tx *tx;
|
||||||
|
uint8_t ch;
|
||||||
|
os_sr_t sr;
|
||||||
|
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
tx = STAILQ_FIRST(&tx_q);
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
if (!tx) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tx->sent_type) {
|
||||||
|
tx->sent_type = 1;
|
||||||
|
return tx->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tx->type) {
|
||||||
|
case HCI_H4_EVT:
|
||||||
|
ch = tx->buf[tx->idx];
|
||||||
|
tx->idx++;
|
||||||
|
if (tx->idx == tx->len) {
|
||||||
|
ble_transport_free(tx->buf);
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
STAILQ_REMOVE_HEAD(&tx_q, tx_q_next);
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
os_memblock_put(&pool_tx_q, tx);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HCI_H4_ACL:
|
||||||
|
os_mbuf_copydata(tx->om, 0, 1, &ch);
|
||||||
|
os_mbuf_adj(tx->om, 1);
|
||||||
|
tx->len--;
|
||||||
|
if (tx->len == 0) {
|
||||||
|
os_mbuf_free_chain(tx->om);
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
STAILQ_REMOVE_HEAD(&tx_q, tx_q_next);
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
os_memblock_put(&pool_tx_q, tx);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
STAILQ_REMOVE_HEAD(&tx_q, tx_q_next);
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
os_memblock_put(&pool_tx_q, tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hci_uart_configure(void)
|
||||||
|
{
|
||||||
|
enum hal_uart_parity parity;
|
||||||
|
enum hal_uart_flow_ctl flowctl;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = hal_uart_init_cbs(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT),
|
||||||
|
hci_uart_tx_char, NULL,
|
||||||
|
hci_uart_rx_char, NULL);
|
||||||
|
if (rc != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_PARITY, odd)) {
|
||||||
|
parity = HAL_UART_PARITY_ODD;
|
||||||
|
} else if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_PARITY, even)) {
|
||||||
|
parity = HAL_UART_PARITY_EVEN;
|
||||||
|
} else {
|
||||||
|
parity = HAL_UART_PARITY_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_FLOW_CONTROL, rtscts)) {
|
||||||
|
flowctl = HAL_UART_FLOW_CTL_RTS_CTS;
|
||||||
|
} else {
|
||||||
|
flowctl = HAL_UART_FLOW_CTL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = hal_uart_config(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT),
|
||||||
|
MYNEWT_VAL(BLE_TRANSPORT_UART_BAUDRATE),
|
||||||
|
MYNEWT_VAL(BLE_TRANSPORT_UART_DATA_BITS),
|
||||||
|
MYNEWT_VAL(BLE_TRANSPORT_UART_STOP_BITS),
|
||||||
|
parity, flowctl);
|
||||||
|
if (rc != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_transport_to_hs_evt(void *buf)
|
||||||
|
{
|
||||||
|
struct hci_uart_tx *txe;
|
||||||
|
os_sr_t sr;
|
||||||
|
|
||||||
|
txe = os_memblock_get(&pool_tx_q);
|
||||||
|
if (!txe) {
|
||||||
|
assert(0);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
txe->type = HCI_H4_EVT;
|
||||||
|
txe->sent_type = 0;
|
||||||
|
txe->len = 2 + ((uint8_t *)buf)[1];
|
||||||
|
txe->buf = buf;
|
||||||
|
txe->idx = 0;
|
||||||
|
txe->om = NULL;
|
||||||
|
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next);
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
|
||||||
|
hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_transport_to_hs_acl(struct os_mbuf *om)
|
||||||
|
{
|
||||||
|
struct hci_uart_tx *txe;
|
||||||
|
os_sr_t sr;
|
||||||
|
|
||||||
|
txe = os_memblock_get(&pool_tx_q);
|
||||||
|
if (!txe) {
|
||||||
|
assert(0);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
txe->type = HCI_H4_ACL;
|
||||||
|
txe->sent_type = 0;
|
||||||
|
txe->len = 2 + OS_MBUF_PKTLEN(om);
|
||||||
|
txe->idx = 0;
|
||||||
|
txe->buf = NULL;
|
||||||
|
txe->om = om;
|
||||||
|
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next);
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
|
||||||
|
hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_transport_hs_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
SYSINIT_ASSERT_ACTIVE();
|
||||||
|
|
||||||
|
rc = hci_uart_configure();
|
||||||
|
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
rc = os_mempool_init(&pool_tx_q, TX_Q_SIZE, sizeof(struct hci_uart_tx),
|
||||||
|
pool_tx_q_buf, "hci_uart_tx_q");
|
||||||
|
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
hci_h4_sm_init(&hci_uart_h4sm, &hci_h4_allocs_from_hs, hci_uart_frame_cb);
|
||||||
|
|
||||||
|
STAILQ_INIT(&tx_q);
|
||||||
|
}
|
||||||
@@ -17,45 +17,23 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
syscfg.defs:
|
syscfg.defs:
|
||||||
BLE_HCI_ACL_OUT_COUNT:
|
BLE_TRANSPORT_UART_PORT:
|
||||||
description: >
|
description: UART index to use for HCI interface
|
||||||
This count is used in creating a pool of elements used by the
|
value: 0
|
||||||
code to enqueue various elements. In the case of the controller
|
BLE_TRANSPORT_UART_BAUDRATE:
|
||||||
only HCI, this number should be equal to the number of mbufs in
|
description: Baudrate on UART
|
||||||
the msys pool. For host only, it is really dependent on the
|
value: 1000000
|
||||||
number of ACL buffers that the controller tells the host it
|
BLE_TRANSPORT_UART_DATA_BITS:
|
||||||
has.
|
description: Number of data bits on UART
|
||||||
value: 12
|
value: 8
|
||||||
|
BLE_TRANSPORT_UART_STOP_BITS:
|
||||||
BLE_HCI_UART_PORT:
|
description: Number of stop bits on UART
|
||||||
description: 'The uart to use for the HCI uart interface'
|
value: 1
|
||||||
value: 0
|
BLE_TRANSPORT_UART_PARITY:
|
||||||
BLE_HCI_UART_BAUD:
|
description: Parity on UART
|
||||||
description: 'The baud rate of the HCI uart interface'
|
value: none
|
||||||
value: 1000000
|
choices: none,even,odd
|
||||||
BLE_HCI_UART_DATA_BITS:
|
BLE_TRANSPORT_UART_FLOW_CONTROL:
|
||||||
description: 'Number of data bits used for HCI uart interface'
|
description: Flow control on UART
|
||||||
value: 8
|
choices: off,rtscts
|
||||||
BLE_HCI_UART_STOP_BITS:
|
value: rtscts
|
||||||
description: 'Number of stop bits used for HCI uart interface'
|
|
||||||
value: 1
|
|
||||||
BLE_HCI_UART_PARITY:
|
|
||||||
description: 'Parity used for HCI uart interface'
|
|
||||||
value: HAL_UART_PARITY_NONE
|
|
||||||
BLE_HCI_UART_FLOW_CTRL:
|
|
||||||
description: 'Flow control used for HCI uart interface'
|
|
||||||
value: HAL_UART_FLOW_CTL_RTS_CTS
|
|
||||||
BLE_TRANS_UART_SYSINIT_STAGE:
|
|
||||||
description: >
|
|
||||||
Sysinit stage for the UART BLE transport.
|
|
||||||
value: 500
|
|
||||||
|
|
||||||
syscfg.vals.BLE_EXT_ADV:
|
|
||||||
BLE_HCI_EVT_BUF_SIZE: 257
|
|
||||||
|
|
||||||
syscfg.vals:
|
|
||||||
BLE_HCI_EVT_BUF_SIZE: 70
|
|
||||||
BLE_HCI_EVT_HI_BUF_COUNT: 8
|
|
||||||
BLE_HCI_EVT_LO_BUF_COUNT: 8
|
|
||||||
BLE_ACL_BUF_COUNT: 12
|
|
||||||
BLE_ACL_BUF_SIZE: 255
|
|
||||||
|
|||||||
Reference in New Issue
Block a user