From 3b13bf58f8cf9022afc19ce970295fd4e6b24163 Mon Sep 17 00:00:00 2001 From: Leif Jakob Date: Sat, 11 May 2019 19:14:54 +0000 Subject: [PATCH] Merged in leif_jakob/nuttx/nrf24l01-support-for-O_NONBLOCK-W_TX_PAYLOAD_NOACK (pull request #868) nrf24l01: don't block in read if file descriptor is O_NONBLOCK nrf24l01: support for "multicast" TX mode - no waiting for ACK (needs to be enabled with fcntl SETTXPAYLOADNOACK) Approved-by: Gregory Nutt --- drivers/wireless/nrf24l01.c | 45 ++++++++++++++++++++++++++++--- include/nuttx/wireless/nrf24l01.h | 2 ++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/drivers/wireless/nrf24l01.c b/drivers/wireless/nrf24l01.c index 1c42778f90..c2ef445bba 100644 --- a/drivers/wireless/nrf24l01.c +++ b/drivers/wireless/nrf24l01.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -143,6 +144,7 @@ struct nrf24l01_dev_s nrf24l01_state_t state; /* Current state of the nRF24L01 */ + bool tx_payload_noack; /* TX without waiting for ACK */ uint8_t en_aa; /* Cache EN_AA register value */ uint8_t en_pipes; /* Cache EN_RXADDR register value */ bool ce_enabled; /* Cache the value of CE pin */ @@ -843,9 +845,9 @@ static int dosend(FAR struct nrf24l01_dev_s *dev, FAR const uint8_t *data, nrf24l01_flush_tx(dev); - /* Write payload */ + /* Write payload - use different command depending on ACK setting */ - nrf24l01_access(dev, MODE_WRITE, NRF24L01_W_TX_PAYLOAD, + nrf24l01_access(dev, MODE_WRITE, dev->tx_payload_noack ? NRF24L01_W_TX_PAYLOAD_NOACK : NRF24L01_W_TX_PAYLOAD, (FAR uint8_t *)data, datalen); dev->tx_pending = true; @@ -1057,7 +1059,24 @@ static ssize_t nrf24l01_read(FAR struct file *filep, FAR char *buffer, return ret; } + if (filep->f_oflags & O_NONBLOCK) + { + /* test if data is ready */ + int packet_count; + ret = nxsem_getvalue(&dev->sem_rx, &packet_count); + if (ret) + { + goto errout; /* getvalue failed */ + } + if (!packet_count) + { + ret = -EWOULDBLOCK; /* don't wait for packets */ + goto errout; + } + } + ret = nrf24l01_recv(dev, (uint8_t *)buffer, buflen, &dev->last_recvpipeno); +errout: nxsem_post(&dev->devsem); return ret; #endif @@ -1323,6 +1342,24 @@ static int nrf24l01_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; } + case NRF24L01IOC_SETTXPAYLOADNOACK: + { + FAR uint32_t *tx_payload_noack = (FAR uint32_t *)(arg); + DEBUGASSERT(tx_payload_noack != NULL); + + dev->tx_payload_noack = (*tx_payload_noack) > 0; + break; + } + + case NRF24L01IOC_GETTXPAYLOADNOACK: + { + FAR uint32_t *tx_payload_noack = (FAR uint32_t *)(arg); + DEBUGASSERT(tx_payload_noack != NULL); + + *tx_payload_noack = dev->tx_payload_noack ? 1 : 0; + break; + } + default: ret = -ENOTTY; break; @@ -1527,9 +1564,9 @@ int nrf24l01_init(FAR struct nrf24l01_dev_s *dev) nrf24l01_configspi(dev->spi); - /* Enable features. */ + /* Enable features in hardware: dynamic payload length + sending without expecting ACK */ - nrf24l01_writeregbyte(dev, NRF24L01_FEATURE, NRF24L01_EN_DPL); + nrf24l01_writeregbyte(dev, NRF24L01_FEATURE, NRF24L01_EN_DPL | NRF24L01_EN_DYN_ACK); features = nrf24l01_readregbyte(dev, NRF24L01_FEATURE); if (0 == features) { diff --git a/include/nuttx/wireless/nrf24l01.h b/include/nuttx/wireless/nrf24l01.h index 7cff670dc1..abc6627d84 100644 --- a/include/nuttx/wireless/nrf24l01.h +++ b/include/nuttx/wireless/nrf24l01.h @@ -80,6 +80,8 @@ #define NRF24L01IOC_GETSTATE _WLCIOC(NRF24L01_FIRST+11) /* arg: Pointer to a nrf24l01_state_t value */ #define NRF24L01IOC_GETLASTXMITCOUNT _WLCIOC(NRF24L01_FIRST+12) /* arg: Pointer to an uint32_t value, retransmission count of the last send operation (NRF24L01_XMIT_MAXRT if no ACK received)*/ #define NRF24L01IOC_GETLASTPIPENO _WLCIOC(NRF24L01_FIRST+13) /* arg: Pointer to an uint32_t value, pipe # of the last received packet */ +#define NRF24L01IOC_SETTXPAYLOADNOACK _WLCIOC(NRF24L01_FIRST+14) /* arg: Pointer to an uint32_t, interpreted as bool */ +#define NRF24L01IOC_GETTXPAYLOADNOACK _WLCIOC(NRF24L01_FIRST+15) /* arg: Pointer to an uint32_t, interpreted as bool */ /* Aliased name for these commands */