From 42d8e2c4949b61d3c88a01fe292d0556ae44f2d8 Mon Sep 17 00:00:00 2001 From: vad7 Date: Fri, 24 Feb 2023 21:53:33 +0300 Subject: [PATCH] upd --- Distr/nrf24batch/CO2_mini.txt | 30 ++-- lib/nrf24/nrf24.c | 295 +++++++--------------------------- lib/nrf24/nrf24.h | 5 + nrf24batch.c | 163 +++++++++++-------- 4 files changed, 176 insertions(+), 317 deletions(-) diff --git a/Distr/nrf24batch/CO2_mini.txt b/Distr/nrf24batch/CO2_mini.txt index 6db96603372..3a05953ea48 100644 --- a/Distr/nrf24batch/CO2_mini.txt +++ b/Distr/nrf24batch/CO2_mini.txt @@ -2,15 +2,17 @@ Info: CO2 sensor mini Rate: 1 Ch: 121 CRC: 2 +DPL: 0 Address: C8C8CF -Delay_ms: 10 +Resend: 3 +Delay_ms: 30 Payload struct: 2,1,1 EEPROM=0; RAM=1; PROGMEM=2; ID=3; RESET=4 R default: ,EEPROM,0xC1 W default: n,,0x81 -Write start: ,,0x8F +Write start: 0,0,0x8F R: ID*=,ID R: OSCCAL=0x51,RAM @@ -24,10 +26,7 @@ R: Ch=2 W: Ch=,2 R: nRF RETR=3 -W: nRF RETR 1/750uS=0x21,3 - -R: AnswerDelay=9 -W: AnswerDelay=,9 +W: nRF RETR=,3 R: Send period=4 W: Send period=,4 @@ -38,19 +37,20 @@ W: CO2 threshold=,5,0x82 R: CO2 correct*2=7,,0xC2 W: CO2 correct=,7,0x82 -R: FanLSB[10]=i:10 -W: FanLSB=,i:19 +R: FanLSB[10]=i:9 +W: FanLSB=,i:9 W: Reset=,RESET,0xC1 RBatch: Settings: ID;OSCCAL;RxAddr;Ch;nRF RETR;CO2 threshold;CO2 correct;FanLSB RBatch: Settings2: OSCCAL;OSCCAL_EMEM;RxAddr;Ch;nRF RETR;CO2 threshold;CO2 correct;FanLSB -WBatch: Default Ch-121: RxAddr=0xCF;Ch=121;CO2 threshold=1000;CO2 correct=0;Send period=30;FanLSB={0xC1,0xC2,0xC3,0};Reset -WBatch: Default Ch-10: RxAddr=0xCF;Ch=10;CO2 threshold=1000;CO2 correct=0;Send period=31;FanLSB={0xC1,0};Reset +WBatch: Default Ch-121: RxAddr=0xCF;Ch=121;CO2 threshold=1000;CO2 correct=0;Send period=30;nRF RETR=0x17;FanLSB={0xC1,0};Reset +WBatch: Default Ch-10: RxAddr=0xCF;Ch=10;CO2 threshold=1000;CO2 correct=0;Send period=31;FanLSB={0xC1,0xC2,0};Reset WBatch: CO2: CO2 threshold=1000;CO2 correct=1 -WBatch: Fan: FanLSB={0xC2,0xC3,0};Reset -WBatch: DELAY=0: AnswerDelay=0 -WBatch: DELAY=100: AnswerDelay=100 -WBatch: DELAY=200: AnswerDelay=200 -WBatch: DELAY=255: AnswerDelay=255 +WBatch: Fan2: FanLSB={0xC2,0xC3,0};Reset +WBatch: RETR 0x17: nRF RETR=0x17 +WBatch: RETR 0x2F: nRF RETR=0x2F +WBatch: RETR 0x0F: nRF RETR=0x0F +WBatch: RETR 0x01: nRF RETR=0x01 +WBatch: Reset: Reset diff --git a/lib/nrf24/nrf24.c b/lib/nrf24/nrf24.c index 016b0d765dc..11d8ca71198 100644 --- a/lib/nrf24/nrf24.c +++ b/lib/nrf24/nrf24.c @@ -1,4 +1,4 @@ -// Modified by vad7, 25.11.2022 +// Modified by vad7, 24.02.2023 // #include "nrf24.h" #include @@ -32,33 +32,34 @@ void nrf24_spi_trx( } uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { - uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data}; - uint8_t rx[2] = {0}; - nrf24_spi_trx(handle, tx, rx, 2); + uint8_t buf[] = {W_REGISTER | (REGISTER_MASK & reg), data}; + nrf24_spi_trx(handle, buf, buf, 2); //FURI_LOG_D("NRF_WR", " #%02X=%02X", reg, data); - return rx[0]; + return buf[0]; } uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = W_REGISTER | (REGISTER_MASK & reg); - memcpy(&tx[1], data, size); - nrf24_spi_trx(handle, tx, rx, size + 1); + uint8_t buf[size + 1]; + buf[0] = W_REGISTER | (REGISTER_MASK & reg); + memcpy(&buf[1], data, size); + nrf24_spi_trx(handle, buf, buf, size + 1); //FURI_LOG_D("NRF_WR", " #%02X(%02X)=0x%02X%02X%02X%02X%02X", reg, size, data[0], data[1], data[2], data[3], data[4] ); - return rx[0]; + return buf[0]; } uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = R_REGISTER | (REGISTER_MASK & reg); - memset(&tx[1], 0, size); - nrf24_spi_trx(handle, tx, rx, size + 1); - memcpy(data, &rx[1], size); - return rx[0]; + uint8_t buf[size + 1]; + memset(buf, 0, size + 1); + buf[0] = R_REGISTER | (REGISTER_MASK & reg); + nrf24_spi_trx(handle, buf, buf, size + 1); + memcpy(data, &buf[1], size); + return buf[0]; +} + +uint8_t nrf24_read_register(FuriHalSpiBusHandle* handle, uint8_t reg) { + uint8_t buf[] = { R_REGISTER | (REGISTER_MASK & reg), 0xFF }; + nrf24_spi_trx(handle, buf, buf, 2); + return buf[1]; } uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) { @@ -90,10 +91,9 @@ uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen) { } uint8_t nrf24_status(FuriHalSpiBusHandle* handle) { - uint8_t status; - uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)}; - nrf24_spi_trx(handle, tx, &status, 1); - return status; + uint8_t tx = RF24_NOP; + nrf24_spi_trx(handle, &tx, &tx, 1); + return tx; } uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle) { @@ -191,32 +191,33 @@ uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len) { // packet_size: 0 - dyn payload (read from PL_WID), 1 - read from pipe size, >1 - override uint8_t nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* ret_packetsize, uint8_t packet_size) { uint8_t status = 0; - uint8_t tx_cmd[33] = {0}; // 32 max payload size + 1 for command - uint8_t tmp_packet[33] = {0}; + uint8_t buf[33]; // 32 max payload size + 1 for command status = nrf24_status(handle); if(!(status & RX_DR)) { - tx_cmd[0] = R_REGISTER | (REGISTER_MASK & REG_FIFO_STATUS); - nrf24_spi_trx(handle, tx_cmd, tmp_packet, 2); - if((tmp_packet[1] & 1) == 0) status |= RX_DR; // packet in FIFO buffer + if((nrf24_read_register(handle, REG_FIFO_STATUS) & 1) == 0) { + FURI_LOG_D("NRF", "FIFO PKT"); + status |= RX_DR; // packet in FIFO buffer + } } if(status & RX_DR) { if(packet_size == 1) packet_size = nrf24_get_packetlen(handle, (status >> 1) & 7); else if(packet_size == 0){ - tx_cmd[0] = R_RX_PL_WID; tx_cmd[1] = 0; - nrf24_spi_trx(handle, tx_cmd, tmp_packet, 2); - packet_size = tmp_packet[1]; + buf[0] = R_RX_PL_WID; buf[1] = 0xFF; + nrf24_spi_trx(handle, buf, buf, 2); + packet_size = buf[1]; } if(packet_size > 32 || packet_size == 0) packet_size = 32; - tx_cmd[0] = R_RX_PAYLOAD; tx_cmd[1] = 0; - nrf24_spi_trx(handle, tx_cmd, tmp_packet, packet_size + 1); - memcpy(packet, &tmp_packet[1], packet_size); + memset(buf, 0, packet_size + 1); + buf[0] = R_RX_PAYLOAD; + nrf24_spi_trx(handle, buf, buf, packet_size + 1); + memcpy(packet, &buf[1], packet_size); nrf24_write_reg(handle, REG_STATUS, RX_DR); // clear RX_DR } - if(status & (TX_DS | MAX_RT)) { // MAX_RT, TX_DS - nrf24_write_reg(handle, REG_STATUS, (TX_DS | MAX_RT)); // clear RX_DR, MAX_RT. - } + // if(status & (TX_DS | MAX_RT)) { // MAX_RT, TX_DS + // nrf24_write_reg(handle, REG_STATUS, (TX_DS | MAX_RT)); // clear RX_DR, MAX_RT. + // } *ret_packetsize = packet_size; return status; @@ -225,28 +226,21 @@ uint8_t nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* re // Return 0 when error uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack) { uint8_t status = 0; - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(tx, 0, size + 1); - memset(rx, 0, size + 1); - - if(!ack) - tx[0] = W_TX_PAYLOAD_NOACK; - else - tx[0] = W_TX_PAYLOAD; - - memcpy(&tx[1], payload, size); - nrf24_spi_trx(handle, tx, rx, size + 1); + uint8_t buf[size + 1]; + buf[0] = ack ? W_TX_PAYLOAD : W_TX_PAYLOAD_NOACK; + memcpy(&buf[1], payload, size); nrf24_set_tx_mode(handle); - + nrf24_spi_trx(handle, buf, buf, size + 1); uint32_t start_time = furi_get_tick(); do { - furi_delay_ms(1); + furi_delay_us(100); status = nrf24_status(handle); - } while(!(status & (TX_DS | MAX_RT)) && furi_get_tick() - start_time < 500UL); - - if(status & MAX_RT) nrf24_flush_tx(handle); - + } while(!(status & (TX_DS | MAX_RT)) && furi_get_tick() - start_time < 100UL); + if(status & MAX_RT) { + if(furi_log_get_level() == FuriLogLevelDebug) FURI_LOG_D("NRF", "MAX RT: %X (%X)", nrf24_read_register(handle, REG_OBSERVE_TX), status); + nrf24_flush_tx(handle); + } + furi_hal_gpio_write(nrf24_CE_PIN, false); //nrf24_set_idle(handle); if(status & (TX_DS | MAX_RT)) nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); return status & TX_DS; @@ -268,109 +262,29 @@ uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) { nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); cfg &= 0xfc; // clear bottom two bits to power down the radio status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //nr204_write_reg(handle, REG_EN_RXADDR, 0x0); furi_hal_gpio_write(nrf24_CE_PIN, false); return status; } uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; uint8_t cfg = 0; - //status = nrf24_write_reg(handle, REG_CONFIG, 0x0F); // enable 2-byte CRC, PWR_UP, and PRIM_RX - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); + cfg = nrf24_read_register(handle, REG_CONFIG); cfg |= 0x03; // PWR_UP, and PRIM_RX - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //nr204_write_reg(REG_EN_RXADDR, 0x03) // Set RX Pipe 0 and 1 + cfg = nrf24_write_reg(handle, REG_CONFIG, cfg); furi_hal_gpio_write(nrf24_CE_PIN, true); - //furi_delay_ms(2); - return status; + return cfg; } uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; + uint8_t reg; furi_hal_gpio_write(nrf24_CE_PIN, false); - nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); - //status = nrf24_write_reg(handle, REG_CONFIG, 0x0E); // enable 2-byte CRC, PWR_UP - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xFE; // disable PRIM_RX - cfg |= 0x02; // PWR_UP - status = nrf24_write_reg(handle, REG_CONFIG, cfg); + //nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); + reg = nrf24_read_register(handle, REG_CONFIG); + reg &= ~0x01; // disable PRIM_RX + reg |= 0x02; // PWR_UP + reg = nrf24_write_reg(handle, REG_CONFIG, reg); furi_hal_gpio_write(nrf24_CE_PIN, true); - //furi_delay_ms(2); - return status; -} - -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) { - assert(channel <= 125); - assert(rate == 1 || rate == 2); - if(rate == 2) - rate = 8; // 2Mbps - else - rate = 0; // 1Mbps - - nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF - nrf24_set_idle(handle); - nrf24_write_reg(handle, REG_STATUS, 0x70); // clear interrupts - if(disable_aa) - nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst - else - nrf24_write_reg(handle, REG_EN_AA, 0x1F); // Enable Shockburst - - nrf24_write_reg(handle, REG_DYNPD, 0x3F); // enable dynamic payload length on all pipes - if(noack) - nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack - else { - nrf24_write_reg(handle, REG_CONFIG, 0x0C); // 2 byte CRC - nrf24_write_reg(handle, REG_FEATURE, 0x07); // enable dyn payload and ack - nrf24_write_reg( - handle, REG_SETUP_RETR, 0x1f); // 15 retries for AA, 500us auto retransmit delay - } - - nrf24_set_idle(handle); - nrf24_flush_rx(handle); - nrf24_flush_tx(handle); - - if(maclen) nrf24_set_maclen(handle, maclen); - if(srcmac) nrf24_set_src_mac(handle, srcmac, maclen); - if(dstmac) nrf24_set_dst_mac(handle, dstmac, maclen); - - nrf24_write_reg(handle, REG_RF_CH, channel); - nrf24_write_reg(handle, REG_RF_SETUP, rate); - furi_delay_ms(200); -} - -void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate) { - //uint8_t preamble[] = {0x55, 0x00}; // little endian - uint8_t preamble[] = {0xAA, 0x00}; // little endian - //uint8_t preamble[] = {0x00, 0x55}; // little endian - //uint8_t preamble[] = {0x00, 0xAA}; // little endian - nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF - nrf24_write_reg(handle, REG_STATUS, 0x70); // clear interrupts - nrf24_write_reg(handle, REG_DYNPD, 0x0); // disable shockburst - nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst - nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack - nrf24_set_maclen(handle, 2); // shortest address - nrf24_set_src_mac(handle, preamble, 2); // set src mac to preamble bits to catch everything - nrf24_set_packetlen(handle, 32); // set max packet length - nrf24_set_idle(handle); - nrf24_flush_rx(handle); - nrf24_flush_tx(handle); - nrf24_write_reg(handle, REG_RF_CH, channel); - nrf24_write_reg(handle, REG_RF_SETUP, rate); - - // prime for RX, no checksum - nrf24_write_reg(handle, REG_CONFIG, 0x03); // PWR_UP and PRIM_RX, disable AA and CRC - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(100); + return reg; } void hexlify(uint8_t* in, uint8_t size, char* out) { @@ -439,95 +353,6 @@ void int16_to_bytes(uint16_t val, uint8_t* out, bool bigendian) { } } -// handle iffyness with preamble processing sometimes being a bit (literally) off -void alt_address_old(uint8_t* packet, uint8_t* altaddr) { - uint8_t macmess_hi_b[4]; - uint8_t macmess_lo_b[2]; - uint32_t macmess_hi; - uint16_t macmess_lo; - uint8_t preserved; - - // get first 6 bytes into 32-bit and 16-bit variables - memcpy(macmess_hi_b, packet, 4); - memcpy(macmess_lo_b, packet + 4, 2); - - macmess_hi = bytes_to_int32(macmess_hi_b, true); - - //preserve least 7 bits from hi that will be shifted down to lo - preserved = macmess_hi & 0x7f; - macmess_hi >>= 7; - - macmess_lo = bytes_to_int16(macmess_lo_b, true); - macmess_lo >>= 7; - macmess_lo = (preserved << 9) | macmess_lo; - int32_to_bytes(macmess_hi, macmess_hi_b, true); - int16_to_bytes(macmess_lo, macmess_lo_b, true); - memcpy(altaddr, &macmess_hi_b[1], 3); - memcpy(altaddr + 3, macmess_lo_b, 2); -} - -bool validate_address(uint8_t* addr) { - uint8_t bad[][3] = {{0x55, 0x55}, {0xAA, 0xAA}, {0x00, 0x00}, {0xFF, 0xFF}}; - for(int i = 0; i < 4; i++) - for(int j = 0; j < 2; j++) - if(!memcmp(addr + j * 2, bad[i], 2)) return false; - - return true; -} - -bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address) { - bool found = false; - uint8_t packet[32] = {0}; - uint8_t packetsize; - //char printit[65]; - uint8_t status = 0; - status = nrf24_rxpacket(handle, packet, &packetsize, true); - if(status & 0x40) { - if(validate_address(packet)) { - for(int i = 0; i < maclen; i++) address[i] = packet[maclen - 1 - i]; - - /* - alt_address(packet, packet); - - for(i = 0; i < maclen; i++) - address[i + 5] = packet[maclen - 1 - i]; - */ - - //memcpy(address, packet, maclen); - //hexlify(packet, packetsize, printit); - found = true; - } - } - - return found; -} - -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) { - uint8_t ping_packet[] = {0x0f, 0x0f, 0x0f, 0x0f}; // this can be anything, we just need an ack - uint8_t ch = max_channel + 1; // means fail - nrf24_configure(handle, rate, srcmac, dstmac, maclen, 2, false, false); - for(ch = min_channel; ch <= max_channel + 1; ch++) { - nrf24_write_reg(handle, REG_RF_CH, ch); - if(nrf24_txpacket(handle, ping_packet, 4, true)) break; - } - - if(autoinit) { - FURI_LOG_D("nrf24", "initializing radio for channel %d", ch); - nrf24_configure(handle, rate, srcmac, dstmac, maclen, ch, false, false); - return ch; - } - - return ch; -} - uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t *mac, uint8_t mlen) { uint8_t addr[5]; diff --git a/lib/nrf24/nrf24.h b/lib/nrf24/nrf24.h index cd994dc4064..a05ddbebc35 100644 --- a/lib/nrf24/nrf24.h +++ b/lib/nrf24/nrf24.h @@ -39,6 +39,7 @@ extern "C" { #define REG_RF_CH 0x05 #define REG_TX_ADDR 0x10 #define REG_FIFO_STATUS 0x17 +#define REG_OBSERVE_TX 0x08 #define RX_PW_P0 0x11 #define RX_PW_P1 0x12 @@ -49,6 +50,7 @@ extern "C" { #define RX_DR 0x40 #define TX_DS 0x20 #define MAX_RT 0x10 +#define NRF24_EN_DYN_ACK 0x01 #define nrf24_TIMEOUT 500 #define nrf24_CE_PIN &gpio_ext_pb2 @@ -87,6 +89,9 @@ uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* d */ uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); +// Read single register (1 byte) +uint8_t nrf24_read_register(FuriHalSpiBusHandle* handle, uint8_t reg); + /** Power up the radio for operation * * @param handle - pointer to FuriHalSpiHandle diff --git a/nrf24batch.c b/nrf24batch.c index e62e1316d27..ce63b59e7ca 100644 --- a/nrf24batch.c +++ b/nrf24batch.c @@ -20,14 +20,8 @@ #define SCAN_APP_PATH_FOLDER "/ext/nrf24batch" #define LOG_FILENAME "log" #define LOG_FILEEXT ".txt" -#define MAX_LOG_RECORDS 200 -#define MAX_FOUND_RECORDS 70 -#define LOG_REC_SIZE 34 // max packet size -#define VIEW_LOG_MAX_X 22 -#define VIEW_LOG_WIDTH_B 10 // bytes -#define NRF_REPEAT_ATTEMPTS 3 -#define NRF_READ_TIMEOUT 700UL // ms -#define WORK_PERIOD 10 // ms, frequency of individual cmds +#define NRF_READ_TIMEOUT 300UL // ms +#define WORK_PERIOD 2 // ms, frequency of individual cmds const char SettingsFld_Info[] = "Info:"; const char SettingsFld_Ch[] = "Ch:"; @@ -35,6 +29,7 @@ const char SettingsFld_Rate[] = "Rate:"; const char SettingsFld_DPL[] = "DPL:"; const char SettingsFld_CRC[] = "CRC:"; const char SettingsFld_Address[] = "Address:"; +const char SettingsFld_Resend[] = "Resend:"; const char SettingsFld_Delay[] = "Delay_ms:"; const char SettingsFld_WriteStart[] = "Write start:"; const char SettingsFld_Payload[] = "Payload struct:"; @@ -86,7 +81,8 @@ uint8_t NRF_AA_OFF; // Disable Auto Acknowledgement bool NRF_ERROR = 0; bool NRF_INITED = false; uint8_t NRF_last_packet_send_st = 0; -uint8_t NRF_repeat = 0; +uint8_t NRF_resend = 1; // number of transaction attempts +uint8_t NRF_repeat = 0; // count number of repeated requests (until < NRF_resend) uint32_t NRF_time; uint8_t addr[5]; // nRF24 address, MSB first @@ -98,6 +94,7 @@ uint8_t payload_fields = 0; uint8_t payload_size = 0; // bytes FuriString *ReadDefault = NULL; FuriString *WriteDefault = NULL; +FuriString *WriteStart = NULL; uint32_t delay_between_pkt = 5;// ms FuriString *Constants = NULL; // text of STR=x FuriString **Read_cmd = NULL; // Names of read cmd @@ -191,6 +188,10 @@ void free_store(void) furi_string_free(WriteDefault); WriteDefault = NULL; } + if(WriteStart) { + furi_string_free(WriteStart); + WriteDefault = NULL; + } if(Read_cmd_Total) { for(uint16_t i = 0; i < Read_cmd_Total; i++) furi_string_free(Read_cmd[i]); Read_cmd_Total = 0; @@ -248,60 +249,66 @@ static bool select_settings_file() { static void prepare_nrf24(void) { - if(NRF_INITED) return; - nrf24_write_reg(nrf24_HANDLE, REG_STATUS, 0x70); // clear interrupts - nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel); - nrf24_write_reg(nrf24_HANDLE, REG_RF_SETUP, (NRF_rate == 0 ? 0b00100000 : NRF_rate == 1 ? 0 : 0b00001000) | 0b111); // +TX high power - nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70 | ((NRF_CRC == 1 ? 0b1000 : NRF_CRC == 2 ? 0b1100 : 0))); // Mask all interrupts - nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0b00010111); // Automatic Retransmission, 0.5ms, 7 times - nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x01); // Auto acknowledgement - nrf24_write_reg(nrf24_HANDLE, REG_FEATURE, NRF_DPL ? 4+1 : 1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload - nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg - nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload_size); - nrf24_set_maclen(nrf24_HANDLE, addr_len); - nrf24_set_mac(REG_RX_ADDR_P0, addr, addr_len); - uint8_t tmp[5] = { 0 }; - nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, addr_len); - for(uint8_t i = 0; i < addr_len / 2; i++) { - uint8_t tb = tmp[i]; - tmp[i] = tmp[addr_len - i - 1]; - tmp[addr_len - i - 1] = tb; + if(!NRF_INITED) { + nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel); + nrf24_write_reg(nrf24_HANDLE, REG_RF_SETUP, (NRF_rate == 0 ? 0b00100000 : NRF_rate == 1 ? 0 : 0b00001000) | 0b111); // +TX high power + nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70 | ((NRF_CRC == 1 ? 0b1000 : NRF_CRC == 2 ? 0b1100 : 0))); // Mask all interrupts + nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, ((NRF_rate == 0 ? 0b0010 : 0b0001)<<4) | 0b0111); // Automatic Retransmission, ARD, ARC + nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x01); // Auto acknowledgement + nrf24_write_reg(nrf24_HANDLE, REG_FEATURE, NRF24_EN_DYN_ACK | (NRF_DPL ? 4 : 0)); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload + nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg + nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload_size); + nrf24_set_maclen(nrf24_HANDLE, addr_len); + nrf24_set_mac(REG_RX_ADDR_P0, addr, addr_len); + uint8_t tmp[5] = { 0 }; + nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, addr_len); + for(uint8_t i = 0; i < addr_len / 2; i++) { + uint8_t tb = tmp[i]; + tmp[i] = tmp[addr_len - i - 1]; + tmp[addr_len - i - 1] = tb; + } + NRF_ERROR = memcmp(addr, tmp, addr_len) != 0; + nrf24_set_mac(REG_TX_ADDR, addr, addr_len); + nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, 1); + //nrf24_set_idle(nrf24_HANDLE); + NRF_INITED = true; } - NRF_ERROR = memcmp(addr, tmp, addr_len) != 0; - nrf24_set_mac(REG_TX_ADDR, addr, addr_len); - nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, 1); - nrf24_flush_rx(nrf24_HANDLE); nrf24_flush_tx(nrf24_HANDLE); - //nrf24_set_idle(nrf24_HANDLE); - NRF_INITED = true; + nrf24_flush_rx(nrf24_HANDLE); + nrf24_write_reg(nrf24_HANDLE, REG_STATUS, MAX_RT | RX_DR | TX_DS); + furi_hal_gpio_write(nrf24_CE_PIN, false); } // true - ok uint8_t nrf24_send_packet() { if(furi_log_get_level() == FuriLogLevelDebug) { - char buf[64]; buf[0] = 0; add_to_str_hex_bytes(buf, payload, payload_size); FURI_LOG_D(TAG, "SEND: %s", buf); - } - // nrf24_write_reg(nrf24_HANDLE, REG_STATUS, RX_DR | TX_DS | MAX_RT); - // nrf24_flush_rx(nrf24_HANDLE); - if(nrf24_status(nrf24_HANDLE) & MAX_RT) { - nrf24_flush_tx(nrf24_HANDLE); - nrf24_write_reg(nrf24_HANDLE, REG_STATUS, MAX_RT); + char buf[65]; buf[0] = 0; add_to_str_hex_bytes(buf, payload, payload_size); FURI_LOG_D(TAG, "SEND: %s", buf); } - NRF_last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, payload, payload_size, true); - NRF_time = furi_get_tick(); - FURI_LOG_D(TAG, "Send packet = %d", NRF_last_packet_send_st); + //nrf24_flush_tx(nrf24_HANDLE); + //nrf24_write_reg(nrf24_HANDLE, REG_STATUS, RX_DR | TX_DS | MAX_RT); + NRF_last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, payload, payload_size, true); // ACK if(NRF_last_packet_send_st) { if((rw_type == rwt_read_cmd || rw_type == rwt_read_batch) && send_status == sst_sending) { // Read nrf24_set_rx_mode(nrf24_HANDLE); send_status = sst_receiving; // receiving - FURI_LOG_D(TAG, "Receiving..."); } - } else notification_message(APP->notification, &sequence_blink_red_100); + NRF_time = furi_get_tick(); + FURI_LOG_D(TAG, "Send packet: %d%s", rw_type, send_status, NRF_last_packet_send_st, send_status == sst_receiving ? ", Receiving" : ""); return NRF_last_packet_send_st; } +uint8_t nrf24_resend_packet() +{ + if(Log_Total) { + FuriString *str = Log[Log_Total - 1]; + char *p = strstr(furi_string_get_cstr(str), ": "); + if(p) furi_string_left(str, p - furi_string_get_cstr(str) + 2); + } + return nrf24_send_packet(); +} + // true - new packet bool nrf24_read_newpacket() { bool found = false; @@ -310,7 +317,7 @@ bool nrf24_read_newpacket() { if(st & RX_DR) { NRF_time = furi_get_tick(); if(furi_log_get_level() == FuriLogLevelDebug) { - char buf[64]; buf[0] = 0; add_to_str_hex_bytes(buf, payload_receive, packetsize); FURI_LOG_D(TAG, "READ: %s", buf); + char buf[65]; buf[0] = 0; add_to_str_hex_bytes(buf, payload_receive, packetsize); FURI_LOG_D(TAG, "READ(%X): %s", st, buf); } if(Log_Total) { FuriString *str = Log[Log_Total - 1]; @@ -343,9 +350,9 @@ bool nrf24_read_newpacket() { if(--cmd_array_cnt) { furi_string_cat_str(str, ","); payload[cmd_array_idx]++; - furi_delay_ms(delay_between_pkt); + NRF_repeat = 0; send_status = sst_sending; - if(!nrf24_send_packet()) send_status = sst_error; + nrf24_send_packet(); } else send_status = sst_ok; } else { if(size == 0) { // string, until '\0' @@ -460,10 +467,10 @@ bool Run_Read_cmd(FuriString *cmd) if(cmd_array_cnt > 1) cmd_array = true; // array } } - NRF_repeat = 0; prepare_nrf24(); if(NRF_ERROR) return false; what_doing = 2; + NRF_repeat = 0; send_status = sst_sending; // Read - sending nrf24_send_packet(); return true; @@ -509,12 +516,27 @@ bool Run_WriteBatch_cmd(FuriString *cmd) { char *p; send_status = sst_none; + prepare_nrf24(); + if(NRF_ERROR) return false; if(cmd) { p = strchr((char*)furi_string_get_cstr(cmd), ':'); if(p == NULL) return false; p += 2; WriteBatch_cmd_curr = NULL; free_Log(); + if(WriteStart) { + if(!fill_payload((char*)furi_string_get_cstr(WriteStart), NULL, VAR_EMPTY)) return false; + send_status = sst_sending; + uint8_t i = 0; + do { + if(nrf24_send_packet()) break; + furi_delay_ms(delay_between_pkt); + } while(i++ < NRF_resend); + if(i >= NRF_resend && i) { // not ok + send_status = sst_error; + return false; + } + } } else { if(WriteBatch_cmd_curr) p = WriteBatch_cmd_curr; else return false; } @@ -566,9 +588,6 @@ bool Run_WriteBatch_cmd(FuriString *cmd) if(strncmp(p, w, len) != 0) continue; delim_col++; str_rtrim(delim_col); - NRF_repeat = 0; - prepare_nrf24(); - if(NRF_ERROR) return false; cmd_array_cnt = 255; do { memset(payload, 0, sizeof(payload)); @@ -577,13 +596,14 @@ bool Run_WriteBatch_cmd(FuriString *cmd) if(cmd_array && cmd_array_idx != 255) { if(cmd_array_cnt != 255) payload[cmd_array_idx] = cmd_array_cnt; } else cmd_array = false; - send_status = sst_sending; // Read - sending + send_status = sst_sending; + NRF_repeat = 0; uint8_t i = 0; - for(; i < NRF_repeat; i++) { + do { if(nrf24_send_packet()) break; furi_delay_ms(delay_between_pkt); - } - if(i < NRF_repeat) { + } while(i++ < NRF_resend); + if(i < NRF_resend || i == 0) { // ok if(cmd_array) { // array for(; arr != NULL;) { if(*arr == ',') break; @@ -644,6 +664,8 @@ static uint8_t load_settings_file() { NRF_CRC = atoi(p + sizeof(SettingsFld_CRC)); } else if(strncmp(p, SettingsFld_DPL, sizeof(SettingsFld_DPL)-1) == 0) { NRF_DPL = atoi(p + sizeof(SettingsFld_DPL)); + } else if(strncmp(p, SettingsFld_Resend, sizeof(SettingsFld_Resend)-1) == 0) { + NRF_resend = atoi(p + sizeof(SettingsFld_Resend)); } else if(strncmp(p, SettingsFld_Delay, sizeof(SettingsFld_Delay)-1) == 0) { delay_between_pkt = atoi(p + sizeof(SettingsFld_Delay)); } else if(strncmp(p, SettingsFld_Payload, sizeof(SettingsFld_Payload)-1) == 0) { @@ -666,6 +688,8 @@ static uint8_t load_settings_file() { FURI_LOG_D(TAG, "Payload fields %d: %d,%d,%d", payload_fields, payload_struct[0], payload_struct[1], payload_struct[2]); } else if(strncmp(p, SettingsFld_ReadDefault, sizeof(SettingsFld_ReadDefault)-1) == 0) { ReadDefault = furi_string_alloc_set_str(p + sizeof(SettingsFld_ReadDefault)); + } else if(strncmp(p, SettingsFld_WriteStart, sizeof(SettingsFld_WriteStart)-1) == 0) { + WriteStart = furi_string_alloc_set_str(p + sizeof(SettingsFld_WriteStart)); } else if(strncmp(p, SettingsFld_WriteDefault, sizeof(SettingsFld_WriteDefault)-1) == 0) { WriteDefault = furi_string_alloc_set_str(p + sizeof(SettingsFld_WriteDefault)); } else if(strncmp(p, SettingsFld_Read, sizeof(SettingsFld_Read)-1) == 0) { @@ -857,25 +881,24 @@ void work_timer_callback(void* ctx) } } else if(send_status == sst_sending) { // sending if(!NRF_last_packet_send_st) { // No ACK on last attempt - if(furi_get_tick() - NRF_time >= delay_between_pkt) { - if(++NRF_repeat < NRF_REPEAT_ATTEMPTS) nrf24_send_packet(); else send_status = sst_error; // error + if(furi_get_tick() - NRF_time > delay_between_pkt) { + if(NRF_repeat++ < NRF_resend) nrf24_resend_packet(); else send_status = sst_error; // error NO_ACK } } } else if(send_status == sst_receiving) { // receiving - for(uint8_t i = 0; i < 10; i++) { + for(uint8_t i = 0; i < 3; i++) { bool new = nrf24_read_newpacket(); if(new) { - if(send_status != sst_receiving) { - NRF_repeat = 0; - break; - } - } else if(furi_get_tick() - NRF_time >= NRF_READ_TIMEOUT) { - if(++NRF_repeat < NRF_REPEAT_ATTEMPTS) nrf24_send_packet(); - else { + if(send_status != sst_receiving) break; + } else if(furi_get_tick() - NRF_time > NRF_READ_TIMEOUT) { + if(NRF_repeat++ < NRF_resend) { + send_status = sst_sending; + nrf24_resend_packet(); + } else { FURI_LOG_D(TAG, "TIMEOUT: %lu", furi_get_tick() - NRF_time); send_status = sst_timeout; - break; } + break; } } } else if(send_status == sst_ok) { @@ -921,6 +944,12 @@ int32_t nrf24batch_app(void* p) { for(bool processing = true; processing;) { FuriStatus event_status = furi_message_queue_get(APP->event_queue, &event, 200); PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + + static FuriLogLevel FuriLogLevel = FuriLogLevelDefault; + if(furi_log_get_level() != FuriLogLevel) { + FuriLogLevel = furi_log_get_level(); + if(FuriLogLevel == FuriLogLevelDebug) furi_hal_uart_set_br(FuriHalUartIdUSART1, 460800); + } if(event_status == FuriStatusOk) { // press events