nimble/transport: Update UART transport

This commit is contained in:
Andrzej Kaczmarek
2022-03-17 11:48:16 +01:00
parent 33c1ece041
commit aefb9d4a90
5 changed files with 270 additions and 1270 deletions
@@ -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
+3 -8
View File
@@ -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
+247
View File
@@ -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);
}
+20 -42
View File
@@ -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