|
@@ -14,7 +14,7 @@
|
|
|
#include <u8g2.h>
|
|
#include <u8g2.h>
|
|
|
|
|
|
|
|
#define TAG "nrf24batch"
|
|
#define TAG "nrf24batch"
|
|
|
-#define VERSION "1.3"
|
|
|
|
|
|
|
+#define VERSION "1.4"
|
|
|
|
|
|
|
|
#define SCAN_APP_PATH_FOLDER "/ext/nrf24batch"
|
|
#define SCAN_APP_PATH_FOLDER "/ext/nrf24batch"
|
|
|
#define LOG_FILEEXT ".txt"
|
|
#define LOG_FILEEXT ".txt"
|
|
@@ -84,7 +84,8 @@ uint8_t NRF_CRC; // 1 - No, 1 - CRC 1byte, 2 - CRC 2byte
|
|
|
uint8_t NRF_RETR = ((0b0011<<4) | 0b1111); // Automatic Retransmission, ARD, ARC
|
|
uint8_t NRF_RETR = ((0b0011<<4) | 0b1111); // Automatic Retransmission, ARD, ARC
|
|
|
uint8_t NRF_Payload;// Payload len in bytes, 0..32
|
|
uint8_t NRF_Payload;// Payload len in bytes, 0..32
|
|
|
bool NRF_ERROR = 0;
|
|
bool NRF_ERROR = 0;
|
|
|
-bool NRF_INITED = false;
|
|
|
|
|
|
|
+uint8_t NRF_INITED = 0; // 0 - not, 1 - rw, rwt_listen - listen
|
|
|
|
|
+bool NRF_BOARD_POWER_5V = false;
|
|
|
uint8_t NRF_last_packet_send_st = 0;
|
|
uint8_t NRF_last_packet_send_st = 0;
|
|
|
uint8_t NRF_resend = 1; // number of transaction attempts
|
|
uint8_t NRF_resend = 1; // number of transaction attempts
|
|
|
uint8_t NRF_repeat = 0; // count number of repeated requests (until < NRF_resend)
|
|
uint8_t NRF_repeat = 0; // count number of repeated requests (until < NRF_resend)
|
|
@@ -92,7 +93,7 @@ uint32_t NRF_time;
|
|
|
uint32_t delay_between_pkt = 10;// ms
|
|
uint32_t delay_between_pkt = 10;// ms
|
|
|
|
|
|
|
|
uint8_t addr[5]; // nRF24 address, MSB first
|
|
uint8_t addr[5]; // nRF24 address, MSB first
|
|
|
-uint8_t addr_len; // 2..5
|
|
|
|
|
|
|
+uint8_t addr_len = 0; // 2..5
|
|
|
uint8_t payload[32];
|
|
uint8_t payload[32];
|
|
|
uint8_t payload_receive[32];
|
|
uint8_t payload_receive[32];
|
|
|
uint8_t payload_struct[32]; // sizeof(1..4) in bytes of each field, example: 2,1,1
|
|
uint8_t payload_struct[32]; // sizeof(1..4) in bytes of each field, example: 2,1,1
|
|
@@ -112,7 +113,8 @@ FuriString *ReadDefault = NULL;
|
|
|
FuriString *WriteDefault = NULL;
|
|
FuriString *WriteDefault = NULL;
|
|
|
FuriString *WriteStart = NULL;
|
|
FuriString *WriteStart = NULL;
|
|
|
FuriString *Constants = NULL; // text of STR=x
|
|
FuriString *Constants = NULL; // text of STR=x
|
|
|
-char *ListenAddr = NULL;
|
|
|
|
|
|
|
+uint8_t listen_addr[5];
|
|
|
|
|
+uint8_t listen_addr_len = 0;
|
|
|
char *ListenFields = NULL; // ptr to string: field1,field2,... max 5 field now
|
|
char *ListenFields = NULL; // ptr to string: field1,field2,... max 5 field now
|
|
|
bool ListenNew;
|
|
bool ListenNew;
|
|
|
FuriHalRtcDateTime ListenLastTime = { 0 };
|
|
FuriHalRtcDateTime ListenLastTime = { 0 };
|
|
@@ -152,7 +154,7 @@ static bool ask_fill_screen_buf(void)
|
|
|
//#define MIN(a, b) ((a<b)?a:b)
|
|
//#define MIN(a, b) ((a<b)?a:b)
|
|
|
|
|
|
|
|
static uint8_t GetHexVal(char hex) {
|
|
static uint8_t GetHexVal(char hex) {
|
|
|
- return (uint8_t)hex - ((uint8_t)hex < 58 ? 48 : ((uint8_t)hex < 97 ? 55 : 87));
|
|
|
|
|
|
|
+ return hex == 0 ? 0 : ((uint8_t)hex - ((uint8_t)hex < 58 ? 48 : ((uint8_t)hex < 97 ? 55 : 87)));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static bool is_digit(char *ptr, bool hex)
|
|
static bool is_digit(char *ptr, bool hex)
|
|
@@ -245,10 +247,6 @@ void free_store(void)
|
|
|
furi_string_free(WriteStart);
|
|
furi_string_free(WriteStart);
|
|
|
WriteDefault = NULL;
|
|
WriteDefault = NULL;
|
|
|
}
|
|
}
|
|
|
- if(ListenAddr) {
|
|
|
|
|
- free(ListenAddr);
|
|
|
|
|
- ListenAddr = NULL;
|
|
|
|
|
- }
|
|
|
|
|
if(ListenFields) {
|
|
if(ListenFields) {
|
|
|
free(ListenFields);
|
|
free(ListenFields);
|
|
|
ListenFields = NULL;
|
|
ListenFields = NULL;
|
|
@@ -307,7 +305,30 @@ static bool select_settings_file() {
|
|
|
|
|
|
|
|
static void prepare_nrf24(void)
|
|
static void prepare_nrf24(void)
|
|
|
{
|
|
{
|
|
|
- if(!NRF_INITED) {
|
|
|
|
|
|
|
+ if(!NRF_INITED || !((rw_type == rwt_listen) == (NRF_INITED == rwt_listen))) {
|
|
|
|
|
+ uint8_t adrlen, *adr;
|
|
|
|
|
+ if(rw_type == rwt_listen) {
|
|
|
|
|
+ adrlen = listen_addr_len;
|
|
|
|
|
+ adr = listen_addr;
|
|
|
|
|
+ NRF_INITED = rwt_listen;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ adrlen = addr_len;
|
|
|
|
|
+ adr = addr;
|
|
|
|
|
+ NRF_INITED = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ nrf24_set_mac(REG_RX_ADDR_P0, adr, adrlen);
|
|
|
|
|
+ uint8_t tmp[5] = { 0 };
|
|
|
|
|
+ nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, adrlen);
|
|
|
|
|
+ for(uint8_t i = 0; i < adrlen / 2; i++) {
|
|
|
|
|
+ uint8_t tb = tmp[i];
|
|
|
|
|
+ tmp[i] = tmp[adrlen - i - 1];
|
|
|
|
|
+ tmp[adrlen - i - 1] = tb;
|
|
|
|
|
+ }
|
|
|
|
|
+ NRF_ERROR = memcmp(adr, tmp, adrlen) != 0;
|
|
|
|
|
+ if(NRF_ERROR) {
|
|
|
|
|
+ NRF_INITED = 0;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel);
|
|
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_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_CONFIG, 0x70 | ((NRF_CRC == 1 ? 0b1000 : NRF_CRC == 2 ? 0b1100 : 0))); // Mask all interrupts
|
|
@@ -316,17 +337,8 @@ static void prepare_nrf24(void)
|
|
|
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_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, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg
|
|
|
nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload_size);
|
|
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_set_maclen(nrf24_HANDLE, adrlen);
|
|
|
|
|
+ nrf24_set_mac(REG_TX_ADDR, adr, adrlen);
|
|
|
nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, 1);
|
|
nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, 1);
|
|
|
//nrf24_set_idle(nrf24_HANDLE);
|
|
//nrf24_set_idle(nrf24_HANDLE);
|
|
|
NRF_INITED = true;
|
|
NRF_INITED = true;
|
|
@@ -818,16 +830,11 @@ static uint8_t load_settings_file() {
|
|
|
p += sizeof(SettingsFld_Listen);
|
|
p += sizeof(SettingsFld_Listen);
|
|
|
char *p2 = strchr(p, '=');
|
|
char *p2 = strchr(p, '=');
|
|
|
if(p2) {
|
|
if(p2) {
|
|
|
- uint8_t len = p2 - p;
|
|
|
|
|
- ListenAddr = malloc(len + 1);
|
|
|
|
|
- if(ListenAddr) {
|
|
|
|
|
- memcpy(ListenAddr, p, len);
|
|
|
|
|
- ListenAddr[len] = '\0';
|
|
|
|
|
- p2++;
|
|
|
|
|
- len = strlen(p2);
|
|
|
|
|
- ListenFields = malloc(len + 1);
|
|
|
|
|
- if(ListenFields) memcpy(ListenFields, p2, len);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ listen_addr_len = ConvertHexToArray(p, listen_addr, (p2 - p) / 2);
|
|
|
|
|
+ p2++;
|
|
|
|
|
+ uint8_t len = strlen(p2);
|
|
|
|
|
+ ListenFields = malloc(len + 1);
|
|
|
|
|
+ if(ListenFields) memcpy(ListenFields, p2, len);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -981,7 +988,12 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
|
|
canvas_set_font(canvas, FontSecondary); // 8x10 font, 6 lines
|
|
canvas_set_font(canvas, FontSecondary); // 8x10 font, 6 lines
|
|
|
canvas_draw_str(canvas, 0, 10, "Listen mode");
|
|
canvas_draw_str(canvas, 0, 10, "Listen mode");
|
|
|
canvas_draw_str(canvas, 0, 25, "Address:");
|
|
canvas_draw_str(canvas, 0, 25, "Address:");
|
|
|
- if(Edit) display_edit_ttf_font(canvas, 40, 25); else if(ListenAddr) canvas_draw_str(canvas, 40, 25, ListenAddr);
|
|
|
|
|
|
|
+ if(Edit) display_edit_ttf_font(canvas, 40, 25);
|
|
|
|
|
+ else if(listen_addr_len) {
|
|
|
|
|
+ screen_buf[0] = '\0';
|
|
|
|
|
+ add_to_str_hex_bytes(screen_buf, listen_addr, listen_addr_len);
|
|
|
|
|
+ canvas_draw_str(canvas, 40, 25, screen_buf);
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines, 25 cols
|
|
canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines, 25 cols
|
|
|
if(rw_type == rwt_read_batch) {
|
|
if(rw_type == rwt_read_batch) {
|
|
@@ -1031,7 +1043,8 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
|
|
for(uint8_t i = 0; i < 5 && *p; i++) {
|
|
for(uint8_t i = 0; i < 5 && *p; i++) {
|
|
|
hex = false;
|
|
hex = false;
|
|
|
p2 = strchr(p, ',');
|
|
p2 = strchr(p, ',');
|
|
|
- if(p2 == NULL) p2 = p + strlen(p); else if(*(p2 - 1) == '#') hex = true;
|
|
|
|
|
|
|
+ if(p2 == NULL) p2 = p + strlen(p);
|
|
|
|
|
+ if(*(p2 - 1) == '#') hex = true;
|
|
|
memcpy(screen_buf, p, len = p2 - p);
|
|
memcpy(screen_buf, p, len = p2 - p);
|
|
|
strcpy(screen_buf + len, ": ");
|
|
strcpy(screen_buf + len, ": ");
|
|
|
if(ListenNew) {
|
|
if(ListenNew) {
|
|
@@ -1178,7 +1191,6 @@ int32_t nrf24batch_app(void* p) {
|
|
|
free(APP->plugin_state);
|
|
free(APP->plugin_state);
|
|
|
return 255;
|
|
return 255;
|
|
|
}
|
|
}
|
|
|
- nrf24_init();
|
|
|
|
|
|
|
|
|
|
// Set system callbacks
|
|
// Set system callbacks
|
|
|
APP->view_port = view_port_alloc();
|
|
APP->view_port = view_port_alloc();
|
|
@@ -1194,6 +1206,12 @@ int32_t nrf24batch_app(void* p) {
|
|
|
file_stream = file_stream_alloc(APP->storage);
|
|
file_stream = file_stream_alloc(APP->storage);
|
|
|
FuriTimer *work_timer = furi_timer_alloc(work_timer_callback, FuriTimerTypePeriodic, NULL);
|
|
FuriTimer *work_timer = furi_timer_alloc(work_timer_callback, FuriTimerTypePeriodic, NULL);
|
|
|
furi_timer_start(work_timer, WORK_PERIOD);
|
|
furi_timer_start(work_timer, WORK_PERIOD);
|
|
|
|
|
+ if(!furi_hal_power_is_otg_enabled()) {
|
|
|
|
|
+ furi_hal_power_enable_otg();
|
|
|
|
|
+ NRF_BOARD_POWER_5V = true;
|
|
|
|
|
+ furi_delay_ms(100);
|
|
|
|
|
+ }
|
|
|
|
|
+ nrf24_init();
|
|
|
|
|
|
|
|
PluginEvent event;
|
|
PluginEvent event;
|
|
|
for(bool processing = true; processing;) {
|
|
for(bool processing = true; processing;) {
|
|
@@ -1337,8 +1355,8 @@ int32_t nrf24batch_app(void* p) {
|
|
|
}
|
|
}
|
|
|
ask_question = 0;
|
|
ask_question = 0;
|
|
|
} else if(Edit) { // insert digit
|
|
} else if(Edit) { // insert digit
|
|
|
- if(what_doing == 0) {
|
|
|
|
|
- if(strlen(Edit_start) < (setup_cursor == 1 ? 5 * 2 : 3)) {
|
|
|
|
|
|
|
+ if(what_doing <= 1) {
|
|
|
|
|
+ if(strlen(Edit_start) < (what_doing == 0 && setup_cursor == 2 ? 3 : 5 * 2)) {
|
|
|
memmove(Edit_pos + 1, Edit_pos, strlen(Edit_pos) + 1);
|
|
memmove(Edit_pos + 1, Edit_pos, strlen(Edit_pos) + 1);
|
|
|
*Edit_pos = '0';
|
|
*Edit_pos = '0';
|
|
|
}
|
|
}
|
|
@@ -1448,7 +1466,7 @@ int32_t nrf24batch_app(void* p) {
|
|
|
}
|
|
}
|
|
|
} else if(event.input.type == InputTypeLong) {
|
|
} else if(event.input.type == InputTypeLong) {
|
|
|
if(Edit) { // delete
|
|
if(Edit) { // delete
|
|
|
- if(what_doing == 0) {
|
|
|
|
|
|
|
+ if(what_doing <= 1) {
|
|
|
if(strlen(Edit_start) > 1) {
|
|
if(strlen(Edit_start) > 1) {
|
|
|
memmove(Edit_pos, Edit_pos + 1, strlen(Edit_pos) + 1);
|
|
memmove(Edit_pos, Edit_pos + 1, strlen(Edit_pos) + 1);
|
|
|
if(*Edit_pos == '\0') Edit_pos--;
|
|
if(*Edit_pos == '\0') Edit_pos--;
|
|
@@ -1462,11 +1480,14 @@ int32_t nrf24batch_app(void* p) {
|
|
|
}
|
|
}
|
|
|
} else if(what_doing == 1) {
|
|
} else if(what_doing == 1) {
|
|
|
if(rw_type == rwt_listen) {
|
|
if(rw_type == rwt_listen) {
|
|
|
- NRF_INITED = false;
|
|
|
|
|
- Edit_start = ListenAddr;
|
|
|
|
|
- Edit_pos = ListenAddr + strlen(ListenAddr) - 1;
|
|
|
|
|
|
|
+ char *ebuf = (char*)payload;
|
|
|
|
|
+ ebuf[0] = '\0';
|
|
|
|
|
+ add_to_str_hex_bytes(ebuf, listen_addr, listen_addr_len);
|
|
|
Edit_hex = true;
|
|
Edit_hex = true;
|
|
|
|
|
+ Edit_pos = ebuf + strlen(ebuf) - 1;
|
|
|
|
|
+ Edit_start = ebuf;
|
|
|
Edit = 1;
|
|
Edit = 1;
|
|
|
|
|
+ NRF_INITED = false;
|
|
|
}
|
|
}
|
|
|
} else if(what_doing == 2 && Log_Total) {
|
|
} else if(what_doing == 2 && Log_Total) {
|
|
|
if(rw_type == rwt_write_batch) {
|
|
if(rw_type == rwt_write_batch) {
|
|
@@ -1495,6 +1516,8 @@ int32_t nrf24batch_app(void* p) {
|
|
|
NRF_channel = str_to_int((char*)payload);
|
|
NRF_channel = str_to_int((char*)payload);
|
|
|
if(NRF_channel > MAX_CHANNEL) NRF_channel = MAX_CHANNEL;
|
|
if(NRF_channel > MAX_CHANNEL) NRF_channel = MAX_CHANNEL;
|
|
|
}
|
|
}
|
|
|
|
|
+ } else if(what_doing == 1 && rw_type == rwt_listen) {
|
|
|
|
|
+ listen_addr_len = ConvertHexToArray((char*)payload, listen_addr, 5);
|
|
|
}
|
|
}
|
|
|
Edit = 0;
|
|
Edit = 0;
|
|
|
} else {
|
|
} else {
|
|
@@ -1522,6 +1545,7 @@ int32_t nrf24batch_app(void* p) {
|
|
|
}
|
|
}
|
|
|
nrf24_set_idle(nrf24_HANDLE);
|
|
nrf24_set_idle(nrf24_HANDLE);
|
|
|
nrf24_deinit();
|
|
nrf24_deinit();
|
|
|
|
|
+ if(NRF_BOARD_POWER_5V) furi_hal_power_disable_otg();
|
|
|
|
|
|
|
|
view_port_enabled_set(APP->view_port, false);
|
|
view_port_enabled_set(APP->view_port, false);
|
|
|
gui_remove_view_port(APP->gui, APP->view_port);
|
|
gui_remove_view_port(APP->gui, APP->view_port);
|