Files
MSE-SoftwEng/pico-sensor/McuLib/RNet/McuNRF24L01.c
2025-05-06 13:07:01 +00:00

1502 lines
53 KiB
C

/* ###################################################################
** 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;i<bufSize;i++) {
bufIn[i] = SPIWriteRead(bufOut[i]);
}
#endif
}
/*
** ===================================================================
** Method : SPIWriteBuffer (component nRF24L01)
**
** Description :
** This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void SPIWriteBuffer(uint8_t *bufOut, uint8_t bufSize)
{
#if McuNRF24L01_USE_SPI_BLOCK_MODE
uint16_t snt, rcvd;
static uint8_t dummyBuf[SPI_INP_BUF_SIZE];
if (bufSize>SPI_INP_BUF_SIZE) { /* not enough dummy buffer */
uint8_t i;
for(i=0;i<bufSize;i++) {
(void)SPIWriteRead(bufOut[i]);
}
} else {
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_SPI.RecvBlock(dummyBuf, bufSize, &rcvd)!=ERR_OK) {
/* get data */
}
}
#else
uint8_t i;
for(i=0;i<bufSize;i++) {
(void)SPIWriteRead(bufOut[i]);
}
#endif
}
/*
** ===================================================================
** Method : Deinit (component nRF24L01)
**
** Description :
** Driver deinitialization
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_Deinit(void)
{
#if McuNRF24L01_CONFIG_USE_MUTEX
vQueueUnregisterQueue(McuNRF24L01_Mutex);
vSemaphoreDelete(McuNRF24L01_Mutex);
McuNRF24L01_Mutex = NULL;
#endif
}
/*
** ===================================================================
** Method : Init (component nRF24L01)
**
** Description :
** Initialization method
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
static void InitCS(void) {
McuGPIO_Config_t config;
McuNRF24L01_CONFIG_CE_CSN_PIN_PRE_INIT();
McuGPIO_GetDefaultConfig(&config);
#if McuLib_CONFIG_CPU_IS_ESP32
config.hw.pin = McuNRF24L01_CONFIG_CE_PIN_NUMBER;
#elif McuLib_CONFIG_CPU_IS_RPxxxx
config.hw.pin = McuNRF24L01_CONFIG_CE_PIN_NUMBER;
#else
config.hw.gpio = McuNRF24L01_CONFIG_CE_PIN_GPIO;
config.hw.port = McuNRF24L01_CONFIG_CE_PIN_PORT;
config.hw.pin = McuNRF24L01_CONFIG_CE_PIN_NUMBER;
#endif
config.isInput = false;
config.isHighOnInit = false; /* CE is HIGH active */
cePin = McuGPIO_InitGPIO(&config);
if (cePin==NULL) {
McuLog_fatal("failed initializing SPI CE pin");
for(;;) {} /* error */
}
#if McuLib_CONFIG_CPU_IS_ESP32
config.hw.pin = McuNRF24L01_CONFIG_CSN_PIN_NUMBER;
#elif McuLib_CONFIG_CPU_IS_RPxxxx
config.hw.pin = McuNRF24L01_CONFIG_CSN_PIN_NUMBER;
#else
config.hw.gpio = McuNRF24L01_CONFIG_CSN_PIN_GPIO;
config.hw.port = McuNRF24L01_CONFIG_CSN_PIN_PORT;
config.hw.pin = McuNRF24L01_CONFIG_CSN_PIN_NUMBER;
#endif
config.isInput = false;
config.isHighOnInit = true; /* CSN is LOW active */
csnPin = McuGPIO_InitGPIO(&config);
if (csnPin==NULL) {
McuLog_fatal("failed initializing SPI CSN pin");
for(;;) {} /* error */
}
}
void McuNRF24L01_Init(void)
{
#if McuNRF24L01_CONFIG_USE_MUTEX
#if configSUPPORT_STATIC_ALLOCATION
static StaticSemaphore_t xMutexBuffer;
#endif
#if configSUPPORT_STATIC_ALLOCATION
McuNRF24L01_Mutex = xSemaphoreCreateRecursiveMutexStatic(&xMutexBuffer);
#else
McuNRF24L01_Mutex = xSemaphoreCreateRecursiveMutex();
#endif
if (McuNRF24L01_Mutex==NULL) { /* semaphore creation failed */
for(;;) {} /* error, not enough memory? */
}
vQueueAddToRegistry(McuNRF24L01_Mutex, "McuNRF24L01_Mutex");
#endif
InitCS();
McuNRF24L01_CE_LOW(); /* CE high: do not send or receive data */
McuNRF24L01_CSN_HIGH(); /* CSN low: not sending commands to the device */
McuNRF24L01_ConfigureSPI(); /* set up SPI bus */
}
/*
** ===================================================================
** Method : WriteRegister (component nRF24L01)
**
** Description :
** Write a register value to the transceiver
** Parameters :
** NAME - DESCRIPTION
** reg - Register address to write
** val - Value to write
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_WriteRegister(uint8_t reg, uint8_t val)
{
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreTakeRecursive(McuNRF24L01_Mutex, portMAX_DELAY);
#endif
#if McuNRF24L01_CONFIG_USE_ON_ACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_ACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_SWITCH_BUS
McuNRF24L01_ConfigureSPI(); /* change bus speed */
#endif
McuNRF24L01_CSN_LOW(); /* initiate command sequence */
(void)SPIWriteRead(McuNRF24L01_W_REGISTER|reg); /* write register command */
(void)SPIWriteRead(val); /* write value */
McuNRF24L01_CSN_HIGH(); /* end command sequence */
#if McuNRF24L01_CONFIG_USE_ON_DEACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_DEACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreGiveRecursive(McuNRF24L01_Mutex);
#endif
/*lint -save -e522 function lacks side-effects */
McuNRF24L01_WAIT_US(10); /* insert a delay until next command */
/*lint -restore */
}
/*
** ===================================================================
** Method : ReadRegister (component nRF24L01)
**
** Description :
** Reads a register from the transceiver
** Parameters :
** NAME - DESCRIPTION
** reg - Register address
** Returns :
** --- - value read
** ===================================================================
*/
uint8_t McuNRF24L01_ReadRegister(uint8_t reg)
{
uint8_t val;
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreTakeRecursive(McuNRF24L01_Mutex, portMAX_DELAY);
#endif
#if McuNRF24L01_CONFIG_USE_ON_ACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_ACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_SWITCH_BUS
McuNRF24L01_ConfigureSPI(); /* change bus speed */
#endif
McuNRF24L01_CSN_LOW();
(void)SPIWriteRead(reg);
val = SPIWriteRead(0); /* write dummy */
McuNRF24L01_CSN_HIGH();
#if McuNRF24L01_CONFIG_USE_ON_DEACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_DEACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreGiveRecursive(McuNRF24L01_Mutex);
#endif
/*lint -save -e522 function lacks side-effects */
McuNRF24L01_WAIT_US(10);
/*lint -restore */
return val;
}
/*
** ===================================================================
** Method : ReadRegisterData (component nRF24L01)
**
** Description :
** Read multiple bytes from the bus.
** Parameters :
** NAME - DESCRIPTION
** reg - Register address
** * buf - Pointer to buffer where to store the values
** bufSize - Size of the destination buffer
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_ReadRegisterData(uint8_t reg, uint8_t *buf, uint8_t bufSize)
{
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreTakeRecursive(McuNRF24L01_Mutex, portMAX_DELAY);
#endif
#if McuNRF24L01_CONFIG_USE_ON_ACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_ACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_SWITCH_BUS
McuNRF24L01_ConfigureSPI(); /* change bus speed */
#endif
McuNRF24L01_CSN_LOW();
(void)SPIWriteRead(McuNRF24L01_R_REGISTER|reg);
SPIWriteReadBuffer(buf, buf, bufSize);
McuNRF24L01_CSN_HIGH();
#if McuNRF24L01_CONFIG_USE_ON_DEACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_DEACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreGiveRecursive(McuNRF24L01_Mutex);
#endif
/*lint -save -e522 function lacks side-effects */
McuNRF24L01_WAIT_US(10);
/*lint -restore */
}
/*
** ===================================================================
** Method : WriteRegisterData (component nRF24L01)
**
** Description :
** Write multiple bytes to the bus.
** Parameters :
** NAME - DESCRIPTION
** reg - Register address
** * buf - Pointer to data buffer to write
** bufSize - Size of buffer in bytes
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_WriteRegisterData(uint8_t reg, uint8_t *buf, uint8_t bufSize)
{
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreTakeRecursive(McuNRF24L01_Mutex, portMAX_DELAY);
#endif
#if McuNRF24L01_CONFIG_USE_ON_ACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_ACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_SWITCH_BUS
McuNRF24L01_ConfigureSPI(); /* change bus speed */
#endif
McuNRF24L01_CSN_LOW();
(void)SPIWriteRead(McuNRF24L01_W_REGISTER|reg); /* not masking registers as it would conflict with McuNRF24L01_W_TX_PAYLOAD */
SPIWriteBuffer(buf, bufSize);
McuNRF24L01_CSN_HIGH();
#if McuNRF24L01_CONFIG_USE_ON_DEACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_DEACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreGiveRecursive(McuNRF24L01_Mutex);
#endif
/*lint -save -e522 function lacks side-effects */
McuNRF24L01_WAIT_US(10);
/*lint -restore */
}
/*
** ===================================================================
** Method : WriteRead (component nRF24L01)
**
** Description :
** Writes a byte and reads back one byte
** Parameters :
** NAME - DESCRIPTION
** val - Value to write to the bus
** Returns :
** --- - Value read from the bus
** ===================================================================
*/
uint8_t McuNRF24L01_WriteRead(uint8_t val)
{
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreTakeRecursive(McuNRF24L01_Mutex, portMAX_DELAY);
#endif
#if McuNRF24L01_CONFIG_USE_ON_ACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_ACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_SWITCH_BUS
McuNRF24L01_ConfigureSPI(); /* change bus speed */
#endif
McuNRF24L01_CSN_LOW();
val = SPIWriteRead(val);
McuNRF24L01_CSN_HIGH();
#if McuNRF24L01_CONFIG_USE_ON_DEACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_DEACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreGiveRecursive(McuNRF24L01_Mutex);
#endif
/*lint -save -e522 function lacks side-effects */
McuNRF24L01_WAIT_US(10);
/*lint -restore */
return val;
}
/*
** ===================================================================
** Method : Write (component nRF24L01)
**
** Description :
** Writes a byte to the bus, without returning the byte read.
** Parameters :
** NAME - DESCRIPTION
** val - Value to write
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_Write(uint8_t val)
{
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreTakeRecursive(McuNRF24L01_Mutex, portMAX_DELAY);
#endif
#if McuNRF24L01_CONFIG_USE_ON_ACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_ACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_SWITCH_BUS
McuNRF24L01_ConfigureSPI(); /* change bus speed */
#endif
McuNRF24L01_CSN_LOW();
(void)SPIWriteRead(val);
McuNRF24L01_CSN_HIGH();
#if McuNRF24L01_CONFIG_USE_ON_DEACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_DEACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreGiveRecursive(McuNRF24L01_Mutex);
#endif
/*lint -save -e522 function lacks side-effects */
McuNRF24L01_WAIT_US(10);
/*lint -restore */
}
/*
** ===================================================================
** Method : GetStatus (component nRF24L01)
**
** Description :
** Returns the device status byte
** Parameters : None
** Returns :
** --- - status byte
** ===================================================================
*/
uint8_t McuNRF24L01_GetStatus(void)
{
return McuNRF24L01_WriteRead(McuNRF24L01_NOP);
}
/*
** ===================================================================
** Method : ResetStatusIRQ (component nRF24L01)
**
** Description :
** Reset the given flags mask of status bits
** Parameters :
** NAME - DESCRIPTION
** flags - Flags, one or more of
** RF24_STATUS_RX_DR, RF24_STATUS_TX_DS,
** RF24_STATUS_MAX_RT
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_ResetStatusIRQ(uint8_t flags)
{
McuNRF24L01_WriteRegister(McuNRF24L01_STATUS, flags); /* reset all IRQ in status register */
}
/*
** ===================================================================
** Method : GetStatusClrIRQ (component nRF24L01)
**
** Description :
** Returns the device status byte and clears any IRQ bits in
** the status register.
** Parameters : None
** Returns :
** --- - status byte
** ===================================================================
*/
uint8_t McuNRF24L01_GetStatusClrIRQ(void)
{
uint8_t status;
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreTakeRecursive(McuNRF24L01_Mutex, portMAX_DELAY);
#endif
#if McuNRF24L01_CONFIG_USE_ON_ACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_ACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_SWITCH_BUS
McuNRF24L01_ConfigureSPI(); /* change bus speed */
#endif
McuNRF24L01_CSN_LOW(); /* initiate command sequence */
status = SPIWriteRead(McuNRF24L01_W_REGISTER|McuNRF24L01_STATUS); /* get status */
(void)SPIWriteRead(status&(McuNRF24L01_STATUS_RX_DR|McuNRF24L01_STATUS_TX_DS|McuNRF24L01_STATUS_MAX_RT)); /* reset IRQ Bits */
McuNRF24L01_CSN_HIGH(); /* end command sequence */
#if McuNRF24L01_CONFIG_USE_ON_DEACTIVATE_CALLBACK
McuNRF24L01_CONFIG_ON_DEACTIVATE_CALLBACK(); /* call user event */
#endif
#if McuNRF24L01_CONFIG_USE_MUTEX
(void)xSemaphoreGiveRecursive(McuNRF24L01_Mutex);
#endif
/*lint -save -e522 function lacks side-effects */
McuNRF24L01_WAIT_US(10); /* insert a delay until next command */
/*lint -restore */
return status;
}
/*
** ===================================================================
** Method : TxPayload (component nRF24L01)
**
** Description :
** Send the payload to the Tx FIFO and send it
** Parameters :
** NAME - DESCRIPTION
** * payload - Pointer to buffer with payload to
** send
** payloadSize - Size of payload buffer
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_TxPayload(uint8_t *payload, uint8_t payloadSize)
{
McuNRF24L01_Write(McuNRF24L01_FLUSH_TX); /* flush old data */
McuNRF24L01_WriteRegisterData(McuNRF24L01_W_TX_PAYLOAD, payload, payloadSize); /* write payload */
McuNRF24L01_CE_HIGH(); /* start transmission */
/*lint -save -e522 function lacks side effect */
McuNRF24L01_WAIT_US(15); /* keep signal high for 15 micro-seconds */
/*lint -restore */
McuNRF24L01_CE_LOW(); /* back to normal */
}
void McuNRF24L01_TxPayloadNoAck(uint8_t *payload, uint8_t payloadSize)
{
McuNRF24L01_Write(McuNRF24L01_FLUSH_TX); /* flush old data */
McuNRF24L01_WriteRegisterData(McuNRF24L01_W_TX_PAYLOAD_NO_ACK, payload, payloadSize); /* write payload */
McuNRF24L01_CE_HIGH(); /* start transmission */
/*lint -save -e522 function lacks side effect */
McuNRF24L01_WAIT_US(15); /* keep signal high for 15 micro-seconds */
/*lint -restore */
McuNRF24L01_CE_LOW(); /* back to normal */
}
/*
** ===================================================================
** Method : RxPayload (component nRF24L01)
**
** Description :
** Receive the Rx payload from the FIFO and stores it in a
** buffer.
** Parameters :
** NAME - DESCRIPTION
** * payload - Pointer to the payload buffer
** payloadSize - Size of the payload buffer
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_RxPayload(uint8_t *payload, uint8_t payloadSize)
{
McuNRF24L01_CE_LOW(); /* need to disable rx mode during reading RX data */
McuNRF24L01_ReadRegisterData(McuNRF24L01_R_RX_PAYLOAD, payload, payloadSize); /* rx payload */
McuNRF24L01_CE_HIGH(); /* re-enable rx mode */
}
/*
** ===================================================================
** Method : StopRxTx (component nRF24L01)
**
** Description :
** Stops sending or receiving (sets CE pin to LOW).
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_StopRxTx(void)
{
McuNRF24L01_CE_LOW(); /* disable RX or TX with pulling CE LOW */
}
/*
** ===================================================================
** Method : StartRxTx (component nRF24L01)
**
** Description :
** Starts sending or receiving (sets CE pin to HIGH).
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
void McuNRF24L01_StartRxTx(void)
{
McuNRF24L01_CE_HIGH(); /* enabling RX or TX with pulling CE HIGH */
}
/*
** ===================================================================
** Method : SetChannel (component nRF24L01)
**
** Description :
** Sets the radio channel (RF_CH register).
** Parameters :
** NAME - DESCRIPTION
** channel - Channel number, valid channel
** numbers are 0x0 to 0x7F
** Returns :
** --- - Error code
** ===================================================================
*/
uint8_t McuNRF24L01_SetChannel(uint8_t channel)
{
McuNRF24L01_WriteRegister(McuNRF24L01_RF_CH, channel&0x7F); /* set channel */
/* need to flush data after channel change */
McuNRF24L01_Write(McuNRF24L01_FLUSH_RX); /* flush old data */
McuNRF24L01_Write(McuNRF24L01_FLUSH_TX); /* flush old data */
return ERR_OK;
}
/*
** ===================================================================
** Method : GetChannel (component nRF24L01)
**
** Description :
** Returns the radio channel (RF_CH register).
** Parameters :
** NAME - DESCRIPTION
** * channel - Pointer to where to store the
** channel number.
** Returns :
** --- - Error code
** ===================================================================
*/
uint8_t McuNRF24L01_GetChannel(uint8_t *channel)
{
*channel = McuNRF24L01_ReadRegister(McuNRF24L01_RF_CH); /* read channel */
return ERR_OK;
}
/*
** ===================================================================
** Method : EnableAutoAck (component nRF24L01)
**
** Description :
** Enables Auto-Acknowledgment for the given pipe(s) (RF_EN_AA
** register).
** Parameters :
** NAME - DESCRIPTION
** pipes - mask of pipes to be enabled (ENAA_P0
** to ENAA_P5)
** Returns :
** --- - Error code
** ===================================================================
*/
uint8_t McuNRF24L01_EnableAutoAck(uint8_t pipes)
{
McuNRF24L01_WriteRegister(McuNRF24L01_EN_AA, pipes&McuNRF24L01_EN_AA_ENAA_ALL); /* enable auto acknowledge for the given pipes */
return ERR_OK;
}
/*
** ===================================================================
** Method : ReadNofRxPayload (component nRF24L01)
**
** Description :
** Returns the number of received payload bytes for the top
** R_RX_PAYLOAD in the RX FIFO
** Parameters :
** NAME - DESCRIPTION
** * nof - Pointer to where to store the number of
** bytes. A return value of 0 means that the
** pipe is not used, and if the value is >32
** 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 && j<nofAddressBytes; i--,j++) {
address[j] = swap[i];
}
return ERR_OK;
} else {
return ERR_FAILED; /* only 3, 4 or 5 address bytes allowed */
}
}
/*
** ===================================================================
** Method : SetRxAddress (component nRF24L01)
**
** Description :
** Set the TX 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_SetRxAddress(uint8_t pipe, uint8_t *address, uint8_t nofAddressBytes)
{
uint8_t swap[5]; /* address is max 5 bytes */
int i, j;
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 */
}
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<nofAddressBytes; i++) {
swap[i] = 0; /* init */
}
if (pipe==0 || pipe==1) { /* full number of address bytes */
McuNRF24L01_ReadRegisterData(McuNRF24L01_RX_ADDR_P0+pipe, swap, nofAddressBytes);
} else if (pipe>=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. */
/*!
** @}
*/