/* ################################################################### ** This component module is generated by Processor Expert. Do not modify it. ** Filename : McuNRF24L01.c ** Component : nRF24L01 ** Version : Component 01.103, Driver 01.00, CPU db: 3.00.000 ** Compiler : GNU C Compiler ** Date/Time : 2021-07-06, 16:35, # CodeGen: 0 ** Abstract : ** This component implements a driver for the Nordic Semiconductor nRF24L01 2.4 GHz transceiver. ** Settings : ** Contents : ** ConfigureSPI - void McuNRF24L01_ConfigureSPI(void); ** WriteRegister - void McuNRF24L01_WriteRegister(uint8_t reg, uint8_t val); ** ReadRegister - uint8_t McuNRF24L01_ReadRegister(uint8_t reg); ** ReadRegisterData - void McuNRF24L01_ReadRegisterData(uint8_t reg, uint8_t *buf, uint8_t bufSize); ** WriteRegisterData - void McuNRF24L01_WriteRegisterData(uint8_t reg, uint8_t *buf, uint8_t bufSize); ** WriteRead - uint8_t McuNRF24L01_WriteRead(uint8_t val); ** Write - void McuNRF24L01_Write(uint8_t val); ** GetStatus - uint8_t McuNRF24L01_GetStatus(void); ** GetStatusClrIRQ - uint8_t McuNRF24L01_GetStatusClrIRQ(void); ** ResetStatusIRQ - void McuNRF24L01_ResetStatusIRQ(uint8_t flags); ** TxPayload - void McuNRF24L01_TxPayload(uint8_t *payload, uint8_t payloadSize); ** RxPayload - void McuNRF24L01_RxPayload(uint8_t *payload, uint8_t payloadSize); ** StopRxTx - void McuNRF24L01_StopRxTx(void); ** StartRxTx - void McuNRF24L01_StartRxTx(void); ** EnableAutoAck - uint8_t McuNRF24L01_EnableAutoAck(uint8_t pipes); ** SetStaticPipePayload - uint8_t McuNRF24L01_SetStaticPipePayload(uint8_t pipe, uint8_t payloadBytes); ** EnableDynamicPayloadLength - uint8_t McuNRF24L01_EnableDynamicPayloadLength(uint8_t pipeMask); ** WriteFeature - uint8_t McuNRF24L01_WriteFeature(uint8_t featureMask); ** ReadFeature - uint8_t McuNRF24L01_ReadFeature(uint8_t *featureMask); ** ReadNofRxPayload - uint8_t McuNRF24L01_ReadNofRxPayload(uint8_t *nof); ** ReadObserveTxRegister - uint8_t McuNRF24L01_ReadObserveTxRegister(uint8_t *nofLoss, uint8_t *nofRetransmitted); ** ReadReceivedPowerDetector - uint8_t McuNRF24L01_ReadReceivedPowerDetector(uint8_t *rpd); ** SetChannel - uint8_t McuNRF24L01_SetChannel(uint8_t channel); ** GetChannel - uint8_t McuNRF24L01_GetChannel(uint8_t *channel); ** ConstantCarrierWave - uint8_t McuNRF24L01_ConstantCarrierWave(bool turnOn); ** SetOutputPower - uint8_t McuNRF24L01_SetOutputPower(int8_t power); ** GetOutputPower - uint8_t McuNRF24L01_GetOutputPower(int8_t *power); ** SetDataRate - uint8_t McuNRF24L01_SetDataRate(uint16_t rate); ** GetDataRate - uint8_t McuNRF24L01_GetDataRate(uint16_t *rate); ** SetAddressWidth - uint8_t McuNRF24L01_SetAddressWidth(uint8_t width); ** GetAddressWidth - uint8_t McuNRF24L01_GetAddressWidth(uint8_t *pAddrWidth); ** SetTxAddress - uint8_t McuNRF24L01_SetTxAddress(uint8_t *address, uint8_t nofAddressBytes); ** GetTxAddress - uint8_t McuNRF24L01_GetTxAddress(uint8_t *address, uint8_t nofAddressBytes); ** SetRxAddress - uint8_t McuNRF24L01_SetRxAddress(uint8_t pipe, uint8_t *address, uint8_t... ** GetRxAddress - uint8_t McuNRF24L01_GetRxAddress(uint8_t pipe, uint8_t *address, uint8_t... ** GetFifoStatus - uint8_t McuNRF24L01_GetFifoStatus(uint8_t *status); ** PollInterrupt - bool McuNRF24L01_PollInterrupt(void); ** Deinit - void McuNRF24L01_Deinit(void); ** Init - void McuNRF24L01_Init(void); ** ** * Copyright (c) 2013-2018, Erich Styger ** * Web: https://mcuoneclipse.com ** * SourceForge: https://sourceforge.net/projects/mcuoneclipse ** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx ** * All rights reserved. ** * ** * Redistribution and use in source and binary forms, with or without modification, ** * are permitted provided that the following conditions are met: ** * ** * - Redistributions of source code must retain the above copyright notice, this list ** * of conditions and the following disclaimer. ** * ** * - Redistributions in binary form must reproduce the above copyright notice, this ** * list of conditions and the following disclaimer in the documentation and/or ** * other materials provided with the distribution. ** * ** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ###################################################################*/ /*! ** @file McuNRF24L01.c ** @version 01.00 ** @brief ** This component implements a driver for the Nordic Semiconductor nRF24L01 2.4 GHz transceiver. */ /*! ** @addtogroup McuNRF24L01_module McuNRF24L01 module documentation ** @{ */ /* MODULE McuNRF24L01. */ #include "McuNRF24L01.h" #if McuNRF24L01_CONFIG_IS_ENABLED #include "McuWait.h" #include "McuSPI.h" #include "McuGPIO.h" #include "McuLog.h" #include "McuUtility.h" static McuGPIO_Handle_t cePin; /* CE pin, HIGH active, if active, device is in RX/TX mode */ static McuGPIO_Handle_t csnPin; /* CSN pin, LOW active, used to select device (chip select) to send commands */ /* Macros to hide low level functionality */ #define McuNRF24L01_WAIT_US(x) McuWait_Waitus(x) /* wait for the given number of micro-seconds */ #define McuNRF24L01_CE_LOW() McuGPIO_SetLow(cePin) /* put CE LOW */ #define McuNRF24L01_CE_HIGH() McuGPIO_SetHigh(cePin) /* put CE HIGH */ #define McuNRF24L01_CSN_LOW() McuGPIO_SetLow(csnPin) /* put CSN LOW, activate bus */ #define McuNRF24L01_CSN_HIGH() McuGPIO_SetHigh(csnPin) /* put CSN HIGH, deactivate bus */ #define McuNRF24L01_USE_SPI_BLOCK_MODE 0 /* using SPI block read/write */ #if 0 static void SM1_Enable(void) { /*! \todo */ } static void SM1_Disable(void) { /*! \todo */ } static int SM1_SetShiftClockPolarity(int pol) { /*! \todo */ return ERR_OK; } static int SM1_SetIdleClockPolarity(int pol) { /*! \todo */ return ERR_OK; } static int SM1_SetBaudRate(int baud) { return McuSPI_SetBaudRate(baud); } #endif #if 0 static int SM1_GetCharsInTxBuf(void) { return 0; } static int SM1_GetCharsInRxBuf(void) { return 1; } static int SM1_SendChar(unsigned char ch) { return McuSPI_SendByte(ch); } #endif void McuNRF24L01_OnActivate(void) { #if PL_HAS_SPI SPI_OnSPIActivate(SPI_BAUD_INDEX_NRF); #endif } void McuNRF24L01_OnDeactivate(void) { #if PL_HAS_SPI SPI_OnSPIDeactivate(SPI_BAUD_INDEX_NRF); #endif } /* HW SPI */ #define McuNRF24L01_SPI_Enable() SM1_Enable() #define McuNRF24L01_SPI_Disable() SM1_Disable() #define McuNRF24L01_SPI_SetShiftClockPolarity(val) (void)SM1_SetShiftClockPolarity(val) #define McuNRF24L01_SPI_SetIdleClockPolarity(val) (void)SM1_SetIdleClockPolarity(val) #define McuNRF24L01_SPI_GetCharsInTxBuf() SM1_GetCharsInTxBuf() #define McuNRF24L01_SPI_GetCharsInRxBuf() SM1_GetCharsInRxBuf() #define McuNRF24L01_SPI_SendChar(ch) SM1_SendChar(ch) #define McuNRF24L01_SPI_RecvChar(p) McuSPI_ReceiveByte(p) #define McuNRF24L01_SPI_SetBaudRateMode(m) SM1_SetBaudRateMode(m) #if McuNRF24L01_CONFIG_USE_MUTEX #include "McuRTOS.h" static SemaphoreHandle_t McuNRF24L01_Mutex = NULL; /* Mutex to allow mutual exclusive access to the bus */ #endif /* Internal method prototypes */ static uint8_t SPIWriteRead(uint8_t val); static void SPIWriteReadBuffer(uint8_t *bufOut, uint8_t *bufIn, uint8_t bufSize); static void SPIWriteBuffer(uint8_t *bufOut, uint8_t bufSize); /* ** =================================================================== ** Method : ConfigureSPI (component nRF24L01) ** ** Description : ** Configures the SPI bus ** Parameters : None ** Returns : Nothing ** =================================================================== */ void McuNRF24L01_ConfigureSPI(void) { #if McuNRF24L01_SWITCH_BUS (void)McuNRF24L01_SPI_Disable(); (void)McuNRF24L01_SPI_SetShiftClockPolarity(0); /* falling edge */ (void)McuNRF24L01_SPI_SetIdleClockPolarity(0); /* low idle clock polarity */ (void)McuNRF24L01_SPI_SetBaudRateMode(McuNRF24L01_BAUD_RATE_MODE); /* set bus speed */ McuSPI_SetBaudRate(baud); (void)McuNRF24L01_SPI_Enable(); #endif } /* ** =================================================================== ** Method : SPIWriteRead (component nRF24L01) ** ** Description : ** This method is internal. It is used by Processor Expert only. ** =================================================================== */ static uint8_t SPIWriteRead(uint8_t val) { uint8_t ch; #if 0 while(McuNRF24L01_SPI_GetCharsInTxBuf()!=0) {} /* wait until tx is empty */ while(McuNRF24L01_SPI_SendChar(val)!=ERR_OK) {} /* send character */ while(McuNRF24L01_SPI_GetCharsInTxBuf()!=0) {} /* wait until data has been sent */ while(McuNRF24L01_SPI_GetCharsInRxBuf()==0) {} /* wait until we receive data */ while(McuNRF24L01_SPI_RecvChar(&ch)!=ERR_OK) {} /* get data */ #else int res = McuSPI_SendReceiveByte(val, &ch); if (res!=0) { McuLog_fatal("failed SPI send and receive"); } #endif return ch; } /* ** =================================================================== ** Method : SPIWriteReadBuffer (component nRF24L01) ** ** Description : ** This method is internal. It is used by Processor Expert only. ** =================================================================== */ static void SPIWriteReadBuffer(uint8_t *bufOut, uint8_t *bufIn, uint8_t bufSize) { #if McuNRF24L01_USE_SPI_BLOCK_MODE uint16_t snt, rcvd; while(McuNRF24L01_SPI_GetCharsInTxBuf()!=0) {} /* wait until tx is empty */ while(SPI_SendBlock(bufOut, bufSize, &snt)!=ERR_OK) { /* send buffer */ } while(McuNRF24L01_SPI_GetCharsInTxBuf()!=0) {} /* wait until data has been sent */ while(McuNRF24L01_SPI_GetCharsInRxBuf()==0) {} /* wait until we receive data */ while(SPI_RecvBlock(bufIn, bufSize, &rcvd)!=ERR_OK) { /* get data */ } #else uint8_t i; for(i=0;iSPI_INP_BUF_SIZE) { /* not enough dummy buffer */ uint8_t i; for(i=0;i32 ** then the data is not valid. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_ReadNofRxPayload(uint8_t *nof) { *nof = McuNRF24L01_ReadRegister(McuNRF24L01_R_RX_PL_WID); /* read number of RX payload for pipe */ return ERR_OK; } /* ** =================================================================== ** Method : SetStaticPipePayload (component nRF24L01) ** ** Description : ** Specifies the static payload for a pipe. ** Parameters : ** NAME - DESCRIPTION ** pipe - Pipe number, 0 to 5 ** payloadBytes - Number of payload pipes ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_SetStaticPipePayload(uint8_t pipe, uint8_t payloadBytes) { if (pipe > 5) { return ERR_FAULT; /* only pipe 0 to 5 allowed */ } if (payloadBytes>32) { return ERR_FAULT; } McuNRF24L01_WriteRegister(McuNRF24L01_RX_PW_P0+pipe, payloadBytes); /* write number of RX payload for pipe */ return ERR_OK; } /* ** =================================================================== ** Method : EnableDynamicPayloadLength (component nRF24L01) ** ** Description : ** Enables dynamic payload length for the give pipes ** Parameters : ** NAME - DESCRIPTION ** pipeMask - Mask of pipes, with 1 for pipe 0, ** 2 for pipe 1, 4 for pipe 2 and so on. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_EnableDynamicPayloadLength(uint8_t pipeMask) { /* note: dynamic payload requires EN_DPL and ENAA_Px set for the pipe */ if (pipeMask>0x3F) { return ERR_FAULT; /* only pipe 0 to 5 allowed */ } McuNRF24L01_WriteRegister(McuNRF24L01_DYNPD, pipeMask); /* write number of RX payload for pipe */ return ERR_OK; } /* ** =================================================================== ** Method : WriteFeature (component nRF24L01) ** ** Description : ** Writes the FEATURE register ** Parameters : ** NAME - DESCRIPTION ** featureMask - Mask of FEATURE, e.g. ** FEATURE_EN_DPL ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_WriteFeature(uint8_t featureMask) { if (featureMask>(McuNRF24L01_FEATURE_EN_DPL|McuNRF24L01_FEATURE_EN_ACK_PAY|McuNRF24L01_FEATURE_EN_DYN_PAY)) { return ERR_FAULT; /* mismatch of feature mask */ } McuNRF24L01_WriteRegister(McuNRF24L01_FEATURE, featureMask); /* write number of RX payload for pipe */ return ERR_OK; } /* ** =================================================================== ** Method : ReadFeature (component nRF24L01) ** ** Description : ** Reads the FEATURE register ** Parameters : ** NAME - DESCRIPTION ** * featureMask - Pointer to value of ** FEATURE register ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_ReadFeature(uint8_t *featureMask) { *featureMask = McuNRF24L01_ReadRegister(McuNRF24L01_FEATURE); /* read FEATURE register */ return ERR_OK; } /* ** =================================================================== ** Method : ReadObserveTxRegister (component nRF24L01) ** ** Description : ** Reads the OBSERVE_TX register to return the count of loss ** packets and count of retransmitted packets. ** Parameters : ** NAME - DESCRIPTION ** * nofLoss - Pointer to number of lost packets ** * nofRetransmitted - Pointer to ** number of retransmitted packets ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_ReadObserveTxRegister(uint8_t *nofLoss, uint8_t *nofRetransmitted) { uint8_t val; val = McuNRF24L01_ReadRegister(McuNRF24L01_OBSERVE_TX); /* read OBSERVE_TX register */ *nofLoss = (uint8_t)((val&0xF0)>>4); /* high nibble */ *nofRetransmitted = (uint8_t)(val&0x0F); /* high nibble */ return ERR_OK; } /* ** =================================================================== ** Method : ReadReceivedPowerDetector (component nRF24L01) ** ** Description : ** Reads the RPD (Received Power Detector) register. ** Parameters : ** NAME - DESCRIPTION ** * rpd - Pointer to RPD bit. Bit is one for ** received power levels above -64 dBm, zero ** for less than -64 dBm. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_ReadReceivedPowerDetector(uint8_t *rpd) { *rpd = McuNRF24L01_ReadRegister(McuNRF24L01_RPD); /* read RPD register */ return ERR_OK; } /* ** =================================================================== ** Method : ConstantCarrierWave (component nRF24L01) ** ** Description : ** Put the transceiver into contant carrier wave output for ** testing. The output power of a radio is a critical factor ** for achieving wanted range. Output power is also the first ** test ** Parameters : ** NAME - DESCRIPTION ** turnOn - Set to true to start constant ** carrier wave, false to stop it. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_ConstantCarrierWave(bool turnOn) { /* note: RF channel, output power should be set independently */ uint8_t val; if (turnOn) { /* Set PWR_UP = 1 and PRIM_RX = 0 in the CONFIG register. */ McuNRF24L01_WriteRegister(McuNRF24L01_CONFIG, McuNRF24L01_PWR_UP|McuNRF24L01_PRIM_TX); /*lint -save -e522 function lacks side effect */ McuNRF24L01_WAIT_US(1500); /* Wait 1.5ms PWR_UP->standby */ /*lint -restore */ /* In the RF register set: - CONT_WAVE = 1. - PLL_LOCK = 1. - RF_PWR (is set independently) */ val = McuNRF24L01_ReadRegister(McuNRF24L01_RF_SETUP); /* read RF_SETUP register */ val |= McuNRF24L01_RF_SETUP_CONT_WAVE|McuNRF24L01_RF_SETUP_PLL_LOCK; /* set bits */ McuNRF24L01_WriteRegister(McuNRF24L01_RF_SETUP, val); McuNRF24L01_CE_HIGH(); /* CE is high for carrier transmission */ /* CE is kept high as long the carrier is needed */ } else { val = McuNRF24L01_ReadRegister(McuNRF24L01_RF_SETUP); /* read RF_SETUP register */ val &= ~(McuNRF24L01_RF_SETUP_CONT_WAVE|McuNRF24L01_RF_SETUP_PLL_LOCK); /* clear bits */ McuNRF24L01_WriteRegister(McuNRF24L01_RF_SETUP, val); /* write back value */ McuNRF24L01_CE_LOW(); /* pull CE Low to disable transceiver */ } return ERR_OK; } /* ** =================================================================== ** Method : SetOutputPower (component nRF24L01) ** ** Description : ** Sets the output power ** Parameters : ** NAME - DESCRIPTION ** power - Output power in dBm, either 0, -10, -12 ** or -18 ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_SetOutputPower(int8_t power) { uint8_t val; /* get current register value */ val = McuNRF24L01_ReadRegister(McuNRF24L01_RF_SETUP); /* read RF_SETUP register */ val &= ~McuNRF24L01_RF_SETUP_RF_PWR_MASK; /* clear bits */ if (power==-18) { val |= McuNRF24L01_RF_SETUP_RF_PWR_18; } else if (power==-12) { val |= McuNRF24L01_RF_SETUP_RF_PWR_12; } else if (power==-10) { val |= McuNRF24L01_RF_SETUP_RF_PWR_10; } else if (power==0) { val |= McuNRF24L01_RF_SETUP_RF_PWR_0; } else { return ERR_RANGE; } McuNRF24L01_WriteRegister(McuNRF24L01_RF_SETUP, val); return ERR_OK; } /* ** =================================================================== ** Method : GetOutputPower (component nRF24L01) ** ** Description : ** Returns the current output power ** Parameters : ** NAME - DESCRIPTION ** * power - Pointer to where to store the value. ** Returns the output power in dBm ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_GetOutputPower(int8_t *power) { uint8_t val; val = McuNRF24L01_ReadRegister(McuNRF24L01_RF_SETUP); /* read RF_SETUP register */ if ((val&McuNRF24L01_RF_SETUP_RF_PWR_MASK)==McuNRF24L01_RF_SETUP_RF_PWR_18) { *power = -18; } else if ((val&McuNRF24L01_RF_SETUP_RF_PWR_MASK)==McuNRF24L01_RF_SETUP_RF_PWR_12) { *power = -12; } else if ((val&McuNRF24L01_RF_SETUP_RF_PWR_MASK)==McuNRF24L01_RF_SETUP_RF_PWR_10) { *power = -10; } else if ((val&McuNRF24L01_RF_SETUP_RF_PWR_MASK)==McuNRF24L01_RF_SETUP_RF_PWR_0) { *power = 0; } else { return ERR_RANGE; } return ERR_OK; } /* ** =================================================================== ** Method : SetDataRate (component nRF24L01) ** ** Description : ** Sets the data rate ** Parameters : ** NAME - DESCRIPTION ** rate - Data rate, either 250, 1000 or 2000 ** (kbps) ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_SetDataRate(uint16_t rate) { uint8_t val; /* get current register value */ val = McuNRF24L01_ReadRegister(McuNRF24L01_RF_SETUP); /* read RF_SETUP register */ val &= ~McuNRF24L01_RF_SETUP_RF_DR_MASK; /* clear bits */ if (rate==250) { val |= McuNRF24L01_RF_SETUP_RF_DR_250; } else if (rate==1000) { val |= McuNRF24L01_RF_SETUP_RF_DR_1000; } else if (rate==2000) { val |= McuNRF24L01_RF_SETUP_RF_DR_2000; } else { /* illegal parameter */ return ERR_RANGE; } McuNRF24L01_WriteRegister(McuNRF24L01_RF_SETUP, val); return ERR_OK; } /* ** =================================================================== ** Method : GetDataRate (component nRF24L01) ** ** Description : ** Returns the current data rate ** Parameters : ** NAME - DESCRIPTION ** * rate - Pointer to where to store the value. ** Returns the data rate, either 250, 1000 or ** 2000 (kbps) ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_GetDataRate(uint16_t *rate) { uint8_t val; val = McuNRF24L01_ReadRegister(McuNRF24L01_RF_SETUP); /* read RF_SETUP register */ if ((val&McuNRF24L01_RF_SETUP_RF_DR_MASK)==McuNRF24L01_RF_SETUP_RF_DR_250) { *rate = 250; } else if ((val&McuNRF24L01_RF_SETUP_RF_DR_MASK)==McuNRF24L01_RF_SETUP_RF_DR_1000) { *rate = 1000; } else if ((val&McuNRF24L01_RF_SETUP_RF_DR_MASK)==McuNRF24L01_RF_SETUP_RF_DR_2000) { *rate = 2000; } else { return ERR_RANGE; } return ERR_OK; } /* ** =================================================================== ** Method : PollInterrupt (component nRF24L01) ** ** Description : ** If there is no interrupt line available, this method polls ** the device to check if there is an interrupt. If ** Parameters : None ** Returns : Nothing ** =================================================================== */ bool McuNRF24L01_PollInterrupt(void) { /*lint -save -e522 function lacks side effect */ uint8_t status; bool interrupt = false; extern void RADIO_OnInterrupt(void); /* prototype */ status = McuNRF24L01_GetStatus(); if (status&(McuNRF24L01_STATUS_RX_DR|McuNRF24L01_STATUS_TX_DS|McuNRF24L01_STATUS_MAX_RT)) { McuNRF24L01_CE_LOW(); /* pull CE Low to disable transceiver */ RADIO_OnInterrupt(); McuNRF24L01_OnInterrupt(); /* call user event (if enabled)... */ interrupt = true; } return interrupt; /*lint -restore */ } /* ** =================================================================== ** Method : GetFifoStatus (component nRF24L01) ** ** Description : ** Returns the FIFO_STATUS register value ** Parameters : ** NAME - DESCRIPTION ** * status - Pointer to where to store the FIFO ** status value. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_GetFifoStatus(uint8_t *status) { *status = McuNRF24L01_ReadRegister(McuNRF24L01_FIFO_STATUS); /* read FIFO_STATUS register */ return ERR_OK; } /* ** =================================================================== ** Method : SetAddressWidth (component nRF24L01) ** ** Description : ** Sets the address width using the SETUP_AW register ** Parameters : ** NAME - DESCRIPTION ** width - only 3, 4 or 5 is allowed ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_SetAddressWidth(uint8_t width) { if (width==3) { McuNRF24L01_WriteRegister(McuNRF24L01_SETUP_AW, McuNRF24L01_SETUP_AW_3BYTES); } else if (width==4) { McuNRF24L01_WriteRegister(McuNRF24L01_SETUP_AW, McuNRF24L01_SETUP_AW_4BYTES); } else if (width==5) { McuNRF24L01_WriteRegister(McuNRF24L01_SETUP_AW, McuNRF24L01_SETUP_AW_5BYTES); } else { return ERR_FAILED; /* only 3, 4 or 5 allowed */ } return ERR_OK; } /* ** =================================================================== ** Method : GetAddressWidth (component nRF24L01) ** ** Description : ** Returns the address width stored in the SETUP_AW register ** Parameters : ** NAME - DESCRIPTION ** * pAddrWidth - Pointer to where to store ** the value. ** Returns : ** --- - number of address bytes (3, 4 or 5) ** =================================================================== */ uint8_t McuNRF24L01_GetAddressWidth(uint8_t *pAddrWidth) { uint8_t val; val = McuNRF24L01_ReadRegister(McuNRF24L01_SETUP_AW); /* read RF_SETUP_AW register */ if (val==McuNRF24L01_SETUP_AW_3BYTES) { *pAddrWidth = 3; return ERR_OK; } else if (val==McuNRF24L01_SETUP_AW_4BYTES) { *pAddrWidth = 4; return ERR_OK; } else if (val==McuNRF24L01_SETUP_AW_5BYTES) { *pAddrWidth = 5; return ERR_OK; } else { /* failure */ *pAddrWidth = 0; /* illegal value */ return ERR_FAILED; } } /* ** =================================================================== ** Method : SetTxAddress (component nRF24L01) ** ** Description : ** Sets the TX address using the RF_TX_ADDR register. ** Parameters : ** NAME - DESCRIPTION ** * address - Pointer to the buffer with the ** address bytes. ** nofAddressBytes - Number of address ** bytes and size of buffer, typically 5. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_SetTxAddress(uint8_t *address, uint8_t nofAddressBytes) { int i, j; uint8_t swap[5]; /* address is max 5 bytes */ if (nofAddressBytes>=3 && nofAddressBytes<=5) { for(j=0,i=nofAddressBytes-1; i>=0 && j<(int)sizeof(swap); i--,j++) { /* need to send LSB first */ swap[j] = address[i]; } McuNRF24L01_WriteRegisterData(McuNRF24L01_TX_ADDR, &swap[0], nofAddressBytes); return ERR_OK; } else { return ERR_FAILED; /* only 3, 4 or 5 address bytes allowed */ } } /* ** =================================================================== ** Method : GetTxAddress (component nRF24L01) ** ** Description : ** Returns the TX address using the RF_TX_ADDR register. ** Parameters : ** NAME - DESCRIPTION ** * address - Pointer to array where the return ** the address bytes. ** nofAddressBytes - Number of address ** bytes and size of buffer, typically 5. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_GetTxAddress(uint8_t *address, uint8_t nofAddressBytes) { int i, j; uint8_t swap[5]; /* address is max 5 bytes */ if (nofAddressBytes>=3 && nofAddressBytes<=5) { McuNRF24L01_ReadRegisterData(McuNRF24L01_TX_ADDR, swap, nofAddressBytes); for(j=0,i=nofAddressBytes-1; i>=0 && j5) { return ERR_FAILED; /* only pipe 0 to 5 allowed */ } if (!(nofAddressBytes>=3 && nofAddressBytes<=5)) { return ERR_FAILED; /* only 3, 4 or 5 allowed */ } if (pipe==0 || pipe==1) { /* full number of address bytes */ for(j=0,i=nofAddressBytes-1; i>=0 && j<(int)sizeof(swap); i--,j++) { /* need to send LSB first */ swap[j] = address[i]; } McuNRF24L01_WriteRegisterData(McuNRF24L01_RX_ADDR_P0+pipe, &swap[0], nofAddressBytes); } else { /* P2-P5: only last byte */ McuNRF24L01_WriteRegisterData(McuNRF24L01_RX_ADDR_P0+pipe, &address[nofAddressBytes-1], 1); } return ERR_OK; } /* ** =================================================================== ** Method : GetRxAddress (component nRF24L01) ** ** Description : ** Returns the RX address using the RF_RX_ADDR_Px register. ** Parameters : ** NAME - DESCRIPTION ** pipe - pipe number (0-5) ** * address - Pointer to array where the return ** the address bytes. ** nofAddressBytes - Number of address ** bytes and size of buffer, typically 5. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuNRF24L01_GetRxAddress(uint8_t pipe, uint8_t *address, uint8_t nofAddressBytes) { int i, j; uint8_t swap[5]; /* address is max 5 bytes */ if (pipe>5) { return ERR_FAILED; /* only pipe 0 to 5 allowed */ } if (!(nofAddressBytes>=3 && nofAddressBytes<=5)) { return ERR_FAILED; /* only 3, 4 or 5 allowed */ } for(i=0; i=2 && pipe<=5) { McuNRF24L01_ReadRegisterData(McuNRF24L01_RX_ADDR_P1, swap, nofAddressBytes); /* read base address from P1 */ McuNRF24L01_ReadRegisterData(McuNRF24L01_RX_ADDR_P0+pipe, &swap[0], 1); /* pipe 2-5 only have one address byte */ } /* swap back into correct order */ for(j=0,i=nofAddressBytes-1; i>=0 && j<(int)nofAddressBytes; i--,j++) { address[j] = swap[i]; } return ERR_OK; } static uint8_t PrintHelp(const McuShell_StdIOType *io) { McuShell_SendHelpStr((unsigned char*)"McuNRF", (unsigned char*)"Group of nRF24L01+ commands\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Shows help or status\r\n", io->stdOut); return ERR_OK; } static uint8_t PrintStatus(const McuShell_StdIOType *io) { uint8_t buf[64]; McuShell_SendStatusStr((unsigned char*)"McuNRF", (unsigned char*)"nRF24L01+ status\r\n", io->stdOut); McuGPIO_GetPinStatusString(cePin, buf, sizeof(buf)); McuUtility_strcat(buf, sizeof(buf), (unsigned char*)"\r\n"); McuShell_SendStatusStr((const unsigned char*)" CE", (const unsigned char*)buf, io->stdOut); McuGPIO_GetPinStatusString(csnPin, buf, sizeof(buf)); McuUtility_strcat(buf, sizeof(buf), (unsigned char*)"\r\n"); McuShell_SendStatusStr((const unsigned char*)" CSN", (const unsigned char*)buf, io->stdOut); return ERR_OK; } uint8_t McuNRF24L01_ParseCommand(const unsigned char *cmd, bool *handled, const McuShell_StdIOType *io) { uint8_t res = ERR_OK; if (McuUtility_strcmp((char*)cmd, (char*)McuShell_CMD_HELP)==0 || McuUtility_strcmp((char*)cmd, (char*)"McuNRF help")==0) { *handled = TRUE; return PrintHelp(io); } else if (McuUtility_strcmp((char*)cmd, (char*)McuShell_CMD_STATUS)==0 || McuUtility_strcmp((char*)cmd, (char*)"McuNRF status")==0) { *handled = TRUE; return PrintStatus(io); } return res; } #endif /* McuNRF24L01_CONFIG_IS_ENABLED */ /* END McuNRF24L01. */ /*! ** @} */