diff --git a/comm/interfaces.c b/comm/interfaces.c index 13086ec..2772182 100644 --- a/comm/interfaces.c +++ b/comm/interfaces.c @@ -18,7 +18,7 @@ enum ComportSelection gActiveComport = COMPORT_USB; // start with USB so the han static uint32_t last_switch_time = 0; // started with USB static bool xfer_verify_done = false; -static void configure_interface(enum ComportSelection iface); +static bool configure_interface(enum ComportSelection iface); /** Switch com transfer if the current one doesnt seem to work */ void com_switch_transfer_if_needed(void) @@ -30,8 +30,8 @@ void com_switch_transfer_if_needed(void) if (gActiveComport == COMPORT_USB) { if (elapsed > 1000) { - // USB may or may not work, depending on whether the module is plugged - - // in or running from a battery/external supply remotely. + // USB may or may not work, depending on whether the module is plugged in + // or running from a battery/external supply remotely. // Check if USB is enumerated @@ -39,19 +39,30 @@ void com_switch_transfer_if_needed(void) if (0 == uadr) { dbg("Not enumerated, assuming USB is dead"); - // Fallback to bare USART - if (SystemSettings.use_comm_uart) { - configure_interface(COMPORT_USART); - } - else if (SystemSettings.use_comm_nordic) { - configure_interface(COMPORT_NORDIC); // this fallbacks to LoRa if LoRa enabled - } - else if (SystemSettings.use_comm_lora) { - configure_interface(COMPORT_LORA); - } - else { - dbg("No alternate com interface configured, leaving USB enabled."); - } + // Fallback to radio or bare USART + do { + if (SystemSettings.use_comm_nordic) { + if (configure_interface(COMPORT_NORDIC)) { + break; + } + } + + if (SystemSettings.use_comm_lora) { + if (configure_interface(COMPORT_LORA)) { + break; + } + } + + if (SystemSettings.use_comm_uart) { + // after nordic/lora + if (configure_interface(COMPORT_USART)) { + break; + } + } + + dbg("No alternate com interface configured."); + gActiveComport = COMPORT_NONE; + } while (0); } else { dbg("USB got address 0x%02x - OK", (int)uadr); } @@ -131,7 +142,7 @@ void com_iface_flush_buffer(void) } } -static void configure_interface(enum ComportSelection iface) +static bool configure_interface(enum ComportSelection iface) { // Teardown if (gActiveComport == COMPORT_USB) { @@ -146,11 +157,17 @@ static void configure_interface(enum ComportSelection iface) __HAL_RCC_USART2_CLK_DISABLE(); irqd_detach(USART2, com_UsartIrqHandler); } - gActiveComport = COMPORT_NONE; + else if (gActiveComport == COMPORT_NORDIC) { + // TODO + } + + + gActiveComport = iface; // Init if (iface == COMPORT_USB) { trap("illegal"); // this never happens + return false; } else if (iface == COMPORT_USART) { dbg("Setting up UART transfer"); @@ -171,37 +188,28 @@ static void configure_interface(enum ComportSelection iface) LL_USART_SetTransferDirection(USART2, LL_USART_DIRECTION_TX_RX); LL_USART_Enable(USART2); - } - else { - if (iface == COMPORT_NORDIC) { - // Try to configure nordic - dbg("Setting up nRF transfer"); - - // TODO set up and check nRF transport - // On failure, try setting up LoRa - dbg("nRF failed to init"); - if (SystemSettings.use_comm_lora) { - iface = COMPORT_LORA; - } else { - iface = COMPORT_NONE; // fail - } - } + return true; // always OK (TODO check voltage on Rx if it's 3V3 when idle?) + } + else if (iface == COMPORT_NORDIC) { + // Try to configure nordic + dbg("Setting up nRF transfer"); - if (iface == COMPORT_LORA) { - // Try to configure nordic - dbg("Setting up LoRa transfer"); + // TODO set up and check nRF transport - // TODO set up and check LoRa transport - dbg("LoRa failed to init"); - iface = COMPORT_NONE; // fail - } + // On failure, try setting up LoRa + dbg("nRF failed to init"); + return false; } - - if (iface == COMPORT_NONE) { - dbg("NO COM PORT AVAILABLE!"); + else if (iface == COMPORT_LORA) { + // Try to configure nordic + dbg("Setting up LoRa transfer"); + // TODO set up and check LoRa transport + dbg("LoRa failed to init"); + return false; + } + else { + trap("Bad iface %d", iface); } - - gActiveComport = iface; } diff --git a/comm/messages.c b/comm/messages.c index e1b679a..77c399d 100644 --- a/comm/messages.c +++ b/comm/messages.c @@ -58,26 +58,33 @@ static TF_Result lst_list_units(TinyFrame *tf, TF_Msg *msg) // --------------------------------------------------------------------------- -/** Callback for bulk read of the settings file */ -static void settings_bulkread_cb(BulkRead *bulk, uint32_t chunk, uint8_t *buffer) +/** Callback for bulk read of a settings file */ +static void ini_bulkread_cb(BulkRead *bulk, uint32_t chunk, uint8_t *buffer) { // clean-up request if (buffer == NULL) { free_ck(bulk); iw_end(); -// dbg("INI read complete."); return; } if (bulk->offset == 0) iw_begin(); IniWriter iw = iw_init((char *)buffer, bulk->offset, chunk); - iw.tag = 1; - settings_build_units_ini(&iw); + iw.tag = 1; // indicates this is read via the API (affects some comments) + + uint8_t filenum = (uint8_t) (int) bulk->userdata; + + if (filenum == 0) { + settings_build_units_ini(&iw); + } + else if (filenum == 1) { + settings_build_system_ini(&iw); + } } /** - * Listener: Export INI file via TF + * Listener: Export a file via TF */ static TF_Result lst_ini_export(TinyFrame *tf, TF_Msg *msg) { @@ -86,14 +93,29 @@ static TF_Result lst_ini_export(TinyFrame *tf, TF_Msg *msg) BulkRead *bulk = malloc_ck(sizeof(BulkRead)); assert_param(bulk != NULL); + uint8_t filenum = 0; + + // if any payload, the first byte defines the file to read + // 0 - units + // 1 - system + // (this is optional for backwards compatibility) + if (msg->len > 0) { + filenum = msg->data[0]; + } + bulk->frame_id = msg->frame_id; - bulk->len = iw_measure_total(settings_build_units_ini, 1); - bulk->read = settings_bulkread_cb; - bulk->userdata = NULL; + bulk->read = ini_bulkread_cb; + bulk->userdata = (void *) (int)filenum; + + if (filenum == 0) { + bulk->len = iw_measure_total(settings_build_units_ini, 1); + } + else if (filenum == 1) { + bulk->len = iw_measure_total(settings_build_system_ini, 1); + } bulkread_start(tf, bulk); Indicator_Effect(STATUS_DISK_BUSY_SHORT); - return TF_STAY; } @@ -142,7 +164,7 @@ static TF_Result lst_ini_import(TinyFrame *tf, TF_Msg *msg) PayloadParser pp = pp_start(msg->data, msg->len, NULL); uint32_t len = pp_u32(&pp); if (!pp.ok) { - com_respond_error(msg->frame_id, E_PROTOCOL_BREACH); + com_respond_error(msg->frame_id, E_MALFORMED_COMMAND); goto done; } @@ -151,11 +173,8 @@ static TF_Result lst_ini_import(TinyFrame *tf, TF_Msg *msg) settings_load_ini_begin(); ini_parse_begin(iniparser_cb, NULL); - bulkwrite_start(tf, bulk); - Indicator_Effect(STATUS_DISK_BUSY); - done: return TF_STAY; } diff --git a/framework/system_settings.c b/framework/system_settings.c index 8e49142..d8f462c 100644 --- a/framework/system_settings.c +++ b/framework/system_settings.c @@ -2,8 +2,6 @@ // Created by MightyPork on 2017/12/02. // -#include -#include #include "platform.h" #include "system_settings.h" #include "utils/str_utils.h" @@ -11,6 +9,8 @@ #include "cfg_utils.h" #include "resources.h" #include "unit_base.h" +#include "platform/debug_uart.h" +#include "comm/interfaces.h" static void systemsettings_mco_teardown(void); static void systemsettings_mco_init(void); @@ -171,18 +171,34 @@ void systemsettings_build_ini(IniWriter *iw) iw_entry_d(iw, "mco-prediv", (1< 0)"); + iw_entry(iw, "nrf-address", "%02X", + SystemSettings.nrf_address); + // those aren't implement yet, don't tease the user // TODO show pin-out, extra settings if applicable #if 0 - iw_comment(iw, "nRF24L01+"); - iw_entry_s(iw, "com-nordic", str_yn(SystemSettings.use_comm_nrf24l01p)); - iw_comment(iw, "LoRa/GFSK sx127x"); iw_entry_s(iw, "com-lora", str_yn(SystemSettings.use_comm_sx127x)); #endif @@ -241,12 +257,24 @@ bool systemsettings_load_ini(const char *restrict key, const char *restrict valu if (suc) SystemSettings.comm_uart_baud = baud; } -#if 0 - if (streq(key, "com-nordic")) { + if (streq(key, "com-nrf")) { bool yn = cfg_bool_parse(value, &suc); if (suc) SystemSettings.use_comm_nordic = yn; } + if (streq(key, "nrf-channel")) { + SystemSettings.nrf_channel = cfg_u8_parse(value, &suc); + } + + if (streq(key, "nrf-address")) { + cfg_hex_parse(&SystemSettings.nrf_address, 1, value, &suc); + } + + if (streq(key, "nrf-network")) { + cfg_hex_parse(&SystemSettings.nrf_network[0], 4, value, &suc); + } + +#if 0 if (streq(key, "com-lora")) { bool yn = cfg_bool_parse(value, &suc); if (suc) SystemSettings.use_comm_lora = yn; diff --git a/framework/system_settings.h b/framework/system_settings.h index 94cf4da..1f866e9 100644 --- a/framework/system_settings.h +++ b/framework/system_settings.h @@ -27,6 +27,9 @@ struct system_settings { uint32_t comm_uart_baud; // baud rate for the uart transport bool use_comm_lora; // SX1276/8 bool use_comm_nordic; // nRF24L01+ + uint8_t nrf_channel; + uint8_t nrf_network[4]; + uint8_t nrf_address; // Support flags put here for scoping, but not atcually part of the persistent settings volatile bool editable; //!< True if we booted with the LOCK jumper removed diff --git a/platform/cfg_utils.c b/platform/cfg_utils.c index b8bef60..e580e61 100644 --- a/platform/cfg_utils.c +++ b/platform/cfg_utils.c @@ -297,3 +297,46 @@ uint32_t cfg_enum4_parse(const char *value, *suc = false; return na; } + +void cfg_hex_parse(uint8_t *dest, uint32_t count, const char *value, bool *suc) +{ + // discard possible leading 0x + if (value[0] == '0' && value[1] == 'x') { + value += 2; + } + + uint8_t bytebuf = 0; + for (uint32_t digit = 0; digit < count * 2;) { + char v = *value; + if (v != 0) value++; + + uint8_t nibble = 0; + if (v == ' ' || v == '.' || v == '-' || v == ':') { + continue; // junk + } + else if (v >= '0' && v <= '9') { + nibble = (uint8_t) (v - '0'); + } + else if (v >= 'a' && v <= 'f') { + nibble = (uint8_t) (10 + (v - 'a')); + } + else if (v >= 'A' && v <= 'F') { + nibble = (uint8_t) (10 + (v - 'A')); + } + else if (v == 0) { + nibble = 0; // pad with zeros + } + else { + *suc = false; + return; + } + + digit++; + bytebuf <<= 4; + bytebuf |= nibble; + if ((digit % 2 == 0) && digit > 0) { // whole byte + *dest++ = bytebuf; + bytebuf = 0; + } + } +} diff --git a/platform/cfg_utils.h b/platform/cfg_utils.h index 05f8ebe..de34c19 100644 --- a/platform/cfg_utils.h +++ b/platform/cfg_utils.h @@ -116,6 +116,18 @@ uint32_t cfg_enum4_parse(const char *tpl, const char *d, uint32_t nd, bool *suc); +/** + * Parse a hexa string to a byte array. + * Skips 0x prefix, '.', '-', ':', ' '. + * + * @param[out] dest - storage array + * @param[in] count - expected number of bytes + * @param[in] value - parsed string + * @param[out] suc - success flag + */ +void cfg_hex_parse(uint8_t *dest, uint32_t count, + const char *value, bool *suc); + /** Convert bool to a Y or N constant string */ #define str_yn(cond) ((cond) ? ("Y") : ("N"))