Bluetooth: SPI: introduce CONFIG_BLUETOOTH_SPI_BLUENRG

This new option is used to encapsulate the logic specific to devices
implementing the BlueNRG Bluetooth stack (e.g. X-NUCLEO-IDB05A1).

The current BlueNRG specific logic covers the HCI Reset handling and
the manual control of the SPI Chip Select line (normally not needed since
spi_transceive is also responsible for controlling the SPI CS line).

Change-Id: I5db4addf873eee0af2d957e2181c50aac53ab656
Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
This commit is contained in:
Ricardo Salveti 2017-01-25 22:24:45 -02:00 committed by Johan Hedberg
commit 4afe063aad
2 changed files with 29 additions and 2 deletions

View file

@ -46,7 +46,7 @@ config BLUETOOTH_SPI
HCI packets are sent and received as single Byte transferrs, HCI packets are sent and received as single Byte transferrs,
prepended after a known header. Headers may vary per device, so prepended after a known header. Headers may vary per device, so
additional platform specific knowlege may need to be added as additional platform specific knowlege may need to be added as
devices are. Current driver supports; ST X-NUCLEO BLE series. devices are.
config BLUETOOTH_NO_DRIVER config BLUETOOTH_NO_DRIVER
bool "No default HCI driver" bool "No default HCI driver"
@ -108,8 +108,16 @@ config BLUETOOTH_HCI_RECV_RESERVE
if BLUETOOTH_SPI if BLUETOOTH_SPI
config BLUETOOTH_SPI_BLUENRG
bool "Enable compatibility with BlueNRG-based devices"
default n
help
Enable support for devices compatible with the BlueNRG Bluetooth
Stack. Current driver supports: ST X-NUCLEO BLE series.
config BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME config BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME
string "Chip Select (CS) line driver name" string "Chip Select (CS) line driver name"
depends on BLUETOOTH_SPI_BLUENRG
help help
This option specifies the name of GPIO driver controlling This option specifies the name of GPIO driver controlling
the Chip Select (CS) line. the Chip Select (CS) line.
@ -128,6 +136,7 @@ config BLUETOOTH_SPI_RESET_DEV_NAME
config BLUETOOTH_SPI_CHIP_SELECT_PIN config BLUETOOTH_SPI_CHIP_SELECT_PIN
int "SPI Chip Select (CS) line number" int "SPI Chip Select (CS) line number"
depends on BLUETOOTH_SPI_BLUENRG
help help
This option specifies the Chip Select (CS) line number on the SPI This option specifies the Chip Select (CS) line number on the SPI
device device

View file

@ -43,14 +43,18 @@
#define CMD_OCF 2 #define CMD_OCF 2
#define GPIO_IRQ_PIN CONFIG_BLUETOOTH_SPI_IRQ_PIN #define GPIO_IRQ_PIN CONFIG_BLUETOOTH_SPI_IRQ_PIN
#define GPIO_CS_PIN CONFIG_BLUETOOTH_SPI_CHIP_SELECT_PIN
#define GPIO_RESET_PIN CONFIG_BLUETOOTH_SPI_RESET_PIN #define GPIO_RESET_PIN CONFIG_BLUETOOTH_SPI_RESET_PIN
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
#define GPIO_CS_PIN CONFIG_BLUETOOTH_SPI_CHIP_SELECT_PIN
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
#define MAX_RX_MSG_LEN CONFIG_BLUETOOTH_SPI_RX_BUFFER_SIZE #define MAX_RX_MSG_LEN CONFIG_BLUETOOTH_SPI_RX_BUFFER_SIZE
#define MAX_TX_MSG_LEN CONFIG_BLUETOOTH_SPI_TX_BUFFER_SIZE #define MAX_TX_MSG_LEN CONFIG_BLUETOOTH_SPI_TX_BUFFER_SIZE
static struct device *spi_dev; static struct device *spi_dev;
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
static struct device *cs_dev; static struct device *cs_dev;
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
static struct device *irq_dev; static struct device *irq_dev;
static struct device *rst_dev; static struct device *rst_dev;
@ -131,8 +135,10 @@ static void bt_spi_rx_thread(void)
k_sem_take(&sem_busy, K_FOREVER); k_sem_take(&sem_busy, K_FOREVER);
do { do {
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); gpio_pin_write(cs_dev, GPIO_CS_PIN, 1);
gpio_pin_write(cs_dev, GPIO_CS_PIN, 0); gpio_pin_write(cs_dev, GPIO_CS_PIN, 0);
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
spi_transceive(spi_dev, spi_transceive(spi_dev,
header_master, 5, header_slave, 5); header_master, 5, header_slave, 5);
} while (header_slave[STATUS_HEADER_TOREAD] == 0 || } while (header_slave[STATUS_HEADER_TOREAD] == 0 ||
@ -144,7 +150,9 @@ static void bt_spi_rx_thread(void)
spi_transceive(spi_dev, &dummy, 1, &rxmsg[i], 1); spi_transceive(spi_dev, &dummy, 1, &rxmsg[i], 1);
} }
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); gpio_pin_write(cs_dev, GPIO_CS_PIN, 1);
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
k_sem_give(&sem_busy); k_sem_give(&sem_busy);
spi_dump_message("RX:ed", rxmsg, size); spi_dump_message("RX:ed", rxmsg, size);
@ -221,8 +229,10 @@ static int bt_spi_send(struct net_buf *buf)
/* Poll sanity values until device has woken-up */ /* Poll sanity values until device has woken-up */
do { do {
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); gpio_pin_write(cs_dev, GPIO_CS_PIN, 1);
gpio_pin_write(cs_dev, GPIO_CS_PIN, 0); gpio_pin_write(cs_dev, GPIO_CS_PIN, 0);
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
spi_transceive(spi_dev, header, 5, rxmsg, 5); spi_transceive(spi_dev, header, 5, rxmsg, 5);
/* /*
@ -236,12 +246,15 @@ static int bt_spi_send(struct net_buf *buf)
/* Transmit the message */ /* Transmit the message */
spi_transceive(spi_dev, buf->data, buf->len, rxmsg, buf->len); spi_transceive(spi_dev, buf->data, buf->len, rxmsg, buf->len);
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
/* Deselect chip */ /* Deselect chip */
gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); gpio_pin_write(cs_dev, GPIO_CS_PIN, 1);
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
k_sem_give(&sem_busy); k_sem_give(&sem_busy);
spi_dump_message("TX:ed", buf->data, buf->len); spi_dump_message("TX:ed", buf->data, buf->len);
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
/* /*
* Since a RESET has been requested, the chip will now restart. * Since a RESET has been requested, the chip will now restart.
* Unfortunately the BlueNRG will reply with "reset received" but * Unfortunately the BlueNRG will reply with "reset received" but
@ -252,6 +265,7 @@ static int bt_spi_send(struct net_buf *buf)
if (bt_spi_get_cmd(buf->data) == BT_HCI_OP_RESET) { if (bt_spi_get_cmd(buf->data) == BT_HCI_OP_RESET) {
k_sem_take(&sem_initialised, K_FOREVER); k_sem_take(&sem_initialised, K_FOREVER);
} }
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
net_buf_unref(buf); net_buf_unref(buf);
@ -267,10 +281,12 @@ static int bt_spi_open(void)
spi_configure(spi_dev, &spi_conf); spi_configure(spi_dev, &spi_conf);
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
/* Configure the CS (Chip Select) pin */ /* Configure the CS (Chip Select) pin */
gpio_pin_configure(cs_dev, GPIO_CS_PIN, gpio_pin_configure(cs_dev, GPIO_CS_PIN,
GPIO_DIR_OUT | GPIO_PUD_PULL_UP); GPIO_DIR_OUT | GPIO_PUD_PULL_UP);
gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); gpio_pin_write(cs_dev, GPIO_CS_PIN, 1);
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
/* Configure IRQ pin and the IRQ call-back/handler */ /* Configure IRQ pin and the IRQ call-back/handler */
gpio_pin_configure(irq_dev, GPIO_IRQ_PIN, gpio_pin_configure(irq_dev, GPIO_IRQ_PIN,
@ -319,12 +335,14 @@ static int _bt_spi_init(struct device *unused)
return -EIO; return -EIO;
} }
#if defined(CONFIG_BLUETOOTH_SPI_BLUENRG)
cs_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME); cs_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME);
if (!cs_dev) { if (!cs_dev) {
BT_ERR("Failed to initialize GPIO driver: %s", BT_ERR("Failed to initialize GPIO driver: %s",
CONFIG_BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME); CONFIG_BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME);
return -EIO; return -EIO;
} }
#endif /* CONFIG_BLUETOOTH_SPI_BLUENRG */
irq_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_IRQ_DEV_NAME); irq_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_IRQ_DEV_NAME);
if (!irq_dev) { if (!irq_dev) {