drivers: bluetooth: hci: Remove ST vendor code from spi.c
Remove ST vendor code from spi.c. Update CMakeLists to select ST vendor file for ST BlueNRG devices. Signed-off-by: Ali Hozhabri <ali.hozhabri@st.com>
This commit is contained in:
parent
98d6dbf787
commit
8b8be3c7aa
2 changed files with 41 additions and 252 deletions
|
|
@ -19,7 +19,13 @@ zephyr_library_sources_ifdef(CONFIG_BT_ESP32 hci_esp32.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_BT_H4 h4.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_H5 h5.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_HCI_IPC ipc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_SPI spi.c)
|
||||
if(CONFIG_BT_SPI)
|
||||
if ((CONFIG_DT_HAS_ST_HCI_SPI_V1_ENABLED) OR (CONFIG_DT_HAS_ST_HCI_SPI_V2_ENABLED))
|
||||
zephyr_library_sources(hci_spi_st.c)
|
||||
else()
|
||||
zephyr_library_sources(spi.c)
|
||||
endif()
|
||||
endif()
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_STM32_IPM ipm_stm32wb.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_STM32WBA hci_stm32wba.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_USERCHAN userchan.c)
|
||||
|
|
|
|||
|
|
@ -86,16 +86,6 @@ static K_SEM_DEFINE(sem_busy, 1, 1);
|
|||
static K_KERNEL_STACK_DEFINE(spi_rx_stack, CONFIG_BT_DRV_RX_STACK_SIZE);
|
||||
static struct k_thread spi_rx_thread_data;
|
||||
|
||||
#if defined(CONFIG_BT_BLUENRG_ACI)
|
||||
#define BLUENRG_ACI_WRITE_CONFIG_DATA BT_OP(BT_OGF_VS, 0x000C)
|
||||
#define BLUENRG_CONFIG_PUBADDR_OFFSET 0x00
|
||||
#define BLUENRG_CONFIG_PUBADDR_LEN 0x06
|
||||
#define BLUENRG_CONFIG_LL_ONLY_OFFSET 0x2C
|
||||
#define BLUENRG_CONFIG_LL_ONLY_LEN 0x01
|
||||
|
||||
static int bt_spi_send_aci_config(uint8_t offset, const uint8_t *value, size_t value_len);
|
||||
#endif /* CONFIG_BT_BLUENRG_ACI */
|
||||
|
||||
static const struct spi_dt_spec bus = SPI_DT_SPEC_INST_GET(
|
||||
0, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 0);
|
||||
|
||||
|
|
@ -146,12 +136,6 @@ static bool bt_spi_handle_vendor_evt(uint8_t *msg)
|
|||
switch (bt_spi_get_evt(msg)) {
|
||||
case EVT_BLUE_INITIALIZED: {
|
||||
k_sem_give(&sem_initialised);
|
||||
#if defined(CONFIG_BT_BLUENRG_ACI)
|
||||
/* force BlueNRG to be on controller mode */
|
||||
uint8_t data = 1;
|
||||
|
||||
bt_spi_send_aci_config(BLUENRG_CONFIG_LL_ONLY_OFFSET, &data, 1);
|
||||
#endif
|
||||
handled = true;
|
||||
}
|
||||
default:
|
||||
|
|
@ -160,144 +144,6 @@ static bool bt_spi_handle_vendor_evt(uint8_t *msg)
|
|||
return handled;
|
||||
}
|
||||
|
||||
#define IS_IRQ_HIGH gpio_pin_get_dt(&irq_gpio)
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v1)
|
||||
/* Define a limit when reading IRQ high */
|
||||
/* It can be required to be increased for */
|
||||
/* some particular cases. */
|
||||
#define IRQ_HIGH_MAX_READ 3
|
||||
/* On BlueNRG-MS, host is expected to read */
|
||||
/* as long as IRQ pin is high */
|
||||
#define READ_CONDITION IS_IRQ_HIGH
|
||||
/* We cannot retry write data without reading again the header */
|
||||
#define WRITE_DATA_CONDITION(...) true
|
||||
|
||||
static void assert_cs(void)
|
||||
{
|
||||
gpio_pin_set_dt(&bus.config.cs.gpio, 0);
|
||||
gpio_pin_set_dt(&bus.config.cs.gpio, 1);
|
||||
}
|
||||
|
||||
static void release_cs(bool data_transaction)
|
||||
{
|
||||
ARG_UNUSED(data_transaction);
|
||||
gpio_pin_set_dt(&bus.config.cs.gpio, 0);
|
||||
}
|
||||
|
||||
static int bt_spi_get_header(uint8_t op, uint16_t *size)
|
||||
{
|
||||
uint8_t header_master[5] = {op, 0, 0, 0, 0};
|
||||
uint8_t header_slave[5];
|
||||
uint8_t size_offset, attempts;
|
||||
int ret;
|
||||
|
||||
if (op == SPI_READ) {
|
||||
if (!IS_IRQ_HIGH) {
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
size_offset = STATUS_HEADER_TOREAD;
|
||||
} else if (op == SPI_WRITE) {
|
||||
size_offset = STATUS_HEADER_TOWRITE;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
attempts = IRQ_HIGH_MAX_READ;
|
||||
do {
|
||||
if (op == SPI_READ) {
|
||||
/* Keep checking that IRQ is still high, if we need to read */
|
||||
if (!IS_IRQ_HIGH) {
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
assert_cs();
|
||||
ret = bt_spi_transceive(header_master, 5, header_slave, 5);
|
||||
if (ret) {
|
||||
/* SPI transaction failed */
|
||||
break;
|
||||
}
|
||||
|
||||
*size = (header_slave[STATUS_HEADER_READY] == READY_NOW) ?
|
||||
header_slave[size_offset] : 0;
|
||||
attempts--;
|
||||
} while ((*size == 0) && attempts);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v2)
|
||||
|
||||
#define READ_CONDITION false
|
||||
/* We cannot retry writing data without reading the header again */
|
||||
#define WRITE_DATA_CONDITION(...) true
|
||||
|
||||
static void assert_cs(uint16_t delay)
|
||||
{
|
||||
gpio_pin_set_dt(&bus.config.cs.gpio, 0);
|
||||
if (delay) {
|
||||
k_sleep(K_USEC(delay));
|
||||
}
|
||||
gpio_pin_set_dt(&bus.config.cs.gpio, 1);
|
||||
gpio_pin_interrupt_configure_dt(&irq_gpio, GPIO_INT_DISABLE);
|
||||
}
|
||||
|
||||
static void release_cs(bool data_transaction)
|
||||
{
|
||||
/* Consume possible event signals */
|
||||
while (k_sem_take(&sem_request, K_NO_WAIT) == 0) {
|
||||
}
|
||||
if (data_transaction) {
|
||||
/* Wait for IRQ to become low only when data phase has been performed */
|
||||
while (IS_IRQ_HIGH) {
|
||||
}
|
||||
}
|
||||
gpio_pin_interrupt_configure_dt(&irq_gpio, GPIO_INT_EDGE_TO_ACTIVE);
|
||||
gpio_pin_set_dt(&bus.config.cs.gpio, 0);
|
||||
}
|
||||
|
||||
static int bt_spi_get_header(uint8_t op, uint16_t *size)
|
||||
{
|
||||
uint8_t header_master[5] = {op, 0, 0, 0, 0};
|
||||
uint8_t header_slave[5];
|
||||
uint16_t cs_delay;
|
||||
uint8_t size_offset;
|
||||
int ret;
|
||||
|
||||
if (op == SPI_READ) {
|
||||
if (!IS_IRQ_HIGH) {
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
cs_delay = 0;
|
||||
size_offset = STATUS_HEADER_TOREAD;
|
||||
} else if (op == SPI_WRITE) {
|
||||
/* To make sure we have a minimum delay from previous release cs */
|
||||
cs_delay = 100;
|
||||
size_offset = STATUS_HEADER_TOWRITE;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
assert_cs(cs_delay);
|
||||
/* Wait up to a maximum time of 100 ms */
|
||||
if (!WAIT_FOR(IS_IRQ_HIGH, 100000, k_usleep(100))) {
|
||||
LOG_ERR("IRQ pin did not raise");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = bt_spi_transceive(header_master, 5, header_slave, 5);
|
||||
*size = header_slave[size_offset] | (header_slave[size_offset + 1] << 8);
|
||||
return ret;
|
||||
}
|
||||
/* Other Boards */
|
||||
#else
|
||||
|
||||
#define release_cs(...)
|
||||
#define READ_CONDITION false
|
||||
#define WRITE_DATA_CONDITION(ret, rx_first) (rx_first != 0U || ret)
|
||||
|
||||
static int bt_spi_get_header(uint8_t op, uint16_t *size)
|
||||
{
|
||||
uint8_t header_master[5] = {op, 0, 0, 0, 0};
|
||||
|
|
@ -334,47 +180,6 @@ static int bt_spi_get_header(uint8_t op, uint16_t *size)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v1) */
|
||||
|
||||
#if defined(CONFIG_BT_BLUENRG_ACI)
|
||||
static int bt_spi_send_aci_config(uint8_t offset, const uint8_t *value, size_t value_len)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
uint8_t *cmd_data;
|
||||
size_t data_len = 2 + value_len;
|
||||
|
||||
buf = bt_hci_cmd_create(BLUENRG_ACI_WRITE_CONFIG_DATA, data_len);
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
cmd_data = net_buf_add(buf, data_len);
|
||||
cmd_data[0] = offset;
|
||||
cmd_data[1] = value_len;
|
||||
memcpy(&cmd_data[2], value, value_len);
|
||||
|
||||
return bt_hci_cmd_send(BLUENRG_ACI_WRITE_CONFIG_DATA, buf);
|
||||
}
|
||||
|
||||
static int bt_spi_bluenrg_setup(const struct bt_hci_setup_params *params)
|
||||
{
|
||||
int ret;
|
||||
const bt_addr_t *addr = ¶ms->public_addr;
|
||||
|
||||
if (!bt_addr_eq(addr, BT_ADDR_NONE) && !bt_addr_eq(addr, BT_ADDR_ANY)) {
|
||||
ret = bt_spi_send_aci_config(
|
||||
BLUENRG_CONFIG_PUBADDR_OFFSET,
|
||||
addr->val, sizeof(addr->val));
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Failed to set BlueNRG public address (%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_BLUENRG_ACI */
|
||||
|
||||
static struct net_buf *bt_spi_rx_buf_construct(uint8_t *msg)
|
||||
{
|
||||
|
|
@ -453,48 +258,44 @@ static void bt_spi_rx_thread(void *p1, void *p2, void *p3)
|
|||
|
||||
LOG_DBG("");
|
||||
|
||||
do {
|
||||
/* Wait for SPI bus to be available */
|
||||
k_sem_take(&sem_busy, K_FOREVER);
|
||||
ret = bt_spi_get_header(SPI_READ, &size);
|
||||
/* Wait for SPI bus to be available */
|
||||
k_sem_take(&sem_busy, K_FOREVER);
|
||||
ret = bt_spi_get_header(SPI_READ, &size);
|
||||
|
||||
/* Delay here is rounded up to next tick */
|
||||
k_sleep(K_USEC(DATA_DELAY_US));
|
||||
/* Read data */
|
||||
if (ret == 0 && size != 0) {
|
||||
do {
|
||||
ret = bt_spi_transceive(&txmsg, size,
|
||||
&rxmsg, size);
|
||||
if (rxmsg[0] == 0U) {
|
||||
/* Consider increasing controller-data-delay-us
|
||||
* if this message is extremely common.
|
||||
*/
|
||||
LOG_DBG("Controller not ready for SPI transaction "
|
||||
"of %d bytes", size);
|
||||
}
|
||||
} while (rxmsg[0] == 0U && ret == 0);
|
||||
}
|
||||
|
||||
release_cs(size > 0);
|
||||
|
||||
k_sem_give(&sem_busy);
|
||||
|
||||
if (ret || size == 0) {
|
||||
if (ret) {
|
||||
LOG_ERR("Error %d", ret);
|
||||
/* Delay here is rounded up to next tick */
|
||||
k_sleep(K_USEC(DATA_DELAY_US));
|
||||
/* Read data */
|
||||
if (ret == 0 && size != 0) {
|
||||
do {
|
||||
ret = bt_spi_transceive(&txmsg, size,
|
||||
&rxmsg, size);
|
||||
if (rxmsg[0] == 0U) {
|
||||
/* Consider increasing controller-data-delay-us
|
||||
* if this message is extremely common.
|
||||
*/
|
||||
LOG_DBG("Controller not ready for SPI transaction "
|
||||
"of %d bytes", size);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} while (rxmsg[0] == 0U && ret == 0);
|
||||
}
|
||||
|
||||
LOG_HEXDUMP_DBG(rxmsg, size, "SPI RX");
|
||||
k_sem_give(&sem_busy);
|
||||
|
||||
/* Construct net_buf from SPI data */
|
||||
buf = bt_spi_rx_buf_construct(rxmsg);
|
||||
if (buf) {
|
||||
/* Handle the received HCI data */
|
||||
bt_recv(buf);
|
||||
if (ret || size == 0) {
|
||||
if (ret) {
|
||||
LOG_ERR("Error %d", ret);
|
||||
}
|
||||
} while (READ_CONDITION);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_HEXDUMP_DBG(rxmsg, size, "SPI RX");
|
||||
|
||||
/* Construct net_buf from SPI data */
|
||||
buf = bt_spi_rx_buf_construct(rxmsg);
|
||||
if (buf) {
|
||||
/* Handle the received HCI data */
|
||||
bt_recv(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -544,7 +345,7 @@ static int bt_spi_send(struct net_buf *buf)
|
|||
while (true) {
|
||||
ret = bt_spi_transceive(buf->data, size,
|
||||
rx_first, 1);
|
||||
if (WRITE_DATA_CONDITION(ret, rx_first[0])) {
|
||||
if (rx_first[0] != 0U || ret) {
|
||||
break;
|
||||
}
|
||||
/* Consider increasing controller-data-delay-us
|
||||
|
|
@ -554,8 +355,6 @@ static int bt_spi_send(struct net_buf *buf)
|
|||
}
|
||||
}
|
||||
|
||||
release_cs(size > 0);
|
||||
|
||||
k_sem_give(&sem_busy);
|
||||
|
||||
if (ret) {
|
||||
|
|
@ -565,18 +364,6 @@ static int bt_spi_send(struct net_buf *buf)
|
|||
|
||||
LOG_HEXDUMP_DBG(buf->data, buf->len, "SPI TX");
|
||||
|
||||
#if (DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v1) || DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v2))
|
||||
/*
|
||||
* Since a RESET has been requested, the chip will now restart.
|
||||
* Unfortunately the BlueNRG will reply with "reset received" but
|
||||
* since it does not send back a NOP, we have no way to tell when the
|
||||
* RESET has actually taken place. Instead, we use the vendor command
|
||||
* EVT_BLUE_INITIALIZED as an indication that it is safe to proceed.
|
||||
*/
|
||||
if (bt_spi_get_cmd(buf->data) == BT_HCI_OP_RESET) {
|
||||
k_sem_take(&sem_initialised, K_FOREVER);
|
||||
}
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v1) || DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v2) */
|
||||
out:
|
||||
net_buf_unref(buf);
|
||||
|
||||
|
|
@ -631,10 +418,6 @@ static int bt_spi_open(void)
|
|||
static const struct bt_hci_driver drv = {
|
||||
.name = DEVICE_DT_NAME(DT_DRV_INST(0)),
|
||||
.bus = BT_HCI_DRIVER_BUS_SPI,
|
||||
#if defined(CONFIG_BT_BLUENRG_ACI)
|
||||
.quirks = BT_QUIRK_NO_RESET,
|
||||
.setup = bt_spi_bluenrg_setup,
|
||||
#endif /* CONFIG_BT_BLUENRG_ACI */
|
||||
.open = bt_spi_open,
|
||||
.send = bt_spi_send,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue