bt: hci driver over spi: BlueNRG-MS read until IRQ pin goes low

According to BlueNRG-MS ref manual, SPI master shoul read  from
controller as long as IRQ pin is high.
Introduce a new loop within spi_rx_thread to do so. Since
it is now possible to enter read loop with nothing to read, set
a max attempts limit to be sure to exit the loop.

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@st.com>
This commit is contained in:
Christophe Priouzeau 2018-06-26 13:30:26 +02:00 committed by Carles Cufí
commit 7b02e6dc55

View file

@ -99,6 +99,11 @@ void spi_dump_message(const u8_t *pre, u8_t *buf, u8_t size) {}
#if defined(CONFIG_BT_SPI_BLUENRG)
static struct device *cs_dev;
/* Define a limit when reading IRQ high */
/* It can be required to be increased for */
/* some particular cases. */
#define IRQ_HIGH_MAX_READ 3
static u8_t attempts;
#endif /* CONFIG_BT_SPI_BLUENRG */
static struct device *spi_dev;
@ -168,7 +173,7 @@ static void bt_spi_handle_vendor_evt(u8_t *rxmsg)
* know the amount of byte to read.
* (See section 5.2 of BlueNRG-MS datasheet)
*/
static int bt_spi_configure_cs(void)
static int configure_cs(void)
{
cs_dev = device_get_binding(CONFIG_BT_SPI_CHIP_SELECT_DEV_NAME);
if (!cs_dev) {
@ -184,20 +189,50 @@ static int bt_spi_configure_cs(void)
return 0;
}
static void bt_spi_kick_cs(void)
static void kick_cs(void)
{
gpio_pin_write(cs_dev, GPIO_CS_PIN, 1);
gpio_pin_write(cs_dev, GPIO_CS_PIN, 0);
}
static void bt_spi_release_cs(void)
static void release_cs(void)
{
gpio_pin_write(cs_dev, GPIO_CS_PIN, 1);
}
static bool irq_pin_high(void)
{
u32_t pin_state;
gpio_pin_read(irq_dev, GPIO_IRQ_PIN, &pin_state);
BT_DBG("IRQ Pin: %d", pin_state);
return pin_state;
}
static void init_irq_high_loop(void)
{
attempts = IRQ_HIGH_MAX_READ;
}
static bool exit_irq_high_loop(void)
{
/* Limit attempts on BlueNRG-MS as we might */
/* enter this loop with nothing to read */
attempts--;
return attempts;
}
#else
#define bt_spi_configure_cs(...) 0
#define bt_spi_kick_cs(...)
#define bt_spi_release_cs(...)
#define configure_cs(...) 0
#define kick_cs(...)
#define release_cs(...)
#define irq_pin_high(...) 0
#define init_irq_high_loop(...)
#define exit_irq_high_loop(...) 1
#endif
static void bt_spi_rx_thread(void)
@ -220,11 +255,14 @@ static void bt_spi_rx_thread(void)
BT_DBG("");
do {
bt_spi_kick_cs();
init_irq_high_loop();
do {
kick_cs();
ret = bt_spi_transceive(header_master, 5,
header_slave, 5);
} while ((header_slave[STATUS_HEADER_TOREAD] == 0 ||
header_slave[STATUS_HEADER_TOREAD] == 0xFF) && !ret);
} while ((((header_slave[STATUS_HEADER_TOREAD] == 0 ||
header_slave[STATUS_HEADER_TOREAD] == 0xFF) &&
!ret)) && exit_irq_high_loop());
if (!ret) {
size = header_slave[STATUS_HEADER_TOREAD];
@ -235,7 +273,7 @@ static void bt_spi_rx_thread(void)
} while (rxmsg[0] == 0 && ret == 0);
}
bt_spi_release_cs();
release_cs();
gpio_pin_enable_callback(irq_dev, GPIO_IRQ_PIN);
k_sem_give(&sem_busy);
@ -283,6 +321,9 @@ static void bt_spi_rx_thread(void)
} else {
bt_recv(buf);
}
/* On BlueNRG-MS, host is expected to read */
/* as long as IRQ pin is high */
} while (irq_pin_high());
}
}
@ -326,7 +367,7 @@ static int bt_spi_send(struct net_buf *buf)
/* Poll sanity values until device has woken-up */
do {
bt_spi_kick_cs();
kick_cs();
ret = bt_spi_transceive(header, 5, rxmsg, 5);
/*
@ -348,7 +389,7 @@ static int bt_spi_send(struct net_buf *buf)
} while (rxmsg[0] == 0 && !ret);
}
bt_spi_release_cs();
release_cs();
if (ret) {
BT_ERR("Error %d", ret);
@ -384,6 +425,9 @@ static int bt_spi_open(void)
/* Configure IRQ pin and the IRQ call-back/handler */
gpio_pin_configure(irq_dev, GPIO_IRQ_PIN,
#if defined(CONFIG_BT_SPI_BLUENRG)
GPIO_PUD_PULL_DOWN |
#endif
GPIO_DIR_IN | GPIO_INT |
GPIO_INT_EDGE | GPIO_INT_ACTIVE_HIGH);
@ -431,7 +475,7 @@ static int _bt_spi_init(struct device *unused)
return -EIO;
}
if (bt_spi_configure_cs()) {
if (configure_cs()) {
return -EIO;
}