diff --git a/Examples/LL/SPI/nRF24L01_Wireless/main.c b/Examples/LL/SPI/nRF24L01_Wireless/main.c index c683bfc..2c6437c 100644 --- a/Examples/LL/SPI/nRF24L01_Wireless/main.c +++ b/Examples/LL/SPI/nRF24L01_Wireless/main.c @@ -19,9 +19,18 @@ /* MODE_TX, MODE_RX, MODE_RX_INT */ #define MODE_TX 0 +#define MODE_TX_FAST 1 #define MODE_RX 2 #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 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_ClearIRQFlags(); NRF24L01_DumpConfig(); - - while(1); #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"); NRF24L01_TX_Mode(RX_ADDRESS, TX_ADDRESS); NRF24L01_DumpConfig(); while(1) { - NRF24L01_TxPacket(tmp, 32); - LL_mDelay(500); + NRF24L01_TxPacket(payload, 32); + 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 @@ -192,7 +221,7 @@ static void APP_SPIConfig(void) SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; 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; LL_SPI_Init(SPI1, &SPI_InitStruct); LL_SPI_Enable(SPI1); diff --git a/Examples/LL/SPI/nRF24L01_Wireless/nrf24l01.c b/Examples/LL/SPI/nRF24L01_Wireless/nrf24l01.c index 061cf8c..fecf356 100644 --- a/Examples/LL/SPI/nRF24L01_Wireless/nrf24l01.c +++ b/Examples/LL/SPI/nRF24L01_Wireless/nrf24l01.c @@ -8,7 +8,7 @@ uint8_t TX_BUF[NRF24L01_PLOAD_WIDTH]; 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 value; - CSN(0); + CSN_LOW; SPI_TxRxByte(reg); value = SPI_TxRxByte(NRF24L01_CMD_NOP); - CSN(1); + CSN_HIGH; 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 status; - CSN(0); + CSN_LOW; if (reg < NRF24L01_CMD_REGISTER_W) { // This is a register access @@ -50,7 +50,7 @@ uint8_t NRF24L01_Write_Reg(uint8_t reg, uint8_t value) SPI_TxRxByte(value); } } - CSN(1); + CSN_HIGH; 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) { - CSN(0); + CSN_LOW; uint8_t status = SPI_TxRxByte(reg); while (len--) { *buf++ = SPI_TxRxByte(NRF24L01_CMD_NOP); } - CSN(1); + CSN_HIGH; 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 * 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); while (len--) { SPI_TxRxByte(*buf++); } - CSN(1); + CSN_HIGH; return status; } @@ -125,6 +125,13 @@ void NRF24L01_FlushTX(void) 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 * 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) { - CE(0); + CE_LOW; _NRF24L01_Config(tx_addr); // RX Address of P0 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 */ NRF24L01_Write_Reg(NRF24L01_CMD_REGISTER_W + NRF24L01_REG_CONFIG, 0x0f); //RX,PWR_UP,CRC16,EN_CRC - CE(1); + CE_HIGH; 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) { - CE(0); + CE_LOW; _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 // 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_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; while(IRQ); - CE(0); + CE_LOW; status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS); BSP_UART_TxHex8(status); 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); for (int i = 0; i < 32; i++) @@ -228,9 +235,9 @@ uint8_t NRF24L01_RxPacket(uint8_t *rx_buf) } BSP_UART_TxString("\r\n"); result = 1; - NRF24L01_ClearIRQFlag(NRF24L01_FLAG_RX_DREADY); + NRF24L01_ClearIRQFlag(NRF24L01_FLAG_RX_DR); } - CE(1); + CE_HIGH; return result; } @@ -240,12 +247,12 @@ uint8_t NRF24L01_RxPacket(uint8_t *rx_buf) void NRF24L01_IntRxPacket(uint8_t *rx_buf) { uint8_t status; - CE(0); + CE_LOW; status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS); BSP_UART_TxHex8(status); 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); 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_TxString("\r\n"); - NRF24L01_ClearIRQFlag(NRF24L01_FLAG_RX_DREADY); + NRF24L01_ClearIRQFlag(NRF24L01_FLAG_RX_DR); } status |= NRF24L01_MASK_STATUS_IRQ; 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 status = 0x00; - CE(0); + CE_LOW; len = len > NRF24L01_PLOAD_WIDTH? NRF24L01_PLOAD_WIDTH : len; NRF24L01_Write_From_Buf(NRF24L01_CMD_TX_PLOAD_W, tx_buf, len); - CE(1); + CE_HIGH; while(IRQ != 0); // Waiting send finish - CE(0); + CE_LOW; status = NRF24L01_Read_Reg(NRF24L01_REG_STATUS); BSP_UART_TxHex8(status); BSP_UART_TxChar(':'); - if(status & NRF24L01_FLAG_TX_DSENT) + if(status & NRF24L01_FLAG_TX_DS) { BSP_UART_TxString("Data sent: "); for (uint8_t i = 0; i < len; i++) { BSP_UART_TxHex8(tx_buf[i]); } BSP_UART_TxString("\r\n"); - NRF24L01_ClearIRQFlag(NRF24L01_FLAG_TX_DSENT); + NRF24L01_ClearIRQFlag(NRF24L01_FLAG_TX_DS); } 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_ClearIRQFlag(NRF24L01_FLAG_MAX_RT); } - CE(1); + CE_HIGH; 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 diff --git a/Examples/LL/SPI/nRF24L01_Wireless/nrf24l01.h b/Examples/LL/SPI/nRF24L01_Wireless/nrf24l01.h index 0093c10..316d9b3 100644 --- a/Examples/LL/SPI/nRF24L01_Wireless/nrf24l01.h +++ b/Examples/LL/SPI/nRF24L01_Wireless/nrf24l01.h @@ -4,8 +4,10 @@ #include // 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 CE(x) x ? LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5) : LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_5) +#define CSN_HIGH LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_6) +#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) // 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_ACK_PAY 0x02 // EN_ACK_PAY 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_TX_DSENT 0x20 // TX_DS bit (data sent TX FIFO interrupt) +#define NRF24L01_FLAG_RX_DR 0x40 // RX_DR bit (data ready RX 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_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 #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 * 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 */ uint8_t NRF24L01_RxPacket(uint8_t *rx_buf); + +/** + * Receive data in interrupt +*/ 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); +/** + * Send data in FIFO without sync ack +*/ +uint8_t NRF24L01_TxFast(const void *txbuf); + /** * Switch NRF24L01 to RX mode */ @@ -151,6 +166,11 @@ void NRF24L01_FlushRX(void); */ void NRF24L01_FlushTX(void); +/** + * Clear TX error flags +*/ +void NRF24L01_ResetTX(void); + /** * Clear IRQ bit of the STATUS register * reg - NRF24L01_FLAG_RX_DREADY, NRF24L01_FLAG_TX_DSENT, NRF24L01_FLAG_MAX_RT