Loading include/driver/nrf24l01.h +212 −39 Original line number Diff line number Diff line Loading @@ -5,61 +5,234 @@ #include "driver/gpio.h" #include "arch.h" class Nrf24l01 { #define rf24_max(a, b) ((a) > (b) ? (a) : (b)) #define rf24_min(a, b) ((a) < (b) ? (a) : (b)) class Nrf24l01 { private: Nrf24l01(const Nrf24l01 ©); unsigned char txbuf[2]; unsigned char rxbuf[2]; bool p_variant; /* False for RF24L01 and true for RF24L01P */ uint8_t payload_size; /**< Fixed size of payloads */ bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ uint8_t pipe0_reading_address[5]; /**< Last address set on pipe 0 for reading. */ uint8_t addr_width; /**< The address width to use - 3,4 or 5 bytes. */ uint32_t txRxDelay; /**< Var for adjusting delays depending on datarate */ uint8_t writeRegister(uint8_t reg, uint8_t value); uint8_t readRegister(uint8_t reg); uint8_t writePayload(const void *buf, uint8_t data_len, const uint8_t writeType); inline void csnHigh() { inline void csnHigh() { gpio.write(NRF24L01_CS_PIN, 1); arch.delay_us(5); } inline void csnLow() { inline void csnLow() { gpio.write(NRF24L01_CS_PIN, 0); arch.delay_us(5); } inline void beginTransaction() { inline void beginTransaction() { csnLow(); } inline void endTransaction() { inline void endTransaction() { csnHigh(); } public: Nrf24l01() {} Nrf24l01() : payload_size(32), dynamic_payloads_enabled(false), addr_width(5) {} /** * Power Amplifier level. * * For use with setPALevel() */ enum rf24_pa_dbm_e { RF24_PA_MIN = 0,RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_PA_ERROR }; enum rf24_pa_dbm_e { RF24_PA_MIN = 0, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_PA_ERROR }; /** * Data rate. How fast data moves through the air. * * For use with setDataRate() */ enum rf24_datarate_e { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS }; enum rf24_datarate_e { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS }; /** * CRC Length. How big (if any) of a CRC is included. * * For use with setCRCLength() */ enum rf24_crclength_e { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 }; enum rf24_crclength_e { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 }; /** * Enter low-power mode * * To return to normal power mode, call powerUp(). * * @note After calling startListening(), a basic radio will consume about 13.5mA * at max PA level. * During active transmission, the radio will consume about 11.5mA, but this will * be reduced to 26uA (.026mA) between sending. * In full powerDown mode, the radio will consume approximately 900nA (.0009mA) * * @code * radio.powerDown(); * avr_enter_sleep_mode(); // Custom function to sleep the device * radio.powerUp(); * @endcode */ void powerDown(void); /** * Leave low-power mode - required for normal radio operation after calling powerDown() * * To return to low power mode, call powerDown(). * @note This will take up to 5ms for maximum compatibility */ void powerUp(void); /** * Empty the transmit buffer. This is generally not required in standard operation. * May be required in specific cases after stopListening() , if operating at 250KBPS data rate. * * @return Current value of status register */ uint8_t flushTx(void); /** * Empty the receive buffer * * @return Current value of status register */ uint8_t flushRx(void); void setup(); void powerOn(); void powerOff(); /** * Set Power Amplifier (PA) level to one of four levels: * RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX * * The power levels correspond to the following output levels respectively: * NRF24L01: -18dBm, -12dBm,-6dBM, and 0dBm * * SI24R1: -6dBm, 0dBm, 3dBM, and 7dBm. * * @param level Desired PA level. */ void setPALevel(uint8_t level); // 0 (-18B), 1 (-12dB), 2 (-6dB), 3 (0dB) /** * Set the address width from 3 to 5 bytes (24, 32 or 40 bit) * * @param a_width The address width to use: 3,4 or 5 */ void setAddressWidth(uint8_t a_width); /** * Set the number and delay of retries upon failed submit * * @param delay How long to wait between each retry, in multiples of 250us, * max is 15. 0 means 250us, 15 means 4000us. * @param count How many retries before giving up, max 15 */ void setRetries(uint8_t delay, uint8_t count); void setPALevel ( uint8_t level ); // 0 (-18B), 1 (-12dB), 2 (-6dB), 3 (0dB) /** * Set RF communication channel * * @param channel Which RF channel to communicate on, 0-125 */ void setChannel(uint8_t channel); /** * Get RF communication channel * * @return The currently configured RF Channel */ uint8_t getChannel(void); /** * Set Static Payload Size * * This implementation uses a pre-stablished fixed payload size for all * transmissions. If this method is never called, the driver will always * transmit the maximum payload size (32 bytes), no matter how much * was sent to write(). * * @todo Implement variable-sized payloads feature * * @param size The number of bytes in the payload */ void setPayloadSize(uint8_t size); /** * Get Static Payload Size * * @see setPayloadSize() * * @return The number of bytes in the payload */ uint8_t getPayloadSize(void); /** * Set the transmission data rate * * @warning setting RF24_250KBPS will fail for non-plus units * * @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps * @return true if the change was successful */ bool setDataRate(rf24_datarate_e speed); /** * The radio will generate interrupt signals when a transmission is complete, * a transmission fails, or a payload is received. This allows users to mask * those interrupts to prevent them from generating a signal on the interrupt * pin. Interrupts are enabled on the radio chip by default. * * @code * Mask all interrupts except the receive interrupt: * * radio.maskIRQ(1,1,0); * @endcode * * @param tx_ok Mask transmission complete interrupts * @param tx_fail Mask transmit failure interrupts * @param rx_ready Mask payload received interrupts */ void maskIRQ(bool tx_ok, bool tx_fail, bool rx_ready); /** * Turn on or off the special features of the chip * * The chip has certain 'features' which are only available when the 'features' * are enabled. See the datasheet for details. */ void toggleFeatures(void); uint8_t write(const void *buf, uint8_t len, bool blocking); uint8_t getStatus(); }; Loading src/app/nrf24l01test/main.cc +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ void loop(void) { gpio.led_toggle(1); kout << "status: " << hex << nrf24l01.getStatus() << endl; kout << "write: "; kout << nrf24l01.write("foo", 3, true) << endl; } int main(void) Loading src/arch/msp430fr5994lp/Makefile.inc +1 −1 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ CPU = 430x MCU = msp430fr5994 cpu_freq ?= 16000000 cpu_freq ?= 8000000 MSP430_FLASHER_DIR ?= /home/derf/var/projects/msp430/MSP430Flasher_1.3.15 Loading src/driver/nrf24l01.cc +187 −11 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ void Nrf24l01::setup() { spi.setup(); gpio.input(NRF24L01_IRQ_PIN, true); gpio.output(NRF24L01_EN_PIN); gpio.output(NRF24L01_CS_PIN); gpio.write(NRF24L01_EN_PIN, 0); Loading @@ -33,11 +34,55 @@ void Nrf24l01::setup() // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet // sizes must never be used. See documentation for a more complete explanation. setRetries(5,15); setRetries(5, 10); // Reset value is MAX setPALevel(RF24_PA_MAX); setDataRate(RF24_1MBPS); toggleFeatures(); writeRegister(FEATURE, 0); writeRegister(DYNPD, 0); dynamic_payloads_enabled = false; // Reset current status // Notice reset and flush is the last thing we do writeRegister(NRF_STATUS, (1 << RX_DR) | (1 << TX_DS) | (1 << MAX_RT)); // Set up default configuration. Callers can always change it later. // This channel should be universally safe and not bleed over into adjacent // spectrum. setChannel(76); // Flush buffers flushRx(); flushTx(); maskIRQ(true, false, false); powerUp(); //Power up by default when begin() is called // Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX instead of 1500us from powerUp ) // PTX should use only 22uA of power writeRegister(NRF_CONFIG, (readRegister(NRF_CONFIG)) & ~(1 << PRIM_RX)); } //Power up now. Radio will not power down unless instructed by MCU for config changes etc. void Nrf24l01::powerUp(void) { uint8_t cfg = readRegister(NRF_CONFIG); // if not powered up then power up and wait for the radio to initialize if (!(cfg & (1 << PWR_UP))) { writeRegister(NRF_CONFIG, cfg | (1 << PWR_UP)); // For nRF24L01+ to go from power down mode to TX or RX mode it must first pass through stand-by mode. // There must be a delay of Tpd2stby (see Table 16.) after the nRF24L01+ leaves power down mode before // the CEis set high. - Tpd2stby can be up to 5ms per the 1.0 datasheet arch.delay_us(5); } } void Nrf24l01::setRetries(uint8_t delay, uint8_t count) Loading @@ -49,15 +94,104 @@ void Nrf24l01::setPALevel(uint8_t level) { uint8_t setup = readRegister(RF_SETUP) & 0b11111000; if(level > 3){ // If invalid level, go to max PA if (level > 3) { // If invalid level, go to max PA level = (RF24_PA_MAX << 1) + 1; // +1 to support the SI24R1 chip extra bit }else{ } else { level = (level << 1) + 1; // Else set level as requested } writeRegister(RF_SETUP, setup |= level); // Write it to the chip } bool Nrf24l01::setDataRate(Nrf24l01::rf24_datarate_e speed) { bool result = false; uint8_t setup = readRegister(RF_SETUP); // HIGH and LOW '00' is 1Mbs - our default setup &= ~((1 << RF_DR_LOW) | (1 << RF_DR_HIGH)); txRxDelay = 85; if (speed == RF24_250KBPS) { // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0 // Making it '10'. setup |= (1 << RF_DR_LOW); txRxDelay = 155; } else { // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1 // Making it '01' if (speed == RF24_2MBPS) { setup |= (1 << RF_DR_HIGH); txRxDelay = 65; } } writeRegister(RF_SETUP, setup); // Verify our result if (readRegister(RF_SETUP) == setup) { result = true; } return result; } void Nrf24l01::toggleFeatures(void) { beginTransaction(); txbuf[0] = ACTIVATE; txbuf[1] = 0x73; spi.xmit(2, txbuf, 0, rxbuf); endTransaction(); } void Nrf24l01::setChannel(uint8_t channel) { writeRegister(RF_CH, rf24_min(channel, 125)); } uint8_t Nrf24l01::write(const void *buf, uint8_t len, bool blocking) { writePayload(buf, len, W_TX_PAYLOAD); gpio.write(NRF24L01_EN_PIN, 1); arch.delay_us(10); gpio.write(NRF24L01_EN_PIN, 0); if (!blocking) { return 0; } while (!(getStatus() & ((1 << TX_DS) | (1 << MAX_RT)))) ; uint8_t status = writeRegister(NRF_STATUS, ((1 << TX_DS) | (1 << MAX_RT))); if (status & (1 << MAX_RT)) { // flush_tx(); //Only going to be 1 packet int the FIFO at a time using this method, so just flush return 0; } return 1; } void Nrf24l01::maskIRQ(bool tx, bool fail, bool rx) { uint8_t config = readRegister(NRF_CONFIG); /* clear the interrupt flags */ config &= ~(1 << MASK_MAX_RT | 1 << MASK_TX_DS | 1 << MASK_RX_DR); /* set the specified interrupt flags */ config |= fail << MASK_MAX_RT | tx << MASK_TX_DS | rx << MASK_RX_DR; writeRegister(NRF_CONFIG, config); } uint8_t Nrf24l01::getStatus() { txbuf[0] = NOP; Loading Loading @@ -92,4 +226,46 @@ uint8_t Nrf24l01::writeRegister(uint8_t reg, uint8_t value) return rxbuf[0]; } uint8_t Nrf24l01::writePayload(const void *buf, uint8_t data_len, const uint8_t writeType) { data_len = rf24_min(data_len, payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; //printf("[Writing %u bytes %u blanks]",data_len,blank_len); //IF_SERIAL_DEBUG( printf("[Writing %u bytes %u blanks]\n",data_len,blank_len); ); beginTransaction(); txbuf[0] = writeType; spi.xmit(1, txbuf, 1, rxbuf); spi.xmit(data_len, (unsigned char *)buf, 0, NULL); txbuf[0] = 0; while (blank_len--) { spi.xmit(1, txbuf, 0, NULL); } endTransaction(); return rxbuf[0]; } uint8_t Nrf24l01::flushRx(void) { txbuf[0] = FLUSH_RX; beginTransaction(); spi.xmit(1, txbuf, 1, rxbuf); endTransaction(); return rxbuf[0]; } /****************************************************************************/ uint8_t Nrf24l01::flushTx(void) { txbuf[0] = FLUSH_TX; beginTransaction(); spi.xmit(1, txbuf, 1, rxbuf); endTransaction(); return rxbuf[0]; } Nrf24l01 nrf24l01; No newline at end of file Loading
include/driver/nrf24l01.h +212 −39 Original line number Diff line number Diff line Loading @@ -5,61 +5,234 @@ #include "driver/gpio.h" #include "arch.h" class Nrf24l01 { #define rf24_max(a, b) ((a) > (b) ? (a) : (b)) #define rf24_min(a, b) ((a) < (b) ? (a) : (b)) class Nrf24l01 { private: Nrf24l01(const Nrf24l01 ©); unsigned char txbuf[2]; unsigned char rxbuf[2]; bool p_variant; /* False for RF24L01 and true for RF24L01P */ uint8_t payload_size; /**< Fixed size of payloads */ bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ uint8_t pipe0_reading_address[5]; /**< Last address set on pipe 0 for reading. */ uint8_t addr_width; /**< The address width to use - 3,4 or 5 bytes. */ uint32_t txRxDelay; /**< Var for adjusting delays depending on datarate */ uint8_t writeRegister(uint8_t reg, uint8_t value); uint8_t readRegister(uint8_t reg); uint8_t writePayload(const void *buf, uint8_t data_len, const uint8_t writeType); inline void csnHigh() { inline void csnHigh() { gpio.write(NRF24L01_CS_PIN, 1); arch.delay_us(5); } inline void csnLow() { inline void csnLow() { gpio.write(NRF24L01_CS_PIN, 0); arch.delay_us(5); } inline void beginTransaction() { inline void beginTransaction() { csnLow(); } inline void endTransaction() { inline void endTransaction() { csnHigh(); } public: Nrf24l01() {} Nrf24l01() : payload_size(32), dynamic_payloads_enabled(false), addr_width(5) {} /** * Power Amplifier level. * * For use with setPALevel() */ enum rf24_pa_dbm_e { RF24_PA_MIN = 0,RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_PA_ERROR }; enum rf24_pa_dbm_e { RF24_PA_MIN = 0, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_PA_ERROR }; /** * Data rate. How fast data moves through the air. * * For use with setDataRate() */ enum rf24_datarate_e { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS }; enum rf24_datarate_e { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS }; /** * CRC Length. How big (if any) of a CRC is included. * * For use with setCRCLength() */ enum rf24_crclength_e { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 }; enum rf24_crclength_e { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 }; /** * Enter low-power mode * * To return to normal power mode, call powerUp(). * * @note After calling startListening(), a basic radio will consume about 13.5mA * at max PA level. * During active transmission, the radio will consume about 11.5mA, but this will * be reduced to 26uA (.026mA) between sending. * In full powerDown mode, the radio will consume approximately 900nA (.0009mA) * * @code * radio.powerDown(); * avr_enter_sleep_mode(); // Custom function to sleep the device * radio.powerUp(); * @endcode */ void powerDown(void); /** * Leave low-power mode - required for normal radio operation after calling powerDown() * * To return to low power mode, call powerDown(). * @note This will take up to 5ms for maximum compatibility */ void powerUp(void); /** * Empty the transmit buffer. This is generally not required in standard operation. * May be required in specific cases after stopListening() , if operating at 250KBPS data rate. * * @return Current value of status register */ uint8_t flushTx(void); /** * Empty the receive buffer * * @return Current value of status register */ uint8_t flushRx(void); void setup(); void powerOn(); void powerOff(); /** * Set Power Amplifier (PA) level to one of four levels: * RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX * * The power levels correspond to the following output levels respectively: * NRF24L01: -18dBm, -12dBm,-6dBM, and 0dBm * * SI24R1: -6dBm, 0dBm, 3dBM, and 7dBm. * * @param level Desired PA level. */ void setPALevel(uint8_t level); // 0 (-18B), 1 (-12dB), 2 (-6dB), 3 (0dB) /** * Set the address width from 3 to 5 bytes (24, 32 or 40 bit) * * @param a_width The address width to use: 3,4 or 5 */ void setAddressWidth(uint8_t a_width); /** * Set the number and delay of retries upon failed submit * * @param delay How long to wait between each retry, in multiples of 250us, * max is 15. 0 means 250us, 15 means 4000us. * @param count How many retries before giving up, max 15 */ void setRetries(uint8_t delay, uint8_t count); void setPALevel ( uint8_t level ); // 0 (-18B), 1 (-12dB), 2 (-6dB), 3 (0dB) /** * Set RF communication channel * * @param channel Which RF channel to communicate on, 0-125 */ void setChannel(uint8_t channel); /** * Get RF communication channel * * @return The currently configured RF Channel */ uint8_t getChannel(void); /** * Set Static Payload Size * * This implementation uses a pre-stablished fixed payload size for all * transmissions. If this method is never called, the driver will always * transmit the maximum payload size (32 bytes), no matter how much * was sent to write(). * * @todo Implement variable-sized payloads feature * * @param size The number of bytes in the payload */ void setPayloadSize(uint8_t size); /** * Get Static Payload Size * * @see setPayloadSize() * * @return The number of bytes in the payload */ uint8_t getPayloadSize(void); /** * Set the transmission data rate * * @warning setting RF24_250KBPS will fail for non-plus units * * @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps * @return true if the change was successful */ bool setDataRate(rf24_datarate_e speed); /** * The radio will generate interrupt signals when a transmission is complete, * a transmission fails, or a payload is received. This allows users to mask * those interrupts to prevent them from generating a signal on the interrupt * pin. Interrupts are enabled on the radio chip by default. * * @code * Mask all interrupts except the receive interrupt: * * radio.maskIRQ(1,1,0); * @endcode * * @param tx_ok Mask transmission complete interrupts * @param tx_fail Mask transmit failure interrupts * @param rx_ready Mask payload received interrupts */ void maskIRQ(bool tx_ok, bool tx_fail, bool rx_ready); /** * Turn on or off the special features of the chip * * The chip has certain 'features' which are only available when the 'features' * are enabled. See the datasheet for details. */ void toggleFeatures(void); uint8_t write(const void *buf, uint8_t len, bool blocking); uint8_t getStatus(); }; Loading
src/app/nrf24l01test/main.cc +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ void loop(void) { gpio.led_toggle(1); kout << "status: " << hex << nrf24l01.getStatus() << endl; kout << "write: "; kout << nrf24l01.write("foo", 3, true) << endl; } int main(void) Loading
src/arch/msp430fr5994lp/Makefile.inc +1 −1 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ CPU = 430x MCU = msp430fr5994 cpu_freq ?= 16000000 cpu_freq ?= 8000000 MSP430_FLASHER_DIR ?= /home/derf/var/projects/msp430/MSP430Flasher_1.3.15 Loading
src/driver/nrf24l01.cc +187 −11 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ void Nrf24l01::setup() { spi.setup(); gpio.input(NRF24L01_IRQ_PIN, true); gpio.output(NRF24L01_EN_PIN); gpio.output(NRF24L01_CS_PIN); gpio.write(NRF24L01_EN_PIN, 0); Loading @@ -33,11 +34,55 @@ void Nrf24l01::setup() // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet // sizes must never be used. See documentation for a more complete explanation. setRetries(5,15); setRetries(5, 10); // Reset value is MAX setPALevel(RF24_PA_MAX); setDataRate(RF24_1MBPS); toggleFeatures(); writeRegister(FEATURE, 0); writeRegister(DYNPD, 0); dynamic_payloads_enabled = false; // Reset current status // Notice reset and flush is the last thing we do writeRegister(NRF_STATUS, (1 << RX_DR) | (1 << TX_DS) | (1 << MAX_RT)); // Set up default configuration. Callers can always change it later. // This channel should be universally safe and not bleed over into adjacent // spectrum. setChannel(76); // Flush buffers flushRx(); flushTx(); maskIRQ(true, false, false); powerUp(); //Power up by default when begin() is called // Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX instead of 1500us from powerUp ) // PTX should use only 22uA of power writeRegister(NRF_CONFIG, (readRegister(NRF_CONFIG)) & ~(1 << PRIM_RX)); } //Power up now. Radio will not power down unless instructed by MCU for config changes etc. void Nrf24l01::powerUp(void) { uint8_t cfg = readRegister(NRF_CONFIG); // if not powered up then power up and wait for the radio to initialize if (!(cfg & (1 << PWR_UP))) { writeRegister(NRF_CONFIG, cfg | (1 << PWR_UP)); // For nRF24L01+ to go from power down mode to TX or RX mode it must first pass through stand-by mode. // There must be a delay of Tpd2stby (see Table 16.) after the nRF24L01+ leaves power down mode before // the CEis set high. - Tpd2stby can be up to 5ms per the 1.0 datasheet arch.delay_us(5); } } void Nrf24l01::setRetries(uint8_t delay, uint8_t count) Loading @@ -49,15 +94,104 @@ void Nrf24l01::setPALevel(uint8_t level) { uint8_t setup = readRegister(RF_SETUP) & 0b11111000; if(level > 3){ // If invalid level, go to max PA if (level > 3) { // If invalid level, go to max PA level = (RF24_PA_MAX << 1) + 1; // +1 to support the SI24R1 chip extra bit }else{ } else { level = (level << 1) + 1; // Else set level as requested } writeRegister(RF_SETUP, setup |= level); // Write it to the chip } bool Nrf24l01::setDataRate(Nrf24l01::rf24_datarate_e speed) { bool result = false; uint8_t setup = readRegister(RF_SETUP); // HIGH and LOW '00' is 1Mbs - our default setup &= ~((1 << RF_DR_LOW) | (1 << RF_DR_HIGH)); txRxDelay = 85; if (speed == RF24_250KBPS) { // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0 // Making it '10'. setup |= (1 << RF_DR_LOW); txRxDelay = 155; } else { // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1 // Making it '01' if (speed == RF24_2MBPS) { setup |= (1 << RF_DR_HIGH); txRxDelay = 65; } } writeRegister(RF_SETUP, setup); // Verify our result if (readRegister(RF_SETUP) == setup) { result = true; } return result; } void Nrf24l01::toggleFeatures(void) { beginTransaction(); txbuf[0] = ACTIVATE; txbuf[1] = 0x73; spi.xmit(2, txbuf, 0, rxbuf); endTransaction(); } void Nrf24l01::setChannel(uint8_t channel) { writeRegister(RF_CH, rf24_min(channel, 125)); } uint8_t Nrf24l01::write(const void *buf, uint8_t len, bool blocking) { writePayload(buf, len, W_TX_PAYLOAD); gpio.write(NRF24L01_EN_PIN, 1); arch.delay_us(10); gpio.write(NRF24L01_EN_PIN, 0); if (!blocking) { return 0; } while (!(getStatus() & ((1 << TX_DS) | (1 << MAX_RT)))) ; uint8_t status = writeRegister(NRF_STATUS, ((1 << TX_DS) | (1 << MAX_RT))); if (status & (1 << MAX_RT)) { // flush_tx(); //Only going to be 1 packet int the FIFO at a time using this method, so just flush return 0; } return 1; } void Nrf24l01::maskIRQ(bool tx, bool fail, bool rx) { uint8_t config = readRegister(NRF_CONFIG); /* clear the interrupt flags */ config &= ~(1 << MASK_MAX_RT | 1 << MASK_TX_DS | 1 << MASK_RX_DR); /* set the specified interrupt flags */ config |= fail << MASK_MAX_RT | tx << MASK_TX_DS | rx << MASK_RX_DR; writeRegister(NRF_CONFIG, config); } uint8_t Nrf24l01::getStatus() { txbuf[0] = NOP; Loading Loading @@ -92,4 +226,46 @@ uint8_t Nrf24l01::writeRegister(uint8_t reg, uint8_t value) return rxbuf[0]; } uint8_t Nrf24l01::writePayload(const void *buf, uint8_t data_len, const uint8_t writeType) { data_len = rf24_min(data_len, payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; //printf("[Writing %u bytes %u blanks]",data_len,blank_len); //IF_SERIAL_DEBUG( printf("[Writing %u bytes %u blanks]\n",data_len,blank_len); ); beginTransaction(); txbuf[0] = writeType; spi.xmit(1, txbuf, 1, rxbuf); spi.xmit(data_len, (unsigned char *)buf, 0, NULL); txbuf[0] = 0; while (blank_len--) { spi.xmit(1, txbuf, 0, NULL); } endTransaction(); return rxbuf[0]; } uint8_t Nrf24l01::flushRx(void) { txbuf[0] = FLUSH_RX; beginTransaction(); spi.xmit(1, txbuf, 1, rxbuf); endTransaction(); return rxbuf[0]; } /****************************************************************************/ uint8_t Nrf24l01::flushTx(void) { txbuf[0] = FLUSH_TX; beginTransaction(); spi.xmit(1, txbuf, 1, rxbuf); endTransaction(); return rxbuf[0]; } Nrf24l01 nrf24l01; No newline at end of file