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/log.h>
|
||||
|
||||
#include <net/buf.h>
|
||||
|
||||
#include "gap_internal.h"
|
||||
#include "uart.h"
|
||||
#include "rpc.h"
|
||||
|
@ -32,40 +34,6 @@
|
|||
#define NBLE_RESET_PIN NBLE_SWDIO_PIN
|
||||
#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;
|
||||
|
||||
void on_nble_up(void)
|
||||
|
@ -142,10 +110,6 @@ int bt_enable(bt_ready_cb_t cb)
|
|||
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();
|
||||
if (ret) {
|
||||
return ret;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <bluetooth/log.h>
|
||||
|
||||
#include "uart.h"
|
||||
#include "rpc.h"
|
||||
|
||||
/* TODO: check size */
|
||||
#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 NET_BUF_POOL(tx_pool, NBLE_IPC_COUNT, NBLE_BUF_SIZE, &tx, NULL, 0);
|
||||
|
||||
enum {
|
||||
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 BT_STACK_NOINIT(rx_fiber_stack, 256);
|
||||
|
||||
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)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
|
@ -137,22 +112,6 @@ void rpc_transmit_cb(uint8_t *p_buf, uint16_t length)
|
|||
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,
|
||||
size_t len, size_t min)
|
||||
{
|
||||
|
@ -265,84 +224,20 @@ void bt_uart_isr(void *unused)
|
|||
BT_DBG("full packet received");
|
||||
|
||||
/* Pass buffer to the stack */
|
||||
uart_frame_recv(buf->len, buf->data);
|
||||
net_buf_unref(buf);
|
||||
buf = NULL;
|
||||
nano_fifo_put(&rx_queue, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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_tx_disable(nble_dev);
|
||||
|
||||
|
@ -362,8 +257,6 @@ int nble_open(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct ipc_uart_info info;
|
||||
|
||||
static int _bt_nble_init(struct device *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(tx_pool);
|
||||
|
||||
nble_dev->driver_data = &info;
|
||||
ipc_uart_ns16550_init(nble_dev);
|
||||
/* TODO: Register nble driver */
|
||||
|
||||
return DEV_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,6 @@ struct ipc_uart_channels {
|
|||
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);
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue