Browse Source

first OOP version

Juraj Ďuďák 2 years ago
parent
commit
d507620c09
7 changed files with 665 additions and 95 deletions
  1. 22 0
      LICENSE
  2. BIN
      nRF24L01Pluss_v1_0.pdf
  3. 0 1
      nrf24l01.cpp
  4. 1 0
      readme.md
  5. 468 0
      src/nrf24l01.cpp
  6. 149 0
      src/nrf24l01.h
  7. 25 94
      src/nrf24l01_defines.h

+ 22 - 0
LICENSE

@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (c) 2021 Tilen Majerle
+Copyright (c) 2023 Juraj Ďuďak (OOP modifications)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

BIN
nRF24L01Pluss_v1_0.pdf


+ 0 - 1
nrf24l01.cpp

@@ -1 +0,0 @@
-#include "nrf24l01.h"

+ 1 - 0
readme.md

@@ -0,0 +1 @@
+# NRF24L01 Driver for STM32

+ 468 - 0
src/nrf24l01.cpp

@@ -0,0 +1,468 @@
+#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);}
+
+
+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);
+
+    /* Return data from buffer */
+    return SPIx->DR;
+}
+
+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;
+
+		/* Wait for SPI to end everything */
+		SPI_WAIT_RX(SPIx);
+
+		/* Save data to buffer */
+		*dataIn++ = *(__IO uint8_t *)&SPIx->DR;
+	}
+}
+
+void SPI_WriteMulti(SPI_TypeDef* SPIx, uint8_t* dataOut, 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 = *dataOut++;
+
+		/* Wait for SPI to end everything */
+		SPI_WAIT_RX(SPIx);
+
+		/* Read data register */
+		(void)*(__IO uint16_t *)&SPIx->DR;
+	}
+}
+
+
+void SPI_SendMulti(SPI_TypeDef* SPIx, uint8_t* dataOut, uint8_t* dataIn, 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 = *dataOut++;
+
+		/* Wait for SPI to end everything */
+		SPI_WAIT_RX(SPIx);
+
+		/* Read data register */
+		*dataIn++ = *(__IO uint8_t *)&SPIx->DR;
+	}
+}
+//--------------------------------------------------------------------------------
+
+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;
+
+	init();
+}
+
+
+
+void Nrf24L01::TM_NRF24L01_WriteBit(uint8_t reg, uint8_t bit, uint8_t value) {
+	uint8_t tmp;
+	/* Read register */
+	tmp = TM_NRF24L01_ReadRegister(reg);
+	/* Make operation */
+	if (value) {
+		tmp |= 1 << bit;
+	} else {
+		tmp &= ~(1 << bit);
+	}
+	/* Write back */
+	TM_NRF24L01_WriteRegister(reg, tmp);
+}
+
+uint8_t Nrf24L01::TM_NRF24L01_ReadBit(uint8_t reg, uint8_t bit) {
+	uint8_t tmp;
+	tmp = TM_NRF24L01_ReadRegister(reg);
+	if (!NRF24L01_CHECK_BIT(tmp, bit)) {
+		return 0;
+	}
+	return 1;
+}
+
+uint8_t Nrf24L01::TM_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;
+	PIN_HIGH(_cs_port, _cs_pin);
+
+	return value;
+}
+
+void Nrf24L01::TM_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;
+	PIN_HIGH(_cs_port, _cs_pin);
+}
+
+void Nrf24L01::TM_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;
+	PIN_HIGH(_cs_port, _cs_pin);
+}
+
+void Nrf24L01::TM_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;
+	PIN_HIGH(_cs_port, _cs_pin);
+}
+
+
+void Nrf24L01::softwareReset(void) {
+	uint8_t data[5];
+
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_CONFIG, 		NRF24L01_REG_DEFAULT_VAL_CONFIG);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_EN_AA,		NRF24L01_REG_DEFAULT_VAL_EN_AA);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_EN_RXADDR, 	NRF24L01_REG_DEFAULT_VAL_EN_RXADDR);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_SETUP_AW, 	NRF24L01_REG_DEFAULT_VAL_SETUP_AW);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_SETUP_RETR, 	NRF24L01_REG_DEFAULT_VAL_SETUP_RETR);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RF_CH, 		NRF24L01_REG_DEFAULT_VAL_RF_CH);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RF_SETUP, 	NRF24L01_REG_DEFAULT_VAL_RF_SETUP);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_STATUS, 		NRF24L01_REG_DEFAULT_VAL_STATUS);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_OBSERVE_TX, 	NRF24L01_REG_DEFAULT_VAL_OBSERVE_TX);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RPD, 		NRF24L01_REG_DEFAULT_VAL_RPD);
+
+	//P0
+	data[0] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P0_0;
+	data[1] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P0_1;
+	data[2] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P0_2;
+	data[3] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P0_3;
+	data[4] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P0_4;
+	TM_NRF24L01_WriteRegisterMulti(NRF24L01_REG_RX_ADDR_P0, data, 5);
+
+	//P1
+	data[0] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P1_0;
+	data[1] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P1_1;
+	data[2] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P1_2;
+	data[3] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P1_3;
+	data[4] = NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P1_4;
+	TM_NRF24L01_WriteRegisterMulti(NRF24L01_REG_RX_ADDR_P1, data, 5);
+
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_ADDR_P2, 	NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P2);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_ADDR_P3, 	NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P3);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_ADDR_P4, 	NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P4);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_ADDR_P5, 	NRF24L01_REG_DEFAULT_VAL_RX_ADDR_P5);
+
+	//TX
+	data[0] = NRF24L01_REG_DEFAULT_VAL_TX_ADDR_0;
+	data[1] = NRF24L01_REG_DEFAULT_VAL_TX_ADDR_1;
+	data[2] = NRF24L01_REG_DEFAULT_VAL_TX_ADDR_2;
+	data[3] = NRF24L01_REG_DEFAULT_VAL_TX_ADDR_3;
+	data[4] = NRF24L01_REG_DEFAULT_VAL_TX_ADDR_4;
+	TM_NRF24L01_WriteRegisterMulti(NRF24L01_REG_TX_ADDR, data, 5);
+
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P0, 	NRF24L01_REG_DEFAULT_VAL_RX_PW_P0);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P1, 	NRF24L01_REG_DEFAULT_VAL_RX_PW_P1);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P2, 	NRF24L01_REG_DEFAULT_VAL_RX_PW_P2);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P3, 	NRF24L01_REG_DEFAULT_VAL_RX_PW_P3);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P4, 	NRF24L01_REG_DEFAULT_VAL_RX_PW_P4);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P5, 	NRF24L01_REG_DEFAULT_VAL_RX_PW_P5);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_FIFO_STATUS, NRF24L01_REG_DEFAULT_VAL_FIFO_STATUS);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_DYNPD, 		NRF24L01_REG_DEFAULT_VAL_DYNPD);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_FEATURE, 	NRF24L01_REG_DEFAULT_VAL_FEATURE);
+}
+
+uint8_t Nrf24L01::RxFifoEmpty(void) {
+	uint8_t reg = TM_NRF24L01_ReadRegister(NRF24L01_REG_FIFO_STATUS);
+	return NRF24L01_CHECK_BIT(reg, NRF24L01_RX_EMPTY);
+}
+
+// ----------------------- 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 */
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P0, nrf_config.PayloadSize); // Auto-ACK pipe
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P1, nrf_config.PayloadSize); // Data payload pipe
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P2, nrf_config.PayloadSize);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P3, nrf_config.PayloadSize);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P4, nrf_config.PayloadSize);
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RX_PW_P5, nrf_config.PayloadSize);
+
+	/* Set RF settings (2mbps, output power) */
+	SetRF(nrf_config.DataRate, nrf_config.OutPwr);
+
+	/* Config register */
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_CONFIG, NRF24L01_CONFIG);
+
+	/* Enable auto-acknowledgment for all pipes */
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_EN_AA, 0x3F);
+
+	/* Enable RX addresses */
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_EN_RXADDR, 0x3F);
+
+	/* Auto retransmit delay: 1000 (4x250) us and Up to 15 retransmit trials */
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_SETUP_RETR, 0x4F);
+
+	/* Dynamic length configurations: No dynamic length */
+	TM_NRF24L01_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);
+	TM_NRF24L01_WriteRegisterMulti(NRF24L01_REG_RX_ADDR_P1, adr, 5);
+//	NRF24L01_CE_HIGH;
+	PIN_HIGH(_ce_port, _ce_pin);
+}
+
+void Nrf24L01::SetTxAddress(uint8_t *adr) {
+	TM_NRF24L01_WriteRegisterMulti(NRF24L01_REG_RX_ADDR_P0, adr, 5);
+	TM_NRF24L01_WriteRegisterMulti(NRF24L01_REG_TX_ADDR, adr, 5);
+}
+
+
+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;
+	PIN_LOW(_cs_port, _cs_pin);
+
+	return status;
+}
+
+Transmit_Status_t Nrf24L01::GetTransmissionStatus(void) {
+	uint8_t status = GetStatus();
+	if (NRF24L01_CHECK_BIT(status, NRF24L01_TX_DS)) {
+		/* Successfully sent */
+		return TM_NRF24L01_Transmit_Status_Ok;
+	} else if (NRF24L01_CHECK_BIT(status, NRF24L01_MAX_RT)) {
+		/* Message lost */
+		return TM_NRF24L01_Transmit_Status_Lost;
+	}
+
+	/* Still sending */
+	return TM_NRF24L01_Transmit_Status_Sending;
+}
+
+
+uint8_t Nrf24L01::GetRetransmissionsCount(void) {
+	/* Low 4 bits */
+	return TM_NRF24L01_ReadRegister(NRF24L01_REG_OBSERVE_TX) & 0x0F;
+}
+
+void Nrf24L01::PowerUpTx(void) {
+	Clear_Interrupts();
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_CONFIG, NRF24L01_CONFIG | (0 << NRF24L01_PRIM_RX) | (1 << NRF24L01_PWR_UP));
+}
+
+void Nrf24L01::SetChannel(uint8_t channel) {
+	if (channel <= 125 && channel != nrf_config.Channel) {
+		/* Store new channel setting */
+		nrf_config.Channel = channel;
+		/* Write channel */
+		TM_NRF24L01_WriteRegister(NRF24L01_REG_RF_CH, channel);
+	}
+}
+
+void Nrf24L01::SetRF(TM_NRF24L01_DataRate_t DataRate, TM_NRF24L01_OutputPower_t OutPwr) {
+	uint8_t tmp = 0;
+	nrf_config.DataRate = DataRate;
+	nrf_config.OutPwr = OutPwr;
+
+	if (DataRate == TM_NRF24L01_DataRate_2M) {
+		tmp |= 1 << NRF24L01_RF_DR_HIGH;
+	} else if (DataRate == TM_NRF24L01_DataRate_250k) {
+		tmp |= 1 << NRF24L01_RF_DR_LOW;
+	}
+	/* If 1Mbps, all bits set to 0 */
+
+	if (OutPwr == TM_NRF24L01_OutputPower_0dBm) {
+		tmp |= 3 << NRF24L01_RF_PWR;
+	} else if (OutPwr == TM_NRF24L01_OutputPower_M6dBm) {
+		tmp |= 2 << NRF24L01_RF_PWR;
+	} else if (OutPwr == TM_NRF24L01_OutputPower_M12dBm) {
+		tmp |= 1 << NRF24L01_RF_PWR;
+	}
+
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_RF_SETUP, tmp);
+}
+
+uint8_t Nrf24L01::Read_Interrupts(TM_NRF24L01_IRQ_t* IRQ) {
+	IRQ->Status = GetStatus();
+	return IRQ->Status;
+}
+
+void Nrf24L01::Clear_Interrupts(void) {
+	TM_NRF24L01_WriteRegister(0x07, 0x70);
+}
+
+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 */
+	Clear_Interrupts();
+	/* Setup RX mode */
+	TM_NRF24L01_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);
+	TM_NRF24L01_WriteBit(NRF24L01_REG_CONFIG, NRF24L01_PWR_UP, 0);
+}
+
+
+
+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);
+
+	/* 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);
+	/* Fill payload with data*/
+	SPI_WriteMulti(_spi->Instance, data, count);
+	/* Disable SPI */
+//	NRF24L01_CSN_HIGH;
+	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);
+	/* Read payload */
+	SPI_SendMulti(_spi->Instance, 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 */
+	TM_NRF24L01_WriteRegister(NRF24L01_REG_STATUS, (1 << NRF24L01_RX_DR));
+}
+
+uint8_t Nrf24L01::DataReady(void) {
+	uint8_t status = GetStatus();
+
+	if (NRF24L01_CHECK_BIT(status, NRF24L01_RX_DR)) {
+		return 1;
+	}
+	return !RxFifoEmpty();
+}
+

+ 149 - 0
src/nrf24l01.h

@@ -0,0 +1,149 @@
+
+
+/**
+ * @author  Tilen MAJERLE
+ * @email   tilen@majerle.eu
+ * @website http://stm32f4-discovery.net
+ * @link    http://stm32f4-discovery.net/2015/09/hal-library-25-nrf24l01-for-stm32fxxx/
+ * @version v1.0
+ * @ide     Keil uVision
+ * @license MIT
+ * @brief   Library template 
+ *	
+\verbatim
+   ----------------------------------------------------------------------
+    Copyright (c) 2016 Tilen MAJERLE
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software, 
+    and to permit persons to whom the Software is furnished to do so, 
+    subject to the following conditions:
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+    AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+    OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------
+\endverbatim
+ */
+
+
+/**
+ * @defgroup TM_NRF24L01P
+ * @brief    nRF24L01+ library for STM32xxx devices - http://stm32f4-discovery.net/2015/09/hal-library-25-nrf24l01-for-stm32fxxx/
+ * @{
+ *
+ * This library allows you to work with nRF24L01+ modules.
+ * 
+ * You can send and receive data from nRF24L01+ modules.
+ * 
+ * \par Default pinout
+ * 	
+\verbatim
+NRF24L01+	STM32Fxxx	DESCRIPTION
+GND			GND			Ground
+VCC			3.3V		3.3V
+CE			PD8			RF activated pin
+CSN			PD7			Chip select pin for SPI
+SCK			PC10		SCK pin for SPI
+MOSI		PC12		MOSI pin for SPI
+MISO		PC11		MISO pin for SPI
+IRQ			Not used	Interrupt pin. Goes low when active. Pin functionality is active, but not used in library
+\endverbatim 
+ *
+ * IRQ pin is not used in this library, but its functionality is enabled by this software.
+ *
+ * You can still set any pin on Fxxx to be an external interrupt and handle interrupts from nRF24L01+ module.
+ *
+ * The easiest way to that is to use @ref TM_EXTI library and attach interrupt functionality to this pin
+ * 
+ * \par Custom pinout
+ *
+ * Add lines below in your defines.h file if you want to change default pinout:
+ */
+
+#ifndef _NRF_24L01_H_
+#define _NRF_24L01_H_
+
+#if defined(STM32F401xC) || defined(STM32F401xE)
+#include "stm32f4xx_hal.h"
+#endif
+
+#if defined (STM32L432xx)
+#include "stm32l4xx_hal.h"
+#endif
+
+#include "nrf24l01_defines.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define PIN_LOW(PORT,PIN)  {PORT->BRR = (uint32_t)PIN;}
+#define PIN_HIGH(PORT,PIN)  {PORT->BSRR = (uint32_t)PIN;}
+
+
+class Nrf24L01 {
+protected:
+	NRF24L01_Conig_t nrf_config;
+	SPI_HandleTypeDef *_spi;
+
+    GPIO_TypeDef *_cs_port;
+    GPIO_TypeDef *_ce_port;
+    uint16_t _ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
+    uint16_t _cs_pin; /**< SPI Chip select */
+    uint32_t spi_speed; /**< SPI Bus Speed */
+    uint8_t status; /** The status byte returned from every SPI transaction */
+    uint8_t _payload_size; /**< Fixed size of payloads */
+    uint8_t _channel;
+
+
+public:
+
+    Nrf24L01(uint8_t channel, SPI_HandleTypeDef *spi, GPIO_TypeDef *port_cs, uint16_t pin_cs, GPIO_TypeDef *port_ce, uint16_t pin_ce);
+    void SetMyAddress(uint8_t* adr);
+    void SetTxAddress(uint8_t* adr);
+    uint8_t GetRetransmissionsCount(void);
+    void PowerUpTx(void);
+    void PowerUpRx(void);
+    void PowerDown(void);
+    Transmit_Status_t GetTransmissionStatus(void);
+    void Transmit(uint8_t *data);
+    uint8_t DataReady(void);
+    void GetData(uint8_t *data);
+    void SetChannel(uint8_t channel);
+    void SetRF(TM_NRF24L01_DataRate_t DataRate, TM_NRF24L01_OutputPower_t OutPwr);
+    uint8_t GetStatus(void);
+    uint8_t Read_Interrupts(TM_NRF24L01_IRQ_t* IRQ);
+    void Clear_Interrupts(void);
+
+private:
+    uint8_t init();
+    void initPins(void);
+    void softwareReset(void);
+
+    void TM_NRF24L01_WriteRegister(uint8_t reg, uint8_t value);
+    void TM_NRF24L01_WriteBit(uint8_t reg, uint8_t bit, uint8_t value);
+    uint8_t TM_NRF24L01_ReadBit(uint8_t reg, uint8_t bit);
+    uint8_t TM_NRF24L01_ReadRegister(uint8_t reg);
+    void TM_NRF24L01_ReadRegisterMulti(uint8_t reg, uint8_t* data, uint8_t count);
+    void TM_NRF24L01_WriteRegisterMulti(uint8_t reg, uint8_t *data, uint8_t count);
+    uint8_t RxFifoEmpty(void);
+};
+
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* _NRF_24L01_H_ */

+ 25 - 94
nrf24l01.h → src/nrf24l01_defines.h

@@ -1,76 +1,8 @@
+#ifndef _NRF_24L01_DEINES_H_
+#define _NRF_24L01_DEINES_H_
 
 
-/**
- * @author  Tilen MAJERLE
- * @email   tilen@majerle.eu
- * @website http://stm32f4-discovery.net
- * @link    http://stm32f4-discovery.net/2015/09/hal-library-25-nrf24l01-for-stm32fxxx/
- * @version v1.0
- * @ide     Keil uVision
- * @license MIT
- * @brief   Library template 
- *	
-\verbatim
-   ----------------------------------------------------------------------
-    Copyright (c) 2016 Tilen MAJERLE
-    Permission is hereby granted, free of charge, to any person
-    obtaining a copy of this software and associated documentation
-    files (the "Software"), to deal in the Software without restriction,
-    including without limitation the rights to use, copy, modify, merge,
-    publish, distribute, sublicense, and/or sell copies of the Software, 
-    and to permit persons to whom the Software is furnished to do so, 
-    subject to the following conditions:
-    The above copyright notice and this permission notice shall be
-    included in all copies or substantial portions of the Software.
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-    AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
-    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-    OTHER DEALINGS IN THE SOFTWARE.
-   ----------------------------------------------------------------------
-\endverbatim
- */
-
-
-/**
- * @defgroup TM_NRF24L01P
- * @brief    nRF24L01+ library for STM32xxx devices - http://stm32f4-discovery.net/2015/09/hal-library-25-nrf24l01-for-stm32fxxx/
- * @{
- *
- * This library allows you to work with nRF24L01+ modules.
- * 
- * You can send and receive data from nRF24L01+ modules.
- * 
- * \par Default pinout
- * 	
-\verbatim
-NRF24L01+	STM32Fxxx	DESCRIPTION
-GND			GND			Ground
-VCC			3.3V		3.3V
-CE			PD8			RF activated pin
-CSN			PD7			Chip select pin for SPI
-SCK			PC10		SCK pin for SPI
-MOSI		PC12		MOSI pin for SPI
-MISO		PC11		MISO pin for SPI
-IRQ			Not used	Interrupt pin. Goes low when active. Pin functionality is active, but not used in library
-\endverbatim 
- *
- * IRQ pin is not used in this library, but its functionality is enabled by this software.
- *
- * You can still set any pin on Fxxx to be an external interrupt and handle interrupts from nRF24L01+ module.
- *
- * The easiest way to that is to use @ref TM_EXTI library and attach interrupt functionality to this pin
- * 
- * \par Custom pinout
- *
- * Add lines below in your defines.h file if you want to change default pinout:
- */
-
-#ifndef _NRF_24L01_H_
-#define _NRF_24L01_H_
+#define NRF24L01_CHECK_BIT(reg, bit)       (reg & (1 << bit))
 
 
 /* Interrupt masks */
@@ -242,32 +174,16 @@ IRQ			Not used	Interrupt pin. Goes low when active. Pin functionality is active,
 #define NRF24L01_NOP_MASK					0xFF
 
 /* Flush FIFOs */
-#define NRF24L01_FLUSH_TX					do { NRF24L01_CSN_LOW; TM_SPI_Send(NRF24L01_SPI, NRF24L01_FLUSH_TX_MASK); NRF24L01_CSN_HIGH; } while (0)
-#define NRF24L01_FLUSH_RX					do { NRF24L01_CSN_LOW; TM_SPI_Send(NRF24L01_SPI, NRF24L01_FLUSH_RX_MASK); NRF24L01_CSN_HIGH; } while (0)
+#define NRF24L01_FLUSH_TX(SPI,PORT_CS,PIN_CS)					do { PIN_LOW(PORT_CS,PIN_CS); SPI_Send(SPI, NRF24L01_FLUSH_TX_MASK); PIN_HIGH(PORT_CS,PIN_CS); } while (0)
+#define NRF24L01_FLUSH_RX(SPI,PORT_CS,PIN_CS)					do { PIN_LOW(PORT_CS,PIN_CS); SPI_Send(SPI, NRF24L01_FLUSH_RX_MASK); PIN_HIGH(PORT_CS,PIN_CS); } while (0)
 
 #define NRF24L01_TRANSMISSON_OK 			0
 #define NRF24L01_MESSAGE_LOST   			1
 
 
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-
-#define NRF24L01_CHECK_BIT(reg, bit)       (reg & (1 << bit))
-
-typedef struct {
-	uint8_t PayloadSize;				//Payload size
-	uint8_t Channel;					//Channel selected
-	TM_NRF24L01_OutputPower_t OutPwr;	//Output power
-	TM_NRF24L01_DataRate_t DataRate;	//Data rate
-} TM_NRF24L01_t;
-
-
-
 
 /**
- * @brief  Interrupt structure 
+ * @brief  Interrupt structure
  */
 typedef union _TM_NRF24L01_IRQ_t {
 	struct {
@@ -281,6 +197,16 @@ typedef union _TM_NRF24L01_IRQ_t {
 } TM_NRF24L01_IRQ_t;
 
 
+
+/**
+ * @brief  Transmission status enumeration
+ */
+typedef enum _TM_NRF24L01_Transmit_Status_t {
+	TM_NRF24L01_Transmit_Status_Lost = 0x00,   /*!< Message is lost, reached maximum number of retransmissions */
+	TM_NRF24L01_Transmit_Status_Ok = 0x01,     /*!< Message sent successfully */
+	TM_NRF24L01_Transmit_Status_Sending = 0xFF /*!< Message is still sending */
+} Transmit_Status_t;
+
 /**
  * @brief  Data rate enumeration
  */
@@ -300,9 +226,14 @@ typedef enum _TM_NRF24L01_OutputPower_t {
 	TM_NRF24L01_OutputPower_0dBm          /*!< Output power set to 0dBm */
 } TM_NRF24L01_OutputPower_t;
 
-#ifdef __cplusplus
- }
-#endif
+
+typedef struct {
+	uint8_t PayloadSize;				//Payload size
+	uint8_t Channel;					//Channel selected
+	TM_NRF24L01_OutputPower_t OutPwr;	//Output power
+	TM_NRF24L01_DataRate_t DataRate;	//Data rate
+} NRF24L01_Conig_t;
+
 
 
-#endif /* _NRF_24L01_H_ */
+#endif /* _NRF_24L01_DEINES_H_ */