/* * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad * Copyright (C) 2013-2019 Sensnology AB * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * Based on maniacbug's RF24 library, copyright (C) 2011 J. Coliz * RF24 driver refactored and optimized for speed and size, copyright (C) 2017 Olivier Mauti * * Definitions for Nordic nRF24L01+ radios: * https://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01P * */ /** * @file RF24.h * * @defgroup RF24grp RF24 * @ingroup internals * @{ * * RF24 driver-related log messages, format: [!]SYSTEM:[SUB SYSTEM:]MESSAGE * - [!] Exclamation mark is prepended in case of error * * |E| SYS | SUB | Message | Comment * |-|------|------|----------------------|--------------------------------------------------------------------- * | | RF24 | INIT | PIN,CE=%%d,CS=%%d | Initialise RF24 radio, pin configuration: chip enable (CE), chip select (CS) * |!| RF24 | INIT | SANCHK FAIL | Sanity check failed, check wiring or replace module * | | RF24 | SPP | PCT=%%d,TX LEVEL=%%d | Set TX level, input TX percent (PCT) * | | RF24 | RBR | REG=%%d,VAL=%%d | Read register (REG), value=(VAL) * | | RF24 | WBR | REG=%%d,VAL=%%d | Write register (REG), value=(VAL) * | | RF24 | FRX | | Flush RX buffer * | | RF24 | FTX | | Flush TX buffer * | | RF24 | OWP | RCPT=%%d | Open writing pipe, recipient=(RCPT) * | | RF24 | STL | | Start listening * | | RF24 | SPL | | Stop listening * | | RF24 | SLP | | Set radio to sleep * | | RF24 | SBY | | Set radio to standby * | | RF24 | TXM | TO=%%d,LEN=%%d | Transmit message to=(TO), length=(LEN) * |!| RF24 | TXM | MAX_RT | Max TX retries, no ACK received * |!| RF24 | GDP | PYL INV | Invalid payload size * | | RF24 | RXM | LEN=%%d | Read message, length=(LEN) * | | RF24 | STX | LEVEL=%%d | Set TX level, level=(LEVEL) * */ #ifndef __RF24_H__ #define __RF24_H__ #include "RF24registers.h" #if !defined(RF24_SPI) #define RF24_SPI hwSPI //!< default SPI #endif #if defined(ARDUINO_ARCH_AVR) #define DEFAULT_RF24_CE_PIN (9) //!< DEFAULT_RF24_CE_PIN #elif defined(ARDUINO_ARCH_ESP8266) #define DEFAULT_RF24_CE_PIN (4) //!< DEFAULT_RF24_CE_PIN #elif defined(ARDUINO_ARCH_ESP32) #define DEFAULT_RF24_CE_PIN (17) //!< DEFAULT_RF24_CE_PIN #elif defined(ARDUINO_ARCH_SAMD) #define DEFAULT_RF24_CE_PIN (27) //!< DEFAULT_RF24_CE_PIN #elif defined(LINUX_ARCH_RASPBERRYPI) #define DEFAULT_RF24_CE_PIN (22) //!< DEFAULT_RF24_CE_PIN //#define DEFAULT_RF24_CS_PIN (24) //!< DEFAULT_RF24_CS_PIN #elif defined(ARDUINO_ARCH_STM32F1) #define DEFAULT_RF24_CE_PIN (PB0) //!< DEFAULT_RF24_CE_PIN #elif defined(TEENSYDUINO) #define DEFAULT_RF24_CE_PIN (9) //!< DEFAULT_RF24_CE_PIN #else #define DEFAULT_RF24_CE_PIN (9) //!< DEFAULT_RF24_CE_PIN #endif #define DEFAULT_RF24_CS_PIN (SS) //!< DEFAULT_RF24_CS_PIN #define LOCAL static //!< static // SPI settings #define RF24_SPI_DATA_ORDER MSBFIRST //!< RF24_SPI_DATA_ORDER #define RF24_SPI_DATA_MODE SPI_MODE0 //!< RF24_SPI_DATA_MODE #define RF24_BROADCAST_ADDRESS (255u) //!< RF24_BROADCAST_ADDRESS // verify RF24 IRQ defs #if defined(MY_RX_MESSAGE_BUFFER_FEATURE) #if !defined(MY_RF24_IRQ_PIN) #error Message buffering feature requires MY_RF24_IRQ_PIN to be defined! #endif // SoftSPI does not support usingInterrupt() #ifdef MY_SOFTSPI #error RF24 IRQ usage cannot be used with Soft SPI #endif // ESP8266 does not support usingInterrupt() #ifdef ARDUINO_ARCH_ESP8266 #error RF24 IRQ usage cannot be used with ESP8266 #endif #ifndef SPI_HAS_TRANSACTION #error RF24 IRQ usage requires transactional SPI support #endif #else #ifdef MY_RX_MESSAGE_BUFFER_SIZE #error Receive message buffering requires RF24 IRQ usage #endif #endif // RF24 settings #if defined(MY_RX_MESSAGE_BUFFER_FEATURE) #define RF24_CONFIGURATION (uint8_t) ((RF24_CRC_16 << 2) | (1 << RF24_MASK_TX_DS) | (1 << RF24_MASK_MAX_RT)) //!< MY_RF24_CONFIGURATION #else #define RF24_CONFIGURATION (uint8_t) (RF24_CRC_16 << 2) //!< RF24_CONFIGURATION #endif #define RF24_FEATURE (uint8_t)( _BV(RF24_EN_DPL)) //!< RF24_FEATURE #define RF24_RF_SETUP (uint8_t)(( ((MY_RF24_DATARATE & 0b10 ) << 4) | ((MY_RF24_DATARATE & 0b01 ) << 3) | (MY_RF24_PA_LEVEL << 1) ) + 1) //!< RF24_RF_SETUP, +1 for Si24R1 and LNA // powerup delay #define RF24_POWERUP_DELAY_MS (100u) //!< Power up delay, allow VCC to settle, transport to become fully operational // pipes #define RF24_BROADCAST_PIPE (1u) //!< RF24_BROADCAST_PIPE #define RF24_NODE_PIPE (0u) //!< RF24_NODE_PIPE // functions /** * @brief RF24_csn * @param level */ LOCAL void RF24_csn(const bool level); /** * @brief RF24_ce * @param level */ LOCAL void RF24_ce(const bool level); /** * @brief RF24_spiMultiByteTransfer * @param cmd * @param buf * @param len * @param readMode * @return */ LOCAL uint8_t RF24_spiMultiByteTransfer(const uint8_t cmd, uint8_t *buf, const uint8_t len, const bool readMode); /** * @brief RF24_spiByteTransfer * @param cmd * @return */ LOCAL uint8_t RF24_spiByteTransfer(const uint8_t cmd); /** * @brief RF24_RAW_readByteRegister * @param cmd * @return */ LOCAL uint8_t RF24_RAW_readByteRegister(const uint8_t cmd); /** * @brief RF24_RAW_writeByteRegister * @param cmd * @param value * @return */ LOCAL uint8_t RF24_RAW_writeByteRegister(const uint8_t cmd, const uint8_t value); // helper macros #define RF24_readByteRegister(__reg) RF24_RAW_readByteRegister(RF24_CMD_READ_REGISTER | (RF24_REGISTER_MASK & (__reg))) //!< RF24_readByteRegister #define RF24_writeByteRegister(__reg,__value) RF24_RAW_writeByteRegister(RF24_CMD_WRITE_REGISTER | (RF24_REGISTER_MASK & (__reg)), __value) //!< RF24_writeByteRegister #define RF24_writeMultiByteRegister(__reg,__buf,__len) RF24_spiMultiByteTransfer(RF24_CMD_WRITE_REGISTER | (RF24_REGISTER_MASK & (__reg)),(uint8_t *)__buf, __len,false) //!< RF24_writeMultiByteRegister /** * @brief RF24_flushRX */ LOCAL void RF24_flushRX(void); /** * @brief RF24_flushTX */ LOCAL void RF24_flushTX(void); /** * @brief RF24_getStatus * @return */ LOCAL uint8_t RF24_getStatus(void); /** * @brief RF24_getFIFOStatus * @return */ LOCAL uint8_t RF24_getFIFOStatus(void) __attribute__((unused)); /** * @brief RF24_openWritingPipe * @param recipient */ LOCAL void RF24_openWritingPipe(const uint8_t recipient); /** * @brief RF24_startListening */ LOCAL void RF24_startListening(void); /** * @brief RF24_stopListening */ LOCAL void RF24_stopListening(void); /** * @brief RF24_sleep */ LOCAL void RF24_sleep(void); /** * @brief RF24_standBy */ LOCAL void RF24_standBy(void); /** * @brief RF24_powerDown */ LOCAL void RF24_powerDown(void); /** * @brief RF24_powerUp */ LOCAL void RF24_powerUp(void); /** * @brief RF24_sendMessage * @param recipient * @param buf * @param len * @param noACK set True if no ACK is required * @return */ LOCAL bool RF24_sendMessage(const uint8_t recipient, const void *buf, const uint8_t len, const bool noACK = false); /** * @brief RF24_getDynamicPayloadSize * @return */ LOCAL uint8_t RF24_getDynamicPayloadSize(void); /** * @brief RF24_isDataAvailable * @return */ LOCAL bool RF24_isDataAvailable(void); /** * @brief RF24_readMessage * @return */ LOCAL uint8_t RF24_readMessage(void *buf); /** * @brief RF24_setNodeAddress * @param address */ LOCAL void RF24_setNodeAddress(const uint8_t address); /** * @brief RF24_getNodeID * @return */ LOCAL uint8_t RF24_getNodeID(void); /** * @brief RF24_sanityCheck * @return */ LOCAL bool RF24_sanityCheck(void); /** * @brief RF24_initialize * @return */ LOCAL bool RF24_initialize(void); /** * @brief RF24_setChannel * @param channel */ LOCAL void RF24_setChannel(const uint8_t channel); /** * @brief RF24_setRetries * @param retransmitDelay * @param retransmitCount */ LOCAL void RF24_setRetries(const uint8_t retransmitDelay, const uint8_t retransmitCount); /** * @brief RF24_setAddressWidth * @param addressWidth */ LOCAL void RF24_setAddressWidth(const uint8_t addressWidth); /** * @brief RF24_setRFSetup * @param RFsetup */ LOCAL void RF24_setRFSetup(const uint8_t RFsetup); /** * @brief RF24_setFeature * @param feature */ LOCAL void RF24_setFeature(const uint8_t feature); /** * @brief RF24_getFeature * @return */ LOCAL uint8_t RF24_getFeature(void); /** * @brief RF24_setPipe * @param pipe */ LOCAL void RF24_setPipe(const uint8_t pipe); /** * @brief RF24_setAutoACK * @param pipe */ LOCAL void RF24_setAutoACK(const uint8_t pipe); /** * @brief RF24_setDynamicPayload * @param pipe */ LOCAL void RF24_setDynamicPayload(const uint8_t pipe); /** * @brief RF24_setRFConfiguration * @param configuration */ LOCAL void RF24_setRFConfiguration(const uint8_t configuration); /** * @brief RF24_setPipeAddress * @param pipe * @param address * @param addressWidth */ LOCAL void RF24_setPipeAddress(const uint8_t pipe, uint8_t *address, const uint8_t addressWidth); /** * @brief RF24_setPipeLSB * @param pipe * @param LSB */ LOCAL void RF24_setPipeLSB(const uint8_t pipe, const uint8_t LSB); /** * @brief RF24_getObserveTX * @return */ LOCAL uint8_t RF24_getObserveTX(void); /** * @brief RF24_setStatus * @param status * @return status byte before setting new status */ LOCAL uint8_t RF24_setStatus(const uint8_t status); /** * @brief RF24_enableFeatures */ LOCAL void RF24_enableFeatures(void); /** * @brief RF24_getTxPowerPercent * @return */ LOCAL uint8_t RF24_getTxPowerPercent(void); /** * @brief RF24_getTxPowerLevel * @return */ LOCAL int16_t RF24_getTxPowerLevel(void); /** * @brief RF24_setTxPowerPercent * @param newPowerPercent * @return */ LOCAL bool RF24_setTxPowerPercent(const uint8_t newPowerPercent); /** * @brief RF24_getSendingRSSI * @return Pseudo-RSSI based on ARC register */ LOCAL int16_t RF24_getSendingRSSI(void); /** * @brief Generate a constant carrier wave at active channel & transmit power (for testing only). */ LOCAL void RF24_enableConstantCarrierWave(void) __attribute__((unused)); /** * @brief Stop generating a constant carrier wave (for testing only). */ LOCAL void RF24_disableConstantCarrierWave(void) __attribute__((unused)); /** * @brief Retrieve latched RPD power level, in receive mode (for testing, nRF24L01+ only). * @return True when power level >-64dBm for more than 40us. */ LOCAL bool RF24_getReceivedPowerDetector(void) __attribute__((unused)); #if defined(MY_RX_MESSAGE_BUFFER_FEATURE) /** * @brief Callback type */ typedef void (*RF24_receiveCallbackType)(void); /** * @brief RF24_registerReceiveCallback * Register a callback, which will be called (from interrupt context) for every message received. * @note When a callback is registered, it _must_ retrieve the message from the nRF24 * by calling RF24_readMessage(). Otherwise the interrupt will not get deasserted * and message reception will stop. * @param cb */ LOCAL void RF24_registerReceiveCallback(RF24_receiveCallbackType cb); #endif #endif // __RF24_H__ /** @}*/