From a426c8d552d4b477758f90d6bb08619fb1ff3edd Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 16 Jul 2019 12:21:26 +0200 Subject: Working Nrf24 ping-pong --- src/app/nrf24l01test/main.cc | 41 ++++++-- src/arch/msp430fr5969lp/Makefile.inc | 2 +- src/driver/nrf24l01.cc | 199 ++++++++++++++++++++++++++++++----- 3 files changed, 208 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/app/nrf24l01test/main.cc b/src/app/nrf24l01test/main.cc index f1d7ef0..d0961d4 100644 --- a/src/app/nrf24l01test/main.cc +++ b/src/app/nrf24l01test/main.cc @@ -10,6 +10,8 @@ counter.stop(); \ kout << endl << index << " :: " << dec << counter.value << "/" << counter.overflow << endl; +char buf[32]; + void loop(void) { gpio.led_toggle(1); @@ -33,17 +35,22 @@ void loop(void) } kout << endl; +#ifdef MULTIPASS_ARCH_msp430fr5969lp kout << "write: "; - nrf24l01.setRetries(0, 0); - nrf24l01.setDynamicPayloads(false); - nrf24l01.setDynamicAck(false); - TIMEIT("blocking write(3)", nrf24l01.write("foo", 3, true, true)); - TIMEIT("blocking write(10)", nrf24l01.write("123456789", 10, true, true)); - TIMEIT("blocking write(20)", nrf24l01.write("123456789123456789", 20, true, true)); - //TIMEIT("blocking write(30)", nrf24l01.write("123456789123456789123456789", 30, true, true)); - nrf24l01.startListening(); - arch.delay_ms(10); + //kout << nrf24l01.write("foo", 3, true, true) << " "; + //kout << nrf24l01.write("123456789", 10, true, true) << " "; + kout << nrf24l01.write("123456789123456789", 20, true, true) << endl; +#else + kout << "carrier " << nrf24l01.testCarrier() << " / RPD " << nrf24l01.testRPD(); + if (nrf24l01.available()) { + nrf24l01.read(buf, 32); + kout << " / data = " << buf << endl; + } else { + kout << " / no data" << endl; + } nrf24l01.stopListening(); + nrf24l01.startListening(); +#endif } int main(void) @@ -56,6 +63,22 @@ int main(void) nrf24l01.setup(); kout << " OK" << endl; + kout << "nrf24l01 configure ..."; + unsigned char addr[5] = {0, 'D', 'E', 'R', 'F'}; + //nrf24l01.setAutoAck(1); + //nrf24l01.enableAckPayload(); + nrf24l01.setDynamicPayloads(true); + nrf24l01.setPALevel(Nrf24l01::RF24_PA_MAX); + nrf24l01.setChannel(25); + nrf24l01.setDataRate(Nrf24l01::RF24_2MBPS); +#ifdef MULTIPASS_ARCH_msp430fr5994lp + nrf24l01.openReadingPipe(1, addr); + nrf24l01.startListening(); +#else + nrf24l01.openWritingPipe((const uint8_t*)addr); +#endif + kout << " OK" << endl; + gpio.led_on(0); arch.idle_loop(); diff --git a/src/arch/msp430fr5969lp/Makefile.inc b/src/arch/msp430fr5969lp/Makefile.inc index 244fcc2..912048a 100644 --- a/src/arch/msp430fr5969lp/Makefile.inc +++ b/src/arch/msp430fr5969lp/Makefile.inc @@ -93,7 +93,7 @@ build/system.hex: build/system.elf program: build/system.hex ${QUIET}LD_LIBRARY_PATH=${MSP430_FLASHER_DIR} \ ${MSP430_FLASHER_DIR}/MSP430Flasher \ - -i ${DEBUG_PORT} \ + -i /dev/${DEBUG_PORT} \ -w build/system.hex -v -g -z '[VCC]' arch_clean: diff --git a/src/driver/nrf24l01.cc b/src/driver/nrf24l01.cc index 921f69d..abd42ea 100644 --- a/src/driver/nrf24l01.cc +++ b/src/driver/nrf24l01.cc @@ -77,7 +77,41 @@ void Nrf24l01::setup() // PTX should use only 22uA of power writeRegister(NRF_CONFIG, (readRegister(NRF_CONFIG)) & ~(1 << PRIM_RX)); } - +/* +int Nrf24l01::init(uint8_t addr, uint8_t channel, rf24_datarate_e datarate){ + + if(channel > 125){ + return -1; + } + + unsigned char node_addr[5] = {addr, 'x', 'S', 'D', 'P'}; + + setAutoAck(1); + enableAckPayload(); + maskIRQ(true, true, false); + enableDynamicPayloads(); + setPALevel(RF24_PA_MAX); + setChannel(channel); + setDataRate(datarate); + openWritingPipe((const uint8_t*)GATEWAY_NAME); // GATEWAY_NAME is defined in the MSP430FR5969 RF24_arch_config.h + currentWritingPipe = 0; + openReadingPipe(1, node_addr); +#ifdef CONFIG_Apps_SolarDoorplate_PacketHandler + node_addr[0] = CONFIG_PACKETHANDLER_BROADCAST_ID; + openReadingPipe(2, node_addr); +#endif + if(getChannel() != channel){ + return -2; + } + + if(getDataRate() != datarate){ + return -3; + } + + return 0; + +} +*/ //Power up now. Radio will not power down unless instructed by MCU for config changes etc. void Nrf24l01::powerUp(void) { @@ -172,6 +206,25 @@ void Nrf24l01::toggleFeatures(void) endTransaction(); } +void Nrf24l01::enableAckPayload(void) +{ + // + // enable ack payload and dynamic payload features + // + + //toggle_features(); + writeRegister(FEATURE, readRegister(FEATURE) | (1 << EN_ACK_PAY) | (1 << EN_DPL)); + + //IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); + + // + // Enable dynamic payload on pipes 0 & 1 + // + + writeRegister(DYNPD, readRegister(DYNPD) | (1 << DPL_P1) | (1 << DPL_P0)); + dynamic_payloads_enabled = true; +} + void Nrf24l01::setChannel(uint8_t channel) { writeRegister(RF_CH, rf24_min(channel, 125)); @@ -182,16 +235,17 @@ uint8_t Nrf24l01::write(const void *buf, uint8_t len, bool await_ack, bool block writePayload(buf, len, await_ack ? W_TX_PAYLOAD : W_TX_PAYLOAD_NO_ACK); gpio.write(NRF24L01_EN_PIN, 1); - arch.delay_us(10); - gpio.write(NRF24L01_EN_PIN, 0); if (!blocking) { + arch.delay_us(10); + gpio.write(NRF24L01_EN_PIN, 0); return 0; } while (!(getStatus() & ((1 << TX_DS) | (1 << MAX_RT)))) ; + gpio.write(NRF24L01_EN_PIN, 1); uint8_t status = writeRegister(NRF_STATUS, ((1 << TX_DS) | (1 << MAX_RT))); if (status & (1 << MAX_RT)) @@ -241,6 +295,41 @@ void Nrf24l01::stopListening(void) writeRegister(EN_RXADDR, readRegister(EN_RXADDR) | (1 << child_pipe_enable[0])); // Enable RX on pipe0 } +bool Nrf24l01::available(void) +{ + return available(NULL); +} + +/****************************************************************************/ + +bool Nrf24l01::available(uint8_t *pipe_num) +{ + if (!(readRegister(FIFO_STATUS) & (1 << RX_EMPTY))) + { + + // If the caller wants the pipe number, include that + if (pipe_num) + { + uint8_t status = getStatus(); + *pipe_num = (status >> RX_P_NO) & 0b111; + } + return 1; + } + return 0; +} + +bool Nrf24l01::testCarrier(void) +{ + return (readRegister(CD) & 1); +} + +/****************************************************************************/ + +bool Nrf24l01::testRPD(void) +{ + return (readRegister(RPD) & 1); +} + void Nrf24l01::openReadingPipe(uint8_t child, const uint8_t *address) { // If this is pipe 0, cache the address. This is needed because @@ -281,6 +370,29 @@ void Nrf24l01::closeReadingPipe(uint8_t pipe) writeRegister(EN_RXADDR, readRegister(EN_RXADDR) & ~(1 << child_pipe_enable[pipe])); } +/****************************************************************************/ +void Nrf24l01::openWritingPipe(const uint8_t *address) +{ + // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+) + // expects it LSB first too, so we're good. + + writeRegister(RX_ADDR_P0, address, addr_width); + writeRegister(TX_ADDR, address, addr_width); + + //const uint8_t max_payload_size = 32; + //write_register(RX_PW_P0,rf24_min(payload_size,max_payload_size)); + writeRegister(RX_PW_P0, payload_size); +} + +void Nrf24l01::setAddressWidth(uint8_t a_width) +{ + if (a_width -= 2) + { + writeRegister(SETUP_AW, a_width % 4); + addr_width = (a_width % 4) + 2; + } +} + void Nrf24l01::maskIRQ(bool tx, bool fail, bool rx) { @@ -338,6 +450,45 @@ uint8_t Nrf24l01::writeRegister(uint8_t reg, uint8_t value) return rxbuf[0]; } +uint8_t Nrf24l01::readPayload(void *buf, uint8_t data_len) +{ + uint8_t status; + uint8_t *current = reinterpret_cast(buf); + + if (data_len > payload_size) + data_len = payload_size; + uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; + + beginTransaction(); + txbuf[0] = R_RX_PAYLOAD; + spi.xmit(1, txbuf, 1, rxbuf); + status = rxbuf[0]; + txbuf[0] = 0xf; + ; + while (data_len--) + { + spi.xmit(1, txbuf, 1, rxbuf); + *current++ = rxbuf[0]; + } + while (blank_len--) + { + spi.xmit(1, txbuf, 1, rxbuf); + } + endTransaction(); + + return status; +} + +void Nrf24l01::read(void *buf, uint8_t len) +{ + + // Fetch the payload + readPayload(buf, len); + + //Clear the two possible interrupt flags with one command + writeRegister(NRF_STATUS, (1 << RX_DR) | (1 << MAX_RT) | (1 << TX_DS)); +} + void Nrf24l01::setDynamicPayloads(const bool enabled) { if (enabled) @@ -368,27 +519,27 @@ void Nrf24l01::setDynamicAck(const bool enabled) void Nrf24l01::setAutoAck(bool enable) { - if ( enable ) - writeRegister(EN_AA, 0b111111); - else - writeRegister(EN_AA, 0); -} - -void Nrf24l01::setAutoAck( uint8_t pipe, bool enable ) -{ - if ( pipe <= 6 ) - { - uint8_t en_aa = readRegister( EN_AA ) ; - if( enable ) - { - en_aa |= (1<