|
|
@@ -1,113 +1,101 @@
|
|
|
#include "nrf24l01.h"
|
|
|
|
|
|
+/*
|
|
|
#define SPI_CHECK_ENABLED_RESP(SPIx, val) if (!((SPIx)->CR1 & SPI_CR1_SPE)) {return (val);}
|
|
|
#define SPI_WAIT_TX(SPIx) while ((SPIx->SR & SPI_FLAG_TXE) == 0 || (SPIx->SR & SPI_FLAG_BSY))
|
|
|
#define SPI_WAIT_RX(SPIx) while ((SPIx->SR & SPI_FLAG_RXNE) == 0 || (SPIx->SR & SPI_FLAG_BSY))
|
|
|
#define SPI_CHECK_ENABLED(SPIx) if (!((SPIx)->CR1 & SPI_CR1_SPE)) {return;}
|
|
|
#define SPI_CHECK_ENABLED_RESP(SPIx, val) if (!((SPIx)->CR1 & SPI_CR1_SPE)) {return (val);}
|
|
|
+*/
|
|
|
|
|
|
-// ----------------- SPI HELPER FUNCTIONS ---------------------------------//
|
|
|
-static __INLINE uint8_t SPI_Send(SPI_TypeDef* SPIx, uint8_t data) {
|
|
|
- /* Check if SPI is enabled */
|
|
|
- SPI_CHECK_ENABLED_RESP(SPIx, 0);
|
|
|
|
|
|
- /* Wait for previous transmissions to complete if DMA TX enabled for SPI */
|
|
|
- SPI_WAIT_TX(SPIx);
|
|
|
-
|
|
|
- /* Fill output buffer with data */
|
|
|
- *(__IO uint8_t *)&SPIx->DR = data;
|
|
|
-
|
|
|
- /* Wait for transmission to complete */
|
|
|
- SPI_WAIT_RX(SPIx);
|
|
|
+Nrf24L01::Nrf24L01(uint8_t channel, NrfManager *nrf_manager, GPIO_TypeDef *port_cs, uint16_t pin_cs, GPIO_TypeDef *port_ce, uint16_t pin_ce){
|
|
|
+ _nrfManager = nrf_manager;
|
|
|
+ _cs_port = port_cs;
|
|
|
+ _cs_pin = pin_cs;
|
|
|
+ _ce_port = port_ce;
|
|
|
+ _ce_pin = pin_ce;
|
|
|
+ _channel = channel;
|
|
|
+ _payload_size = 32;
|
|
|
|
|
|
- /* Return data from buffer */
|
|
|
- return SPIx->DR;
|
|
|
+ init();
|
|
|
}
|
|
|
|
|
|
-void SPI_ReadMulti(SPI_TypeDef* SPIx, uint8_t* dataIn, uint8_t dummy, uint32_t count) {
|
|
|
- /* Check if SPI is enabled */
|
|
|
- SPI_CHECK_ENABLED(SPIx);
|
|
|
-
|
|
|
- while (count--) {
|
|
|
- /* Wait busy */
|
|
|
- SPI_WAIT_TX(SPIx);
|
|
|
-
|
|
|
- /* Fill output buffer with data */
|
|
|
- *(__IO uint8_t *)&SPIx->DR = dummy;
|
|
|
+uint8_t Nrf24L01::init() {
|
|
|
+ //TM_GPIO_Init(NRF24L01_CSN_PORT, NRF24L01_CSN_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
|
|
|
+ //TM_GPIO_Init(NRF24L01_CE_PORT, NRF24L01_CE_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
|
|
|
|
|
|
- /* Wait for SPI to end everything */
|
|
|
- SPI_WAIT_RX(SPIx);
|
|
|
+ // CSN high = disable SPI
|
|
|
+ PIN_HIGH(_cs_port, _cs_pin);
|
|
|
+ // CE low = disable TX/RX
|
|
|
+ PIN_LOW(_ce_port, _ce_pin);
|
|
|
|
|
|
- /* Save data to buffer */
|
|
|
- *dataIn++ = *(__IO uint8_t *)&SPIx->DR;
|
|
|
+ /* Max payload is 32bytes */
|
|
|
+ if (_payload_size > 32) {
|
|
|
+ _payload_size = 32;
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-void SPI_WriteMulti(SPI_TypeDef* SPIx, uint8_t* dataOut, uint32_t count) {
|
|
|
- /* Check if SPI is enabled */
|
|
|
- SPI_CHECK_ENABLED(SPIx);
|
|
|
+ /* Fill structure */
|
|
|
+ nrf_config.Channel = !_channel; /* Set channel to some different value for TM_NRF24L01_SetChannel() function */
|
|
|
+ nrf_config.PayloadSize = _payload_size;
|
|
|
+ nrf_config.OutPwr = TM_NRF24L01_OutputPower_0dBm;
|
|
|
+ nrf_config.DataRate = TM_NRF24L01_DataRate_2M;
|
|
|
|
|
|
- while (count--) {
|
|
|
- /* Wait busy */
|
|
|
- SPI_WAIT_TX(SPIx);
|
|
|
+ /* Reset nRF24L01+ to power on registers values */
|
|
|
+ softwareReset();
|
|
|
|
|
|
- /* Fill output buffer with data */
|
|
|
- *(__IO uint8_t *)&SPIx->DR = *dataOut++;
|
|
|
+ /* Channel select */
|
|
|
+ SetChannel(_channel);
|
|
|
|
|
|
- /* Wait for SPI to end everything */
|
|
|
- SPI_WAIT_RX(SPIx);
|
|
|
+ /* Set pipeline to max possible 32 bytes */
|
|
|
+ writeRegister(NRF24L01_REG_RX_PW_P0, nrf_config.PayloadSize); // Auto-ACK pipe
|
|
|
+ writeRegister(NRF24L01_REG_RX_PW_P1, nrf_config.PayloadSize); // Data payload pipe
|
|
|
+ writeRegister(NRF24L01_REG_RX_PW_P2, nrf_config.PayloadSize);
|
|
|
+ writeRegister(NRF24L01_REG_RX_PW_P3, nrf_config.PayloadSize);
|
|
|
+ writeRegister(NRF24L01_REG_RX_PW_P4, nrf_config.PayloadSize);
|
|
|
+ writeRegister(NRF24L01_REG_RX_PW_P5, nrf_config.PayloadSize);
|
|
|
|
|
|
- /* Read data register */
|
|
|
- (void)*(__IO uint16_t *)&SPIx->DR;
|
|
|
- }
|
|
|
-}
|
|
|
+ /* Set RF settings (2mbps, output power) */
|
|
|
+ SetRF(nrf_config.DataRate, nrf_config.OutPwr);
|
|
|
|
|
|
+ /* Config register */
|
|
|
+ writeRegister(NRF24L01_REG_CONFIG, NRF24L01_CONFIG);
|
|
|
|
|
|
-void SPI_SendMulti(SPI_TypeDef* SPIx, uint8_t* dataOut, uint8_t* dataIn, uint32_t count) {
|
|
|
- /* Check if SPI is enabled */
|
|
|
- SPI_CHECK_ENABLED(SPIx);
|
|
|
+ /* Enable auto-acknowledgment for all pipes */
|
|
|
+ writeRegister(NRF24L01_REG_EN_AA, 0x3F);
|
|
|
|
|
|
- while (count--) {
|
|
|
- /* Wait busy */
|
|
|
- SPI_WAIT_TX(SPIx);
|
|
|
+ /* Enable RX addresses */
|
|
|
+ writeRegister(NRF24L01_REG_EN_RXADDR, 0x3F);
|
|
|
|
|
|
- /* Fill output buffer with data */
|
|
|
- *(__IO uint8_t *)&SPIx->DR = *dataOut++;
|
|
|
+ /* Auto retransmit delay: 1000 (4x250) us and Up to 15 retransmit trials */
|
|
|
+ writeRegister(NRF24L01_REG_SETUP_RETR, 0x4F);
|
|
|
|
|
|
- /* Wait for SPI to end everything */
|
|
|
- SPI_WAIT_RX(SPIx);
|
|
|
+ /* Dynamic length configurations: No dynamic length */
|
|
|
+ writeRegister(NRF24L01_REG_DYNPD, (0 << NRF24L01_DPL_P0) | (0 << NRF24L01_DPL_P1) | (0 << NRF24L01_DPL_P2) | (0 << NRF24L01_DPL_P3) | (0 << NRF24L01_DPL_P4) | (0 << NRF24L01_DPL_P5));
|
|
|
|
|
|
- /* Read data register */
|
|
|
- *dataIn++ = *(__IO uint8_t *)&SPIx->DR;
|
|
|
- }
|
|
|
-}
|
|
|
-//----------------------------- NRF240L01 ----------------------------------------------//
|
|
|
+ /* Clear FIFOs */
|
|
|
+ NRF24L01_FLUSH_TX(_nrfManager, _cs_port, _cs_pin);
|
|
|
+ NRF24L01_FLUSH_RX(_nrfManager, _cs_port, _cs_pin);
|
|
|
|
|
|
-Nrf24L01::Nrf24L01(uint8_t channel, SPI_HandleTypeDef *spi, GPIO_TypeDef *port_cs, uint16_t pin_cs, GPIO_TypeDef *port_ce, uint16_t pin_ce){
|
|
|
- _spi = spi;
|
|
|
- _cs_port = port_cs;
|
|
|
- _cs_pin = pin_cs;
|
|
|
- _ce_port = port_ce;
|
|
|
- _ce_pin = pin_ce;
|
|
|
- _channel = channel;
|
|
|
- _payload_size = 32;
|
|
|
+ /* Clear interrupts */
|
|
|
+ Clear_Interrupts();
|
|
|
|
|
|
- init();
|
|
|
-}
|
|
|
+ /* Go to RX mode */
|
|
|
+ PowerUpRx();
|
|
|
|
|
|
+ /* Return OK */
|
|
|
+ return 1;
|
|
|
+}
|
|
|
|
|
|
|
|
|
void Nrf24L01::writeBit(uint8_t reg, uint8_t bit, uint8_t value) {
|
|
|
uint8_t tmp;
|
|
|
- /* Read register */
|
|
|
tmp = readRegister(reg);
|
|
|
- /* Make operation */
|
|
|
if (value) {
|
|
|
tmp |= 1 << bit;
|
|
|
} else {
|
|
|
tmp &= ~(1 << bit);
|
|
|
}
|
|
|
- /* Write back */
|
|
|
writeRegister(reg, tmp);
|
|
|
}
|
|
|
|
|
|
@@ -122,40 +110,39 @@ uint8_t Nrf24L01::readBit(uint8_t reg, uint8_t bit) {
|
|
|
|
|
|
uint8_t Nrf24L01::readRegister(uint8_t reg) {
|
|
|
uint8_t value;
|
|
|
-// NRF24L01_CSN_LOW;
|
|
|
+
|
|
|
PIN_LOW(_cs_port, _cs_pin);
|
|
|
- SPI_Send(_spi->Instance, NRF24L01_READ_REGISTER_MASK(reg));
|
|
|
- value = SPI_Send(_spi->Instance, NRF24L01_NOP_MASK);
|
|
|
- //NRF24L01_CSN_HIGH;
|
|
|
+
|
|
|
+ _nrfManager->SPI_Send(NRF24L01_READ_REGISTER_MASK(reg));
|
|
|
+ value = _nrfManager->SPI_Send(NRF24L01_NOP_MASK);
|
|
|
+
|
|
|
PIN_HIGH(_cs_port, _cs_pin);
|
|
|
|
|
|
return value;
|
|
|
}
|
|
|
|
|
|
void Nrf24L01::readRegisterMulti(uint8_t reg, uint8_t* data, uint8_t count) {
|
|
|
-// NRF24L01_CSN_LOW;
|
|
|
PIN_LOW(_cs_port, _cs_pin);
|
|
|
- SPI_Send(_spi->Instance, NRF24L01_READ_REGISTER_MASK(reg));
|
|
|
- SPI_ReadMulti(_spi->Instance, data, NRF24L01_NOP_MASK, count);
|
|
|
-// NRF24L01_CSN_HIGH;
|
|
|
+
|
|
|
+ _nrfManager->SPI_Send(NRF24L01_READ_REGISTER_MASK(reg));
|
|
|
+ _nrfManager->SPI_ReadMulti(data, NRF24L01_NOP_MASK, count);
|
|
|
+
|
|
|
PIN_HIGH(_cs_port, _cs_pin);
|
|
|
}
|
|
|
|
|
|
void Nrf24L01::writeRegister(uint8_t reg, uint8_t value) {
|
|
|
-// NRF24L01_CSN_LOW;
|
|
|
PIN_LOW(_cs_port, _cs_pin);
|
|
|
- SPI_Send(_spi->Instance, NRF24L01_WRITE_REGISTER_MASK(reg));
|
|
|
- SPI_Send(_spi->Instance, value);
|
|
|
-// NRF24L01_CSN_HIGH;
|
|
|
+ _nrfManager->SPI_Send(NRF24L01_WRITE_REGISTER_MASK(reg));
|
|
|
+ _nrfManager->SPI_Send(value);
|
|
|
PIN_HIGH(_cs_port, _cs_pin);
|
|
|
}
|
|
|
|
|
|
void Nrf24L01::writeRegisterMulti(uint8_t reg, uint8_t *data, uint8_t count) {
|
|
|
-// NRF24L01_CSN_LOW;
|
|
|
PIN_LOW(_cs_port, _cs_pin);
|
|
|
- SPI_Send(_spi->Instance, NRF24L01_WRITE_REGISTER_MASK(reg));
|
|
|
- SPI_WriteMulti(_spi->Instance, data, count);
|
|
|
-// NRF24L01_CSN_HIGH;
|
|
|
+
|
|
|
+ _nrfManager->SPI_Send(NRF24L01_WRITE_REGISTER_MASK(reg));
|
|
|
+ _nrfManager->SPI_WriteMulti(data, count);
|
|
|
+
|
|
|
PIN_HIGH(_cs_port, _cs_pin);
|
|
|
}
|
|
|
|
|
|
@@ -221,84 +208,11 @@ uint8_t Nrf24L01::rxFifoEmpty(void) {
|
|
|
|
|
|
// ----------------------- PUBLIC METHODS -------------------------------------
|
|
|
|
|
|
-uint8_t Nrf24L01::init() {
|
|
|
- /* Initialize CE and CSN pins */
|
|
|
- /* CNS pin */
|
|
|
- //TM_GPIO_Init(NRF24L01_CSN_PORT, NRF24L01_CSN_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
|
|
|
-
|
|
|
- /* CE pin */
|
|
|
- //TM_GPIO_Init(NRF24L01_CE_PORT, NRF24L01_CE_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
|
|
|
-
|
|
|
- /* CSN high = disable SPI */
|
|
|
- PIN_HIGH(_cs_port, _cs_pin);
|
|
|
-
|
|
|
- /* CE low = disable TX/RX */
|
|
|
- PIN_LOW(_ce_port, _ce_pin);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* Max payload is 32bytes */
|
|
|
- if (_payload_size > 32) {
|
|
|
- _payload_size = 32;
|
|
|
- }
|
|
|
-
|
|
|
- /* Fill structure */
|
|
|
- nrf_config.Channel = !_channel; /* Set channel to some different value for TM_NRF24L01_SetChannel() function */
|
|
|
- nrf_config.PayloadSize = _payload_size;
|
|
|
- nrf_config.OutPwr = TM_NRF24L01_OutputPower_0dBm;
|
|
|
- nrf_config.DataRate = TM_NRF24L01_DataRate_2M;
|
|
|
-
|
|
|
- /* Reset nRF24L01+ to power on registers values */
|
|
|
- softwareReset();
|
|
|
-
|
|
|
- /* Channel select */
|
|
|
- SetChannel(_channel);
|
|
|
-
|
|
|
- /* Set pipeline to max possible 32 bytes */
|
|
|
- writeRegister(NRF24L01_REG_RX_PW_P0, nrf_config.PayloadSize); // Auto-ACK pipe
|
|
|
- writeRegister(NRF24L01_REG_RX_PW_P1, nrf_config.PayloadSize); // Data payload pipe
|
|
|
- writeRegister(NRF24L01_REG_RX_PW_P2, nrf_config.PayloadSize);
|
|
|
- writeRegister(NRF24L01_REG_RX_PW_P3, nrf_config.PayloadSize);
|
|
|
- writeRegister(NRF24L01_REG_RX_PW_P4, nrf_config.PayloadSize);
|
|
|
- writeRegister(NRF24L01_REG_RX_PW_P5, nrf_config.PayloadSize);
|
|
|
-
|
|
|
- /* Set RF settings (2mbps, output power) */
|
|
|
- SetRF(nrf_config.DataRate, nrf_config.OutPwr);
|
|
|
-
|
|
|
- /* Config register */
|
|
|
- writeRegister(NRF24L01_REG_CONFIG, NRF24L01_CONFIG);
|
|
|
-
|
|
|
- /* Enable auto-acknowledgment for all pipes */
|
|
|
- writeRegister(NRF24L01_REG_EN_AA, 0x3F);
|
|
|
-
|
|
|
- /* Enable RX addresses */
|
|
|
- writeRegister(NRF24L01_REG_EN_RXADDR, 0x3F);
|
|
|
-
|
|
|
- /* Auto retransmit delay: 1000 (4x250) us and Up to 15 retransmit trials */
|
|
|
- writeRegister(NRF24L01_REG_SETUP_RETR, 0x4F);
|
|
|
-
|
|
|
- /* Dynamic length configurations: No dynamic length */
|
|
|
- writeRegister(NRF24L01_REG_DYNPD, (0 << NRF24L01_DPL_P0) | (0 << NRF24L01_DPL_P1) | (0 << NRF24L01_DPL_P2) | (0 << NRF24L01_DPL_P3) | (0 << NRF24L01_DPL_P4) | (0 << NRF24L01_DPL_P5));
|
|
|
-
|
|
|
- /* Clear FIFOs */
|
|
|
- NRF24L01_FLUSH_TX(_spi->Instance, _cs_port, _cs_pin);
|
|
|
- NRF24L01_FLUSH_RX(_spi->Instance, _cs_port, _cs_pin);
|
|
|
-
|
|
|
- /* Clear interrupts */
|
|
|
- Clear_Interrupts();
|
|
|
-
|
|
|
- /* Go to RX mode */
|
|
|
- PowerUpRx();
|
|
|
-
|
|
|
- /* Return OK */
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
void Nrf24L01::SetMyAddress(uint8_t *adr) {
|
|
|
-// NRF24L01_CE_LOW;
|
|
|
PIN_LOW(_ce_port, _ce_pin);
|
|
|
+
|
|
|
writeRegisterMulti(NRF24L01_REG_RX_ADDR_P1, adr, 5);
|
|
|
-// NRF24L01_CE_HIGH;
|
|
|
+
|
|
|
PIN_HIGH(_ce_port, _ce_pin);
|
|
|
}
|
|
|
|
|
|
@@ -310,13 +224,11 @@ void Nrf24L01::SetTxAddress(uint8_t *adr) {
|
|
|
|
|
|
uint8_t Nrf24L01::GetStatus(void) {
|
|
|
uint8_t status;
|
|
|
-
|
|
|
-// NRF24L01_CSN_LOW;
|
|
|
PIN_LOW(_cs_port, _cs_pin);
|
|
|
+
|
|
|
/* First received byte is always status register */
|
|
|
- status = SPI_Send(_spi->Instance, NRF24L01_NOP_MASK);
|
|
|
- /* Pull up chip select */
|
|
|
-// NRF24L01_CSN_HIGH;
|
|
|
+ status = _nrfManager->SPI_Send(NRF24L01_NOP_MASK);
|
|
|
+
|
|
|
PIN_LOW(_cs_port, _cs_pin);
|
|
|
|
|
|
return status;
|
|
|
@@ -390,22 +302,17 @@ void Nrf24L01::Clear_Interrupts(void) {
|
|
|
|
|
|
void Nrf24L01::PowerUpRx(void) {
|
|
|
/* Disable RX/TX mode */
|
|
|
-// NRF24L01_CE_LOW;
|
|
|
PIN_LOW(_ce_port, _ce_pin);
|
|
|
- /* Clear RX buffer */
|
|
|
- NRF24L01_FLUSH_RX(_spi->Instance, _cs_port, _cs_pin);
|
|
|
- /* Clear interrupts */
|
|
|
+ NRF24L01_FLUSH_RX(_nrfManager, _cs_port, _cs_pin);
|
|
|
Clear_Interrupts();
|
|
|
/* Setup RX mode */
|
|
|
writeRegister(NRF24L01_REG_CONFIG, NRF24L01_CONFIG | 1 << NRF24L01_PWR_UP | 1 << NRF24L01_PRIM_RX);
|
|
|
/* Start listening */
|
|
|
-// NRF24L01_CE_HIGH;
|
|
|
PIN_HIGH(_ce_port, _ce_pin);
|
|
|
}
|
|
|
|
|
|
|
|
|
void Nrf24L01::PowerDown(void) {
|
|
|
-// NRF24L01_CE_LOW;
|
|
|
PIN_LOW(_ce_port, _ce_pin);
|
|
|
writeBit(NRF24L01_REG_CONFIG, NRF24L01_PWR_UP, 0);
|
|
|
}
|
|
|
@@ -416,41 +323,33 @@ void Nrf24L01::Transmit(uint8_t *data) {
|
|
|
uint8_t count = nrf_config.PayloadSize;
|
|
|
|
|
|
/* Chip enable put to low, disable it */
|
|
|
-// NRF24L01_CE_LOW;
|
|
|
PIN_LOW(_ce_port, _ce_pin);
|
|
|
|
|
|
/* Go to power up tx mode */
|
|
|
PowerUpTx();
|
|
|
|
|
|
/* Clear TX FIFO from NRF24L01+ */
|
|
|
- NRF24L01_FLUSH_TX(_spi->Instance, _cs_port, _cs_pin);
|
|
|
+ NRF24L01_FLUSH_TX(_nrfManager, _cs_port, _cs_pin);
|
|
|
|
|
|
/* Send payload to nRF24L01+ */
|
|
|
-// NRF24L01_CSN_LOW;
|
|
|
PIN_LOW(_cs_port, _cs_pin);
|
|
|
/* Send write payload command */
|
|
|
- SPI_Send(_spi->Instance, NRF24L01_W_TX_PAYLOAD_MASK);
|
|
|
+ _nrfManager->SPI_Send(NRF24L01_W_TX_PAYLOAD_MASK);
|
|
|
/* Fill payload with data*/
|
|
|
- SPI_WriteMulti(_spi->Instance, data, count);
|
|
|
- /* Disable SPI */
|
|
|
-// NRF24L01_CSN_HIGH;
|
|
|
+ _nrfManager->SPI_WriteMulti(data, count);
|
|
|
+
|
|
|
PIN_HIGH(_cs_port, _cs_pin);
|
|
|
|
|
|
- /* Send data! */
|
|
|
-// NRF24L01_CE_HIGH;
|
|
|
PIN_HIGH(_ce_port, _ce_pin);
|
|
|
}
|
|
|
|
|
|
void Nrf24L01::GetData(uint8_t* data) {
|
|
|
- /* Pull down chip select */
|
|
|
-// NRF24L01_CSN_LOW;
|
|
|
PIN_LOW(_cs_port, _cs_pin);
|
|
|
/* Send read payload command*/
|
|
|
- SPI_Send(_spi->Instance, NRF24L01_R_RX_PAYLOAD_MASK);
|
|
|
+ _nrfManager->SPI_Send(NRF24L01_R_RX_PAYLOAD_MASK);
|
|
|
/* Read payload */
|
|
|
- SPI_SendMulti(_spi->Instance, data, data, nrf_config.PayloadSize);
|
|
|
+ _nrfManager->SPI_SendMulti(data, data, nrf_config.PayloadSize);
|
|
|
/* Pull up chip select */
|
|
|
-// NRF24L01_CSN_HIGH;
|
|
|
PIN_HIGH(_cs_port, _cs_pin);
|
|
|
|
|
|
/* Reset status register, clear RX_DR interrupt flag */
|