#pragma once #include #include #include #ifdef __cplusplus extern "C" { #endif #define R_REGISTER 0x00 #define W_REGISTER 0x20 #define REGISTER_MASK 0x1F #define ACTIVATE 0x50 #define R_RX_PL_WID 0x60 #define R_RX_PAYLOAD 0x61 #define W_TX_PAYLOAD 0xA0 #define W_TX_PAYLOAD_NOACK 0xB0 #define W_ACK_PAYLOAD 0xA8 #define FLUSH_TX 0xE1 #define FLUSH_RX 0xE2 #define REUSE_TX_PL 0xE3 #define RF24_NOP 0xFF #define REG_CONFIG 0x00 #define REG_EN_AA 0x01 #define REG_EN_RXADDR 0x02 #define REG_SETUP_AW 0x03 #define REG_SETUP_RETR 0x04 #define REG_DYNPD 0x1C #define REG_FEATURE 0x1D #define REG_RF_SETUP 0x06 #define REG_STATUS 0x07 #define REG_RX_ADDR_P0 0x0A #define REG_RF_CH 0x05 #define REG_TX_ADDR 0x10 #define RX_PW_P0 0x11 #define TX_DS 0x20 #define MAX_RT 0x10 #define nrf24_TIMEOUT 500 #define nrf24_CE_PIN &gpio_ext_pb2 #define nrf24_HANDLE &furi_hal_spi_bus_handle_external /* Low level API */ /** Write device register * * @param handle - pointer to FuriHalSpiHandle * @param reg - register * @param data - data to write * * @return device status */ uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); /** Write buffer to device register * * @param handle - pointer to FuriHalSpiHandle * @param reg - register * @param data - data to write * @param size - size of data to write * * @return device status */ uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); /** Read device register * * @param handle - pointer to FuriHalSpiHandle * @param reg - register * @param[out] data - pointer to data * * @return device status */ uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); /** Power up the radio for operation * * @param handle - pointer to FuriHalSpiHandle * * @return device status */ uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle); /** Power down the radio * * @param handle - pointer to FuriHalSpiHandle * * @return device status */ uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle); /** Sets the radio to RX mode * * @param handle - pointer to FuriHalSpiHandle * * @return device status */ uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle); /** Sets the radio to TX mode * * @param handle - pointer to FuriHalSpiHandle * * @return device status */ uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle); /*=============================================================================================================*/ /* High level API */ /** Must call this before using any other nrf24 API * */ void nrf24_init(); /** Must call this when we end using nrf24 device * */ void nrf24_deinit(); /** Send flush rx command * * @param handle - pointer to FuriHalSpiHandle * * @return device status */ uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle); /** Send flush tx command * * @param handle - pointer to FuriHalSpiHandle * * @return device status */ uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle); /** Gets the RX packet length in data pipe 0 * * @param handle - pointer to FuriHalSpiHandle * * @return packet length in data pipe 0 */ uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle); /** Sets the RX packet length in data pipe 0 * * @param handle - pointer to FuriHalSpiHandle * @param len - length to set * * @return device status */ uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len); /** Gets configured length of MAC address * * @param handle - pointer to FuriHalSpiHandle * * @return MAC address length */ uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle); /** Sets configured length of MAC address * * @param handle - pointer to FuriHalSpiHandle * @param maclen - length to set MAC address to, must be greater than 1 and less than 6 * * @return MAC address length */ uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen); /** Gets the current status flags from the STATUS register * * @param handle - pointer to FuriHalSpiHandle * * @return status flags */ uint8_t nrf24_status(FuriHalSpiBusHandle* handle); /** Gets the current transfer rate * * @param handle - pointer to FuriHalSpiHandle * * @return transfer rate in bps */ uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle); /** Sets the transfer rate * * @param handle - pointer to FuriHalSpiHandle * @param rate - the transfer rate in bps * * @return device status */ uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate); /** Gets the current channel * In nrf24, the channel number is multiplied times 1MHz and added to 2400MHz to get the frequency * * @param handle - pointer to FuriHalSpiHandle * * @return channel */ uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle); /** Sets the channel * * @param handle - pointer to FuriHalSpiHandle * @param frequency - the frequency in hertz * * @return device status */ uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan); /** Gets the source mac address * * @param handle - pointer to FuriHalSpiHandle * @param[out] mac - the source mac address * * @return device status */ uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); /** Sets the source mac address * * @param handle - pointer to FuriHalSpiHandle * @param mac - the mac address to set * @param size - the size of the mac address (2 to 5) * * @return device status */ uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); /** Gets the dest mac address * * @param handle - pointer to FuriHalSpiHandle * @param[out] mac - the source mac address * * @return device status */ uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); /** Sets the dest mac address * * @param handle - pointer to FuriHalSpiHandle * @param mac - the mac address to set * @param size - the size of the mac address (2 to 5) * * @return device status */ uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); /** Reads RX packet * * @param handle - pointer to FuriHalSpiHandle * @param[out] packet - the packet contents * @param[out] packetsize - size of the received packet * @param full - boolean set to true, packet length is determined by RX_PW_P0 register, false it is determined by dynamic payload length command * * @return device status */ uint8_t nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* packetsize, bool full); /** Sends TX packet * * @param handle - pointer to FuriHalSpiHandle * @param packet - the packet contents * @param size - packet size * @param ack - boolean to determine whether an ACK is required for the packet or not * * @return device status */ uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack); /** Configure the radio * This is not comprehensive, but covers a lot of the common configuration options that may be changed * @param handle - pointer to FuriHalSpiHandle * @param rate - transfer rate in Mbps (1 or 2) * @param srcmac - source mac address * @param dstmac - destination mac address * @param maclen - length of mac address * @param channel - channel to tune to * @param noack - if true, disable auto-acknowledge * @param disable_aa - if true, disable ShockBurst * */ void nrf24_configure( FuriHalSpiBusHandle* handle, uint8_t rate, uint8_t* srcmac, uint8_t* dstmac, uint8_t maclen, uint8_t channel, bool noack, bool disable_aa); /** Configures the radio for "promiscuous mode" and primes it for rx * This is not an actual mode of the nrf24, but this function exploits a few bugs in the chip that allows it to act as if it were. * See http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html for details. * @param handle - pointer to FuriHalSpiHandle * @param channel - channel to tune to * @param rate - transfer rate in Mbps (1 or 2) */ void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate); /** Listens for a packet and returns first possible address sniffed * Call this only after calling nrf24_init_promisc_mode * @param handle - pointer to FuriHalSpiHandle * @param maclen - length of target mac address * @param[out] addresses - sniffed address * * @return success */ bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address); /** Sends ping packet on each channel for designated tx mac looking for ack * * @param handle - pointer to FuriHalSpiHandle * @param srcmac - source address * @param dstmac - destination address * @param maclen - length of address * @param rate - transfer rate in Mbps (1 or 2) * @param min_channel - channel to start with * @param max_channel - channel to end at * @param autoinit - if true, automatically configure radio for this channel * * @return channel that the address is listening on, if this value is above the max_channel param, it failed */ uint8_t nrf24_find_channel( FuriHalSpiBusHandle* handle, uint8_t* srcmac, uint8_t* dstmac, uint8_t maclen, uint8_t rate, uint8_t min_channel, uint8_t max_channel, bool autoinit); /** Converts 64 bit value into uint8_t array * @param val - 64-bit integer * @param[out] out - bytes out * @param bigendian - if true, convert as big endian, otherwise little endian */ void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian); /** Converts 32 bit value into uint8_t array * @param val - 32-bit integer * @param[out] out - bytes out * @param bigendian - if true, convert as big endian, otherwise little endian */ void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian); /** Converts uint8_t array into 32 bit value * @param bytes - uint8_t array * @param bigendian - if true, convert as big endian, otherwise little endian * * @return 32-bit value */ uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian); #ifdef __cplusplus } #endif