1502 lines
53 KiB
C
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. */
|
|
|
|
/*!
|
|
** @}
|
|
*/
|