refactor: nrf24l01 example fast tx mode

This commit is contained in:
IOsetting 2023-02-04 12:20:34 +08:00
parent 8d60209268
commit 3dceece9bb
3 changed files with 122 additions and 44 deletions

View File

@ -19,9 +19,18 @@
/* MODE_TX, MODE_RX, MODE_RX_INT */ /* MODE_TX, MODE_RX, MODE_RX_INT */
#define MODE_TX 0 #define MODE_TX 0
#define MODE_TX_FAST 1
#define MODE_RX 2 #define MODE_RX 2
#define MODE_RX_INT 3 #define MODE_RX_INT 3
#define NRF24_MODE MODE_TX #define NRF24_MODE MODE_TX_FAST
#if (NRF24_MODE == MODE_TX || NRF24_MODE == MODE_TX_FAST)
uint8_t payload[] = {
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x21, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x28,
0x31, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x38,
0x41, 0x12, 0x13, 0x14, 0x15, 0x16, 0x47, 0x48};
#endif
uint8_t RX_ADDRESS[NRF24L01_ADDR_WIDTH] = {0x32,0x4E,0x6F,0x64,0x65}; uint8_t RX_ADDRESS[NRF24L01_ADDR_WIDTH] = {0x32,0x4E,0x6F,0x64,0x65};
uint8_t TX_ADDRESS[NRF24L01_ADDR_WIDTH] = {0x32,0x4E,0x6F,0x64,0x22}; uint8_t TX_ADDRESS[NRF24L01_ADDR_WIDTH] = {0x32,0x4E,0x6F,0x64,0x22};
@ -71,24 +80,44 @@ int main(void)
NRF24L01_RX_Mode(TX_ADDRESS, RX_ADDRESS); NRF24L01_RX_Mode(TX_ADDRESS, RX_ADDRESS);
NRF24L01_ClearIRQFlags(); NRF24L01_ClearIRQFlags();
NRF24L01_DumpConfig(); NRF24L01_DumpConfig();
while(1); while(1);
#elif (NRF24_MODE == MODE_TX) #elif (NRF24_MODE == MODE_TX)
uint8_t tmp[] = {0x1f,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x21, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x28,
0x31, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x38,
0x41, 0x12, 0x13, 0x14, 0x15, 0x16, 0x47, 0x48};
printf("nRF24L01 in TX mode\r\n"); printf("nRF24L01 in TX mode\r\n");
NRF24L01_TX_Mode(RX_ADDRESS, TX_ADDRESS); NRF24L01_TX_Mode(RX_ADDRESS, TX_ADDRESS);
NRF24L01_DumpConfig(); NRF24L01_DumpConfig();
while(1) while(1)
{ {
NRF24L01_TxPacket(tmp, 32); NRF24L01_TxPacket(payload, 32);
LL_mDelay(500); LL_mDelay(100);
}
#elif (NRF24_MODE == MODE_TX_FAST)
printf("nRF24L01 in fast TX mode\r\n");
NRF24L01_TX_Mode(RX_ADDRESS, TX_ADDRESS);
NRF24L01_DumpConfig();
uint8_t succ = 0, err = 0;
while (1)
{
if (NRF24L01_TxFast(payload) != 0)
{
NRF24L01_ResetTX();
err++;
}
else
{
succ++;
}
if (err == 255 || succ == 255)
{
printf("Fail/Succ: %d/%d\r\n", err, succ);
err = 0;
succ = 0;
}
LL_mDelay(5);
} }
#endif #endif
@ -192,7 +221,7 @@ static void APP_SPIConfig(void)
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8; SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4;
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
LL_SPI_Init(SPI1, &SPI_InitStruct); LL_SPI_Init(SPI1, &SPI_InitStruct);
LL_SPI_Enable(SPI1); LL_SPI_Enable(SPI1);

View File

@ -8,7 +8,7 @@ uint8_t TX_BUF[NRF24L01_PLOAD_WIDTH];
void NRF24L01_Init(void) void NRF24L01_Init(void)
{ {
CSN(1); CSN_HIGH;
} }
/** /**
@ -17,10 +17,10 @@ void NRF24L01_Init(void)
uint8_t NRF24L01_Read_Reg(uint8_t reg) uint8_t NRF24L01_Read_Reg(uint8_t reg)
{ {
uint8_t value; uint8_t value;
CSN(0); CSN_LOW;
SPI_TxRxByte(reg); SPI_TxRxByte(reg);
value = SPI_TxRxByte(NRF24L01_CMD_NOP); value = SPI_TxRxByte(NRF24L01_CMD_NOP);
CSN(1); CSN_HIGH;
return value; return value;
} }
@ -30,7 +30,7 @@ uint8_t NRF24L01_Read_Reg(uint8_t reg)
uint8_t NRF24L01_Write_Reg(uint8_t reg, uint8_t value) uint8_t NRF24L01_Write_Reg(uint8_t reg, uint8_t value)
{ {
uint8_t status; uint8_t status;
CSN(0); CSN_LOW;
if (reg < NRF24L01_CMD_REGISTER_W) if (reg < NRF24L01_CMD_REGISTER_W)
{ {
// This is a register access // This is a register access
@ -50,7 +50,7 @@ uint8_t NRF24L01_Write_Reg(uint8_t reg, uint8_t value)
SPI_TxRxByte(value); SPI_TxRxByte(value);
} }
} }
CSN(1); CSN_HIGH;
return status; return status;
} }
@ -62,13 +62,13 @@ uint8_t NRF24L01_Write_Reg(uint8_t reg, uint8_t value)
*/ */
uint8_t NRF24L01_Read_To_Buf(uint8_t reg, uint8_t *buf, uint8_t len) uint8_t NRF24L01_Read_To_Buf(uint8_t reg, uint8_t *buf, uint8_t len)
{ {
CSN(0); CSN_LOW;
uint8_t status = SPI_TxRxByte(reg); uint8_t status = SPI_TxRxByte(reg);
while (len--) while (len--)
{ {
*buf++ = SPI_TxRxByte(NRF24L01_CMD_NOP); *buf++ = SPI_TxRxByte(NRF24L01_CMD_NOP);
} }
CSN(1); CSN_HIGH;
return status; return status;
} }
@ -78,15 +78,15 @@ uint8_t NRF24L01_Read_To_Buf(uint8_t reg, uint8_t *buf, uint8_t len)
* buf - pointer to the buffer with data * buf - pointer to the buffer with data
* len - number of bytes to write * len - number of bytes to write
*/ */
uint8_t NRF24L01_Write_From_Buf(uint8_t reg, uint8_t *buf, uint8_t len) uint8_t NRF24L01_Write_From_Buf(uint8_t reg, const uint8_t *buf, uint8_t len)
{ {
CSN(0); CSN_LOW;
uint8_t status = SPI_TxRxByte(reg); uint8_t status = SPI_TxRxByte(reg);
while (len--) while (len--)
{ {
SPI_TxRxByte(*buf++); SPI_TxRxByte(*buf++);
} }
CSN(1); CSN_HIGH;
return status; return status;
} }
@ -125,6 +125,13 @@ void NRF24L01_FlushTX(void)
NRF24L01_Write_Reg(NRF24L01_CMD_FLUSH_TX, NRF24L01_CMD_NOP); NRF24L01_Write_Reg(NRF24L01_CMD_FLUSH_TX, NRF24L01_CMD_NOP);
} }
void NRF24L01_ResetTX(void)
{
NRF24L01_Write_Reg(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_STATUS, NRF24L01_FLAG_MAX_RT); // Clear max retry flag
CE_LOW;
CE_HIGH;
}
/** /**
* Clear IRQ bit of the STATUS register * Clear IRQ bit of the STATUS register
* reg - NRF24L01_FLAG_RX_DREADY * reg - NRF24L01_FLAG_RX_DREADY
@ -173,7 +180,7 @@ void _NRF24L01_Config(uint8_t *tx_addr)
*/ */
void NRF24L01_RX_Mode(uint8_t *rx_addr, uint8_t *tx_addr) void NRF24L01_RX_Mode(uint8_t *rx_addr, uint8_t *tx_addr)
{ {
CE(0); CE_LOW;
_NRF24L01_Config(tx_addr); _NRF24L01_Config(tx_addr);
// RX Address of P0 // RX Address of P0
NRF24L01_Write_From_Buf(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_RX_ADDR_P0, rx_addr, NRF24L01_ADDR_WIDTH); NRF24L01_Write_From_Buf(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_RX_ADDR_P0, rx_addr, NRF24L01_ADDR_WIDTH);
@ -189,7 +196,7 @@ void NRF24L01_RX_Mode(uint8_t *rx_addr, uint8_t *tx_addr)
7)Reserved 0 7)Reserved 0
*/ */
NRF24L01_Write_Reg(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_CONFIG, 0x0f); //RX,PWR_UP,CRC16,EN_CRC NRF24L01_Write_Reg(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_CONFIG, 0x0f); //RX,PWR_UP,CRC16,EN_CRC
CE(1); CE_HIGH;
NRF24L01_FlushRX(); NRF24L01_FlushRX();
} }
@ -198,13 +205,13 @@ void NRF24L01_RX_Mode(uint8_t *rx_addr, uint8_t *tx_addr)
*/ */
void NRF24L01_TX_Mode(uint8_t *rx_addr, uint8_t *tx_addr) void NRF24L01_TX_Mode(uint8_t *rx_addr, uint8_t *tx_addr)
{ {
CE(0); CE_LOW;
_NRF24L01_Config(tx_addr); _NRF24L01_Config(tx_addr);
// On the PTX the **TX_ADDR** must be the same as the **RX_ADDR_P0** and as the pipe address for the designated pipe // On the PTX the **TX_ADDR** must be the same as the **RX_ADDR_P0** and as the pipe address for the designated pipe
// RX_ADDR_P0 will be used for receiving ACK // RX_ADDR_P0 will be used for receiving ACK
NRF24L01_Write_From_Buf(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_RX_ADDR_P0, tx_addr, NRF24L01_ADDR_WIDTH); NRF24L01_Write_From_Buf(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_RX_ADDR_P0, tx_addr, NRF24L01_ADDR_WIDTH);
NRF24L01_Write_Reg(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_CONFIG, 0x0e); //TX,PWR_UP,CRC16,EN_CRC NRF24L01_Write_Reg(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_CONFIG, 0x0e); //TX,PWR_UP,CRC16,EN_CRC
CE(1); CE_HIGH;
} }
/** /**
@ -214,12 +221,12 @@ uint8_t NRF24L01_RxPacket(uint8_t *rx_buf)
{ {
uint8_t status, result = 0; uint8_t status, result = 0;
while(IRQ); while(IRQ);
CE(0); CE_LOW;
status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS); status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS);
BSP_UART_TxHex8(status); BSP_UART_TxHex8(status);
BSP_UART_TxChar(':'); BSP_UART_TxChar(':');
if(status & NRF24L01_FLAG_RX_DREADY) if(status & NRF24L01_FLAG_RX_DR)
{ {
NRF24L01_Read_To_Buf(NRF24L01_CMD_RX_PLOAD_R, rx_buf, NRF24L01_PLOAD_WIDTH); NRF24L01_Read_To_Buf(NRF24L01_CMD_RX_PLOAD_R, rx_buf, NRF24L01_PLOAD_WIDTH);
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
@ -228,9 +235,9 @@ uint8_t NRF24L01_RxPacket(uint8_t *rx_buf)
} }
BSP_UART_TxString("\r\n"); BSP_UART_TxString("\r\n");
result = 1; result = 1;
NRF24L01_ClearIRQFlag(NRF24L01_FLAG_RX_DREADY); NRF24L01_ClearIRQFlag(NRF24L01_FLAG_RX_DR);
} }
CE(1); CE_HIGH;
return result; return result;
} }
@ -240,12 +247,12 @@ uint8_t NRF24L01_RxPacket(uint8_t *rx_buf)
void NRF24L01_IntRxPacket(uint8_t *rx_buf) void NRF24L01_IntRxPacket(uint8_t *rx_buf)
{ {
uint8_t status; uint8_t status;
CE(0); CE_LOW;
status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS); status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS);
BSP_UART_TxHex8(status); BSP_UART_TxHex8(status);
BSP_UART_TxChar(':'); BSP_UART_TxChar(':');
if(status & NRF24L01_FLAG_RX_DREADY) if(status & NRF24L01_FLAG_RX_DR)
{ {
NRF24L01_Read_To_Buf(NRF24L01_CMD_RX_PLOAD_R, rx_buf, NRF24L01_PLOAD_WIDTH); NRF24L01_Read_To_Buf(NRF24L01_CMD_RX_PLOAD_R, rx_buf, NRF24L01_PLOAD_WIDTH);
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
@ -253,11 +260,11 @@ void NRF24L01_IntRxPacket(uint8_t *rx_buf)
BSP_UART_TxHex8(RX_BUF[i]); BSP_UART_TxHex8(RX_BUF[i]);
} }
BSP_UART_TxString("\r\n"); BSP_UART_TxString("\r\n");
NRF24L01_ClearIRQFlag(NRF24L01_FLAG_RX_DREADY); NRF24L01_ClearIRQFlag(NRF24L01_FLAG_RX_DR);
} }
status |= NRF24L01_MASK_STATUS_IRQ; status |= NRF24L01_MASK_STATUS_IRQ;
NRF24L01_Write_Reg(NRF24L01_REG_STATUS, status); NRF24L01_Write_Reg(NRF24L01_REG_STATUS, status);
CE(1); CE_HIGH;
} }
/** /**
@ -266,24 +273,24 @@ void NRF24L01_IntRxPacket(uint8_t *rx_buf)
uint8_t NRF24L01_TxPacket(uint8_t *tx_buf, uint8_t len) uint8_t NRF24L01_TxPacket(uint8_t *tx_buf, uint8_t len)
{ {
uint8_t status = 0x00; uint8_t status = 0x00;
CE(0); CE_LOW;
len = len > NRF24L01_PLOAD_WIDTH? NRF24L01_PLOAD_WIDTH : len; len = len > NRF24L01_PLOAD_WIDTH? NRF24L01_PLOAD_WIDTH : len;
NRF24L01_Write_From_Buf(NRF24L01_CMD_TX_PLOAD_W, tx_buf, len); NRF24L01_Write_From_Buf(NRF24L01_CMD_TX_PLOAD_W, tx_buf, len);
CE(1); CE_HIGH;
while(IRQ != 0); // Waiting send finish while(IRQ != 0); // Waiting send finish
CE(0); CE_LOW;
status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS); status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS);
BSP_UART_TxHex8(status); BSP_UART_TxHex8(status);
BSP_UART_TxChar(':'); BSP_UART_TxChar(':');
if(status & NRF24L01_FLAG_TX_DSENT) if(status & NRF24L01_FLAG_TX_DS)
{ {
BSP_UART_TxString("Data sent: "); BSP_UART_TxString("Data sent: ");
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
BSP_UART_TxHex8(tx_buf[i]); BSP_UART_TxHex8(tx_buf[i]);
} }
BSP_UART_TxString("\r\n"); BSP_UART_TxString("\r\n");
NRF24L01_ClearIRQFlag(NRF24L01_FLAG_TX_DSENT); NRF24L01_ClearIRQFlag(NRF24L01_FLAG_TX_DS);
} }
else if(status & NRF24L01_FLAG_MAX_RT) else if(status & NRF24L01_FLAG_MAX_RT)
{ {
@ -291,10 +298,32 @@ uint8_t NRF24L01_TxPacket(uint8_t *tx_buf, uint8_t len)
NRF24L01_FlushTX(); NRF24L01_FlushTX();
NRF24L01_ClearIRQFlag(NRF24L01_FLAG_MAX_RT); NRF24L01_ClearIRQFlag(NRF24L01_FLAG_MAX_RT);
} }
CE(1); CE_HIGH;
return status; return status;
} }
void NRF24L01_TxPacketFast(const void *txbuf)
{
NRF24L01_Write_From_Buf(NRF24L01_CMD_TX_PLOAD_W, txbuf, NRF24L01_PLOAD_WIDTH);
CE_HIGH;
}
uint8_t NRF24L01_TxFast(const void *txbuf)
{
uint8_t status;
// Blocking only if FIFO is full. This will loop and block until TX is successful or fail
do
{
status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS);
if (status & NRF24L01_FLAG_MAX_RT)
{
return 1;
}
} while (status & NRF24L01_FLAG_TX_FULL);
NRF24L01_TxPacketFast(txbuf);
return 0;
}
/** /**
* Dump nRF24L01 configuration * Dump nRF24L01 configuration

View File

@ -4,8 +4,10 @@
#include <main.h> #include <main.h>
// CE Pin & CSN Pin & IRQ Pin // CE Pin & CSN Pin & IRQ Pin
#define CSN(x) x ? LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_6) : LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_6) #define CSN_HIGH LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_6)
#define CE(x) x ? LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5) : LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_5) #define CSN_LOW LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_6)
#define CE_HIGH LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5)
#define CE_LOW LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_5)
#define IRQ READ_BIT(GPIOA->IDR, LL_GPIO_PIN_4) #define IRQ READ_BIT(GPIOA->IDR, LL_GPIO_PIN_4)
// SPI(nRF24L01) commands // SPI(nRF24L01) commands
@ -57,9 +59,13 @@
#define NRF24L01_FEATURE_EN_DYN_ACK 0x01 // EN_DYN_ACK bit in FEATURE register #define NRF24L01_FEATURE_EN_DYN_ACK 0x01 // EN_DYN_ACK bit in FEATURE register
#define NRF24L01_FEATURE_EN_ACK_PAY 0x02 // EN_ACK_PAY bit in FEATURE register #define NRF24L01_FEATURE_EN_ACK_PAY 0x02 // EN_ACK_PAY bit in FEATURE register
#define NRF24L01_FEATURE_EN_DPL 0x04 // EN_DPL bit in FEATURE register #define NRF24L01_FEATURE_EN_DPL 0x04 // EN_DPL bit in FEATURE register
#define NRF24L01_FLAG_RX_DREADY 0x40 // RX_DR bit (data ready RX FIFO interrupt) #define NRF24L01_FLAG_RX_DR 0x40 // RX_DR bit (data ready RX FIFO interrupt)
#define NRF24L01_FLAG_TX_DSENT 0x20 // TX_DS bit (data sent TX FIFO interrupt) #define NRF24L01_FLAG_TX_DS 0x20 // TX_DS bit (data sent TX FIFO interrupt)
#define NRF24L01_FLAG_MAX_RT 0x10 // MAX_RT bit (maximum number of TX re-transmits interrupt) #define NRF24L01_FLAG_MAX_RT 0x10 // MAX_RT bit (maximum number of TX re-transmits interrupt)
#define NRF24L01_FLAG_IT_BITS 0x70 // RX_DR|TX_DS|MAX_RT
#define NRF24L01_FLAG_TX_FULL 0x01 // TX FIFO full flag. 1: TX FIFO full. 0: Available locations in TX FIFO
// Register masks definitions // Register masks definitions
#define NRF24L01_MASK_REG_MAP 0x1F // Mask bits[4:0] for CMD_RREG and CMD_WREG commands #define NRF24L01_MASK_REG_MAP 0x1F // Mask bits[4:0] for CMD_RREG and CMD_WREG commands
@ -118,12 +124,16 @@ uint8_t NRF24L01_Read_To_Buf(uint8_t reg,uint8_t *pBuf,uint8_t len);
* buf - pointer to the buffer with data * buf - pointer to the buffer with data
* len - number of bytes to write * len - number of bytes to write
*/ */
uint8_t NRF24L01_Write_From_Buf(uint8_t reg,uint8_t *pBuf,uint8_t len); uint8_t NRF24L01_Write_From_Buf(uint8_t reg, const uint8_t *pBuf,uint8_t len);
/** /**
* Hold till data received and written to rx_buf * Hold till data received and written to rx_buf
*/ */
uint8_t NRF24L01_RxPacket(uint8_t *rx_buf); uint8_t NRF24L01_RxPacket(uint8_t *rx_buf);
/**
* Receive data in interrupt
*/
void NRF24L01_IntRxPacket(uint8_t *rx_buf); void NRF24L01_IntRxPacket(uint8_t *rx_buf);
/** /**
@ -131,6 +141,11 @@ void NRF24L01_IntRxPacket(uint8_t *rx_buf);
*/ */
uint8_t NRF24L01_TxPacket(uint8_t *tx_buf, uint8_t len); uint8_t NRF24L01_TxPacket(uint8_t *tx_buf, uint8_t len);
/**
* Send data in FIFO without sync ack
*/
uint8_t NRF24L01_TxFast(const void *txbuf);
/** /**
* Switch NRF24L01 to RX mode * Switch NRF24L01 to RX mode
*/ */
@ -151,6 +166,11 @@ void NRF24L01_FlushRX(void);
*/ */
void NRF24L01_FlushTX(void); void NRF24L01_FlushTX(void);
/**
* Clear TX error flags
*/
void NRF24L01_ResetTX(void);
/** /**
* Clear IRQ bit of the STATUS register * Clear IRQ bit of the STATUS register
* reg - NRF24L01_FLAG_RX_DREADY, NRF24L01_FLAG_TX_DSENT, NRF24L01_FLAG_MAX_RT * reg - NRF24L01_FLAG_RX_DREADY, NRF24L01_FLAG_TX_DSENT, NRF24L01_FLAG_MAX_RT