Bluetooth: nble: Move receive logic to fiber
Move receiving logic to fiber rx_fiber(). rx_queue is registered with uart driver and all data is sent there for processing. Clean up old ipc_channel interface since there will be only one interface to uart driver. Change-Id: I292863b1f38e5adb8ca4e6ac63aed09c83de56bf Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This commit is contained in:
parent
96aaaadca8
commit
702b151e47
3 changed files with 28 additions and 177 deletions
|
@ -24,6 +24,8 @@
|
||||||
#include <bluetooth/conn.h>
|
#include <bluetooth/conn.h>
|
||||||
#include <bluetooth/log.h>
|
#include <bluetooth/log.h>
|
||||||
|
|
||||||
|
#include <net/buf.h>
|
||||||
|
|
||||||
#include "gap_internal.h"
|
#include "gap_internal.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "rpc.h"
|
#include "rpc.h"
|
||||||
|
@ -32,40 +34,6 @@
|
||||||
#define NBLE_RESET_PIN NBLE_SWDIO_PIN
|
#define NBLE_RESET_PIN NBLE_SWDIO_PIN
|
||||||
#define NBLE_BTWAKE_PIN 5
|
#define NBLE_BTWAKE_PIN 5
|
||||||
|
|
||||||
#define NBLE_CHANNEL 0
|
|
||||||
|
|
||||||
static void *channel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function handling the events from the UART IPC (irq).
|
|
||||||
*
|
|
||||||
* @param channel Channel on which the event applies
|
|
||||||
* @param request IPC_MSG_TYPE_MESSAGE when a new message was received,
|
|
||||||
* IPC_MSG_TYPE_FREE when the previous message was sent and can be freed.
|
|
||||||
* @param len Length of the data
|
|
||||||
* @param p_data Pointer to the data
|
|
||||||
* @return 0
|
|
||||||
*/
|
|
||||||
static int recv_cb(int channel, int request, int len, void *p_data)
|
|
||||||
{
|
|
||||||
BT_DBG("channel %d request %d len %d", channel, request, len);
|
|
||||||
|
|
||||||
switch (request) {
|
|
||||||
case IPC_MSG_TYPE_MESSAGE:
|
|
||||||
rpc_deserialize(p_data, len);
|
|
||||||
break;
|
|
||||||
case IPC_MSG_TYPE_FREE:
|
|
||||||
/* TODO: Try to send another message immediately */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Free the message */
|
|
||||||
BT_ERR("Unsupported RPC request");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bt_ready_cb_t bt_ready_cb;
|
static bt_ready_cb_t bt_ready_cb;
|
||||||
|
|
||||||
void on_nble_up(void)
|
void on_nble_up(void)
|
||||||
|
@ -142,10 +110,6 @@ int bt_enable(bt_ready_cb_t cb)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the UART channel for RPC while Nordic is in reset */
|
|
||||||
channel = ipc_uart_channel_open(NBLE_CHANNEL, recv_cb);
|
|
||||||
BT_DBG("channel %p", channel);
|
|
||||||
|
|
||||||
ret = nble_open();
|
ret = nble_open();
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <bluetooth/log.h>
|
#include <bluetooth/log.h>
|
||||||
|
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
#include "rpc.h"
|
||||||
|
|
||||||
/* TODO: check size */
|
/* TODO: check size */
|
||||||
#define NBLE_IPC_COUNT 1
|
#define NBLE_IPC_COUNT 1
|
||||||
|
@ -39,54 +40,28 @@ static NET_BUF_POOL(rx_pool, NBLE_IPC_COUNT, NBLE_BUF_SIZE, &rx, NULL, 0);
|
||||||
static struct nano_fifo tx;
|
static struct nano_fifo tx;
|
||||||
static NET_BUF_POOL(tx_pool, NBLE_IPC_COUNT, NBLE_BUF_SIZE, &tx, NULL, 0);
|
static NET_BUF_POOL(tx_pool, NBLE_IPC_COUNT, NBLE_BUF_SIZE, &tx, NULL, 0);
|
||||||
|
|
||||||
enum {
|
static BT_STACK_NOINIT(rx_fiber_stack, 256);
|
||||||
STATUS_TX_IDLE = 0,
|
|
||||||
STATUS_TX_BUSY,
|
|
||||||
STATUS_TX_DONE,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
STATUS_RX_IDLE = 0,
|
|
||||||
STATUS_RX_HDR,
|
|
||||||
STATUS_RX_DATA
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the uart IPC to handle
|
|
||||||
*/
|
|
||||||
struct ipc_uart_info {
|
|
||||||
int uart_num; /* UART device to use */
|
|
||||||
uint32_t irq_vector; /* IRQ number */
|
|
||||||
uint32_t irq_mask; /* IRQ mask */
|
|
||||||
|
|
||||||
/* callback to be called to set wake state when TX is starting
|
|
||||||
* or ending
|
|
||||||
*/
|
|
||||||
void (*tx_cb)(bool wake_state, void*);
|
|
||||||
void *tx_cb_param; /* tx_cb function parameter */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipc_uart {
|
|
||||||
uint8_t *tx_data;
|
|
||||||
uint8_t *rx_ptr;
|
|
||||||
struct ipc_uart_channels channels[IPC_UART_MAX_CHANNEL];
|
|
||||||
struct ipc_uart_header tx_hdr;
|
|
||||||
struct ipc_uart_header rx_hdr;
|
|
||||||
uint16_t send_counter;
|
|
||||||
uint16_t rx_size;
|
|
||||||
uint8_t tx_state;
|
|
||||||
uint8_t rx_state;
|
|
||||||
uint8_t uart_enabled;
|
|
||||||
/* protect against multiple wakelock and wake assert calls */
|
|
||||||
uint8_t tx_wakelock_acquired;
|
|
||||||
/* TODO: remove once IRQ will take a parameter */
|
|
||||||
struct device *device;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct ipc_uart ipc;
|
|
||||||
|
|
||||||
static struct device *nble_dev;
|
static struct device *nble_dev;
|
||||||
|
|
||||||
|
static struct nano_fifo rx_queue;
|
||||||
|
|
||||||
|
static void rx_fiber(void)
|
||||||
|
{
|
||||||
|
BT_DBG("Started");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
buf = nano_fifo_get(&rx_queue, TICKS_UNLIMITED);
|
||||||
|
BT_DBG("Got buf %p", buf);
|
||||||
|
|
||||||
|
rpc_deserialize(buf->data, buf->len);
|
||||||
|
|
||||||
|
net_buf_unref(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t *rpc_alloc_cb(uint16_t length)
|
uint8_t *rpc_alloc_cb(uint16_t length)
|
||||||
{
|
{
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
@ -137,22 +112,6 @@ void rpc_transmit_cb(uint8_t *p_buf, uint16_t length)
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_frame_recv(uint16_t len, uint8_t *p_data)
|
|
||||||
{
|
|
||||||
BT_DBG("rcv: len: %d data len %d src %d channel %d",
|
|
||||||
ipc.rx_hdr.len, len, ipc.rx_hdr.src_cpu_id, ipc.rx_hdr.channel);
|
|
||||||
|
|
||||||
if ((ipc.rx_hdr.channel < IPC_UART_MAX_CHANNEL) &&
|
|
||||||
(ipc.channels[ipc.rx_hdr.channel].cb != NULL)) {
|
|
||||||
ipc.channels[ipc.rx_hdr.channel].cb(ipc.rx_hdr.channel,
|
|
||||||
IPC_MSG_TYPE_MESSAGE,
|
|
||||||
len,
|
|
||||||
p_data);
|
|
||||||
} else {
|
|
||||||
BT_ERR("uart_ipc: bad channel %d", ipc.rx_hdr.channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nble_read(struct device *uart, uint8_t *buf,
|
static int nble_read(struct device *uart, uint8_t *buf,
|
||||||
size_t len, size_t min)
|
size_t len, size_t min)
|
||||||
{
|
{
|
||||||
|
@ -265,84 +224,20 @@ void bt_uart_isr(void *unused)
|
||||||
BT_DBG("full packet received");
|
BT_DBG("full packet received");
|
||||||
|
|
||||||
/* Pass buffer to the stack */
|
/* Pass buffer to the stack */
|
||||||
uart_frame_recv(buf->len, buf->data);
|
nano_fifo_put(&rx_queue, buf);
|
||||||
net_buf_unref(buf);
|
|
||||||
buf = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ipc_uart_channel_open(int channel_id,
|
|
||||||
int (*cb)(int, int, int, void *))
|
|
||||||
{
|
|
||||||
struct ipc_uart_channels *chan;
|
|
||||||
|
|
||||||
if (channel_id > (IPC_UART_MAX_CHANNEL - 1))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
chan = &ipc.channels[channel_id];
|
|
||||||
|
|
||||||
if (chan->state != IPC_CHANNEL_STATE_CLOSED)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
chan->state = IPC_CHANNEL_STATE_OPEN;
|
|
||||||
chan->cb = cb;
|
|
||||||
|
|
||||||
ipc.uart_enabled = 1;
|
|
||||||
|
|
||||||
return chan;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_uart_close_channel(int channel_id)
|
|
||||||
{
|
|
||||||
ipc.channels[channel_id].state = IPC_CHANNEL_STATE_CLOSED;
|
|
||||||
ipc.channels[channel_id].cb = NULL;
|
|
||||||
ipc.channels[channel_id].index = channel_id;
|
|
||||||
|
|
||||||
ipc.uart_enabled = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_uart_ns16550_set_tx_cb(struct device *dev, void (*cb)(bool, void*),
|
|
||||||
void *param)
|
|
||||||
{
|
|
||||||
struct ipc_uart_info *info = dev->driver_data;
|
|
||||||
|
|
||||||
info->tx_cb = cb;
|
|
||||||
info->tx_cb_param = param;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ipc_uart_ns16550_init(struct device *dev)
|
|
||||||
{
|
|
||||||
struct ipc_uart_info *info = dev->driver_data;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Fail init if no info defined */
|
|
||||||
if (!info) {
|
|
||||||
BT_ERR("No driver data found");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < IPC_UART_MAX_CHANNEL; i++) {
|
|
||||||
ipc_uart_close_channel(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set dev used in irq handler */
|
|
||||||
ipc.device = dev;
|
|
||||||
|
|
||||||
ipc.uart_enabled = 0;
|
|
||||||
|
|
||||||
/* Initialize the reception pointer */
|
|
||||||
ipc.rx_size = sizeof(ipc.rx_hdr);
|
|
||||||
ipc.rx_ptr = (uint8_t *)&ipc.rx_hdr;
|
|
||||||
ipc.rx_state = STATUS_RX_IDLE;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nble_open(void)
|
int nble_open(void)
|
||||||
{
|
{
|
||||||
BT_DBG("");
|
BT_DBG("");
|
||||||
|
|
||||||
|
/* Initialize receive queue and start rx_fiber */
|
||||||
|
nano_fifo_init(&rx_queue);
|
||||||
|
fiber_start(rx_fiber_stack, sizeof(rx_fiber_stack),
|
||||||
|
(nano_fiber_entry_t)rx_fiber, 0, 0, 7, 0);
|
||||||
|
|
||||||
uart_irq_rx_disable(nble_dev);
|
uart_irq_rx_disable(nble_dev);
|
||||||
uart_irq_tx_disable(nble_dev);
|
uart_irq_tx_disable(nble_dev);
|
||||||
|
|
||||||
|
@ -362,8 +257,6 @@ int nble_open(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ipc_uart_info info;
|
|
||||||
|
|
||||||
static int _bt_nble_init(struct device *unused)
|
static int _bt_nble_init(struct device *unused)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(unused);
|
ARG_UNUSED(unused);
|
||||||
|
@ -376,10 +269,6 @@ static int _bt_nble_init(struct device *unused)
|
||||||
net_buf_pool_init(rx_pool);
|
net_buf_pool_init(rx_pool);
|
||||||
net_buf_pool_init(tx_pool);
|
net_buf_pool_init(tx_pool);
|
||||||
|
|
||||||
nble_dev->driver_data = &info;
|
|
||||||
ipc_uart_ns16550_init(nble_dev);
|
|
||||||
/* TODO: Register nble driver */
|
|
||||||
|
|
||||||
return DEV_OK;
|
return DEV_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,6 @@ struct ipc_uart_channels {
|
||||||
int (*cb)(int chan, int request, int len, void *data);
|
int (*cb)(int chan, int request, int len, void *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
void ipc_uart_isr(void);
|
|
||||||
void ipc_uart_ns16550_disable(struct device *dev);
|
|
||||||
int nble_open(void);
|
int nble_open(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue