mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-09-11 11:40:01 +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.description: XXX
|
||||
pkg.description: HCI H4 transport over UART
|
||||
pkg.author: "Apache Mynewt <[email protected]>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
pkg.keywords:
|
||||
- ble
|
||||
- bluetooth
|
||||
pkg.homepage: "https://mynewt.apache.org/"
|
||||
|
||||
pkg.deps:
|
||||
- "@apache-mynewt-core/hw/hal"
|
||||
- "@apache-mynewt-core/kernel/os"
|
||||
- nimble
|
||||
- nimble/transport/common/hci_h4
|
||||
|
||||
pkg.apis:
|
||||
- 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:
|
||||
BLE_HCI_ACL_OUT_COUNT:
|
||||
description: >
|
||||
This count is used in creating a pool of elements used by the
|
||||
code to enqueue various elements. In the case of the controller
|
||||
only HCI, this number should be equal to the number of mbufs in
|
||||
the msys pool. For host only, it is really dependent on the
|
||||
number of ACL buffers that the controller tells the host it
|
||||
has.
|
||||
value: 12
|
||||
|
||||
BLE_HCI_UART_PORT:
|
||||
description: 'The uart to use for the HCI uart interface'
|
||||
value: 0
|
||||
BLE_HCI_UART_BAUD:
|
||||
description: 'The baud rate of the HCI uart interface'
|
||||
value: 1000000
|
||||
BLE_HCI_UART_DATA_BITS:
|
||||
description: 'Number of data bits used for HCI uart interface'
|
||||
value: 8
|
||||
BLE_HCI_UART_STOP_BITS:
|
||||
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
|
||||
BLE_TRANSPORT_UART_PORT:
|
||||
description: UART index to use for HCI interface
|
||||
value: 0
|
||||
BLE_TRANSPORT_UART_BAUDRATE:
|
||||
description: Baudrate on UART
|
||||
value: 1000000
|
||||
BLE_TRANSPORT_UART_DATA_BITS:
|
||||
description: Number of data bits on UART
|
||||
value: 8
|
||||
BLE_TRANSPORT_UART_STOP_BITS:
|
||||
description: Number of stop bits on UART
|
||||
value: 1
|
||||
BLE_TRANSPORT_UART_PARITY:
|
||||
description: Parity on UART
|
||||
value: none
|
||||
choices: none,even,odd
|
||||
BLE_TRANSPORT_UART_FLOW_CONTROL:
|
||||
description: Flow control on UART
|
||||
choices: off,rtscts
|
||||
value: rtscts
|
||||
|
||||
Reference in New Issue
Block a user