now it's possible to read and write SYSTEM.INI using bulk

remotes/github/master
Ondřej Hruška 6 years ago
parent a66c453820
commit 9182c666ea
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 98
      comm/interfaces.c
  2. 47
      comm/messages.c
  3. 46
      framework/system_settings.c
  4. 3
      framework/system_settings.h
  5. 43
      platform/cfg_utils.c
  6. 12
      platform/cfg_utils.h

@ -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 uint32_t last_switch_time = 0; // started with USB
static bool xfer_verify_done = false; 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 */ /** Switch com transfer if the current one doesnt seem to work */
void com_switch_transfer_if_needed(void) void com_switch_transfer_if_needed(void)
@ -30,8 +30,8 @@ void com_switch_transfer_if_needed(void)
if (gActiveComport == COMPORT_USB) { if (gActiveComport == COMPORT_USB) {
if (elapsed > 1000) { if (elapsed > 1000) {
// USB may or may not work, depending on whether the module is plugged - // USB may or may not work, depending on whether the module is plugged in
// in or running from a battery/external supply remotely. // or running from a battery/external supply remotely.
// Check if USB is enumerated // Check if USB is enumerated
@ -39,19 +39,30 @@ void com_switch_transfer_if_needed(void)
if (0 == uadr) { if (0 == uadr) {
dbg("Not enumerated, assuming USB is dead"); dbg("Not enumerated, assuming USB is dead");
// Fallback to bare USART // Fallback to radio or bare USART
if (SystemSettings.use_comm_uart) { do {
configure_interface(COMPORT_USART); if (SystemSettings.use_comm_nordic) {
} if (configure_interface(COMPORT_NORDIC)) {
else if (SystemSettings.use_comm_nordic) { break;
configure_interface(COMPORT_NORDIC); // this fallbacks to LoRa if LoRa enabled }
} }
else if (SystemSettings.use_comm_lora) {
configure_interface(COMPORT_LORA); if (SystemSettings.use_comm_lora) {
} if (configure_interface(COMPORT_LORA)) {
else { break;
dbg("No alternate com interface configured, leaving USB enabled."); }
} }
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 { } else {
dbg("USB got address 0x%02x - OK", (int)uadr); 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 // Teardown
if (gActiveComport == COMPORT_USB) { if (gActiveComport == COMPORT_USB) {
@ -146,11 +157,17 @@ static void configure_interface(enum ComportSelection iface)
__HAL_RCC_USART2_CLK_DISABLE(); __HAL_RCC_USART2_CLK_DISABLE();
irqd_detach(USART2, com_UsartIrqHandler); irqd_detach(USART2, com_UsartIrqHandler);
} }
gActiveComport = COMPORT_NONE; else if (gActiveComport == COMPORT_NORDIC) {
// TODO
}
gActiveComport = iface;
// Init // Init
if (iface == COMPORT_USB) { if (iface == COMPORT_USB) {
trap("illegal"); // this never happens trap("illegal"); // this never happens
return false;
} }
else if (iface == COMPORT_USART) { else if (iface == COMPORT_USART) {
dbg("Setting up UART transfer"); 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_SetTransferDirection(USART2, LL_USART_DIRECTION_TX_RX);
LL_USART_Enable(USART2); 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 return true; // always OK (TODO check voltage on Rx if it's 3V3 when idle?)
dbg("nRF failed to init"); }
if (SystemSettings.use_comm_lora) { else if (iface == COMPORT_NORDIC) {
iface = COMPORT_LORA; // Try to configure nordic
} else { dbg("Setting up nRF transfer");
iface = COMPORT_NONE; // fail
}
}
if (iface == COMPORT_LORA) { // TODO set up and check nRF transport
// Try to configure nordic
dbg("Setting up LoRa transfer");
// TODO set up and check LoRa transport
dbg("LoRa failed to init"); // On failure, try setting up LoRa
iface = COMPORT_NONE; // fail dbg("nRF failed to init");
} return false;
} }
else if (iface == COMPORT_LORA) {
if (iface == COMPORT_NONE) { // Try to configure nordic
dbg("NO COM PORT AVAILABLE!"); 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;
} }

@ -58,26 +58,33 @@ static TF_Result lst_list_units(TinyFrame *tf, TF_Msg *msg)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Callback for bulk read of the settings file */ /** Callback for bulk read of a settings file */
static void settings_bulkread_cb(BulkRead *bulk, uint32_t chunk, uint8_t *buffer) static void ini_bulkread_cb(BulkRead *bulk, uint32_t chunk, uint8_t *buffer)
{ {
// clean-up request // clean-up request
if (buffer == NULL) { if (buffer == NULL) {
free_ck(bulk); free_ck(bulk);
iw_end(); iw_end();
// dbg("INI read complete.");
return; return;
} }
if (bulk->offset == 0) iw_begin(); if (bulk->offset == 0) iw_begin();
IniWriter iw = iw_init((char *)buffer, bulk->offset, chunk); IniWriter iw = iw_init((char *)buffer, bulk->offset, chunk);
iw.tag = 1; iw.tag = 1; // indicates this is read via the API (affects some comments)
settings_build_units_ini(&iw);
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) 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)); BulkRead *bulk = malloc_ck(sizeof(BulkRead));
assert_param(bulk != NULL); 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->frame_id = msg->frame_id;
bulk->len = iw_measure_total(settings_build_units_ini, 1); bulk->read = ini_bulkread_cb;
bulk->read = settings_bulkread_cb; bulk->userdata = (void *) (int)filenum;
bulk->userdata = NULL;
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); bulkread_start(tf, bulk);
Indicator_Effect(STATUS_DISK_BUSY_SHORT); Indicator_Effect(STATUS_DISK_BUSY_SHORT);
return TF_STAY; 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); PayloadParser pp = pp_start(msg->data, msg->len, NULL);
uint32_t len = pp_u32(&pp); uint32_t len = pp_u32(&pp);
if (!pp.ok) { if (!pp.ok) {
com_respond_error(msg->frame_id, E_PROTOCOL_BREACH); com_respond_error(msg->frame_id, E_MALFORMED_COMMAND);
goto done; goto done;
} }
@ -151,11 +173,8 @@ static TF_Result lst_ini_import(TinyFrame *tf, TF_Msg *msg)
settings_load_ini_begin(); settings_load_ini_begin();
ini_parse_begin(iniparser_cb, NULL); ini_parse_begin(iniparser_cb, NULL);
bulkwrite_start(tf, bulk); bulkwrite_start(tf, bulk);
Indicator_Effect(STATUS_DISK_BUSY); Indicator_Effect(STATUS_DISK_BUSY);
done: done:
return TF_STAY; return TF_STAY;
} }

@ -2,8 +2,6 @@
// Created by MightyPork on 2017/12/02. // Created by MightyPork on 2017/12/02.
// //
#include <platform/debug_uart.h>
#include <comm/interfaces.h>
#include "platform.h" #include "platform.h"
#include "system_settings.h" #include "system_settings.h"
#include "utils/str_utils.h" #include "utils/str_utils.h"
@ -11,6 +9,8 @@
#include "cfg_utils.h" #include "cfg_utils.h"
#include "resources.h" #include "resources.h"
#include "unit_base.h" #include "unit_base.h"
#include "platform/debug_uart.h"
#include "comm/interfaces.h"
static void systemsettings_mco_teardown(void); static void systemsettings_mco_teardown(void);
static void systemsettings_mco_init(void); static void systemsettings_mco_init(void);
@ -171,18 +171,34 @@ void systemsettings_build_ini(IniWriter *iw)
iw_entry_d(iw, "mco-prediv", (1<<SystemSettings.mco_prediv)); iw_entry_d(iw, "mco-prediv", (1<<SystemSettings.mco_prediv));
iw_cmt_newline(iw); iw_cmt_newline(iw);
iw_comment(iw, "Allowed fallback communication ports"); iw_comment(iw, "--- Allowed fallback communication ports ---");
iw_comment(iw, "UART Tx:PA2, Rx:PA2"); iw_cmt_newline(iw);
iw_comment(iw, "UART Tx:PA2, Rx:PA3");
iw_entry_s(iw, "com-uart", str_yn(SystemSettings.use_comm_uart)); iw_entry_s(iw, "com-uart", str_yn(SystemSettings.use_comm_uart));
iw_entry_d(iw, "com-uart-baud", SystemSettings.comm_uart_baud); iw_entry_d(iw, "com-uart-baud", SystemSettings.comm_uart_baud);
iw_cmt_newline(iw);
iw_comment(iw, "nRF24L01+ radio");
iw_entry_s(iw, "com-nrf", str_yn(SystemSettings.use_comm_nordic));
iw_comment(iw, "nRF channel");
iw_entry_d(iw, "nrf-channel", SystemSettings.nrf_channel);
iw_comment(iw, "nRF network ID (hex, 4 bytes, little-endian)");
iw_entry(iw, "nrf-network", "%02X.%02X.%02X.%02X",
SystemSettings.nrf_network[0],
SystemSettings.nrf_network[1],
SystemSettings.nrf_network[2],
SystemSettings.nrf_network[3]);
iw_comment(iw, "nRF node address (hex, 1 byte, > 0)");
iw_entry(iw, "nrf-address", "%02X",
SystemSettings.nrf_address);
// those aren't implement yet, don't tease the user // those aren't implement yet, don't tease the user
// TODO show pin-out, extra settings if applicable // TODO show pin-out, extra settings if applicable
#if 0 #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_comment(iw, "LoRa/GFSK sx127x");
iw_entry_s(iw, "com-lora", str_yn(SystemSettings.use_comm_sx127x)); iw_entry_s(iw, "com-lora", str_yn(SystemSettings.use_comm_sx127x));
#endif #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 (suc) SystemSettings.comm_uart_baud = baud;
} }
#if 0 if (streq(key, "com-nrf")) {
if (streq(key, "com-nordic")) {
bool yn = cfg_bool_parse(value, &suc); bool yn = cfg_bool_parse(value, &suc);
if (suc) SystemSettings.use_comm_nordic = yn; 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")) { if (streq(key, "com-lora")) {
bool yn = cfg_bool_parse(value, &suc); bool yn = cfg_bool_parse(value, &suc);
if (suc) SystemSettings.use_comm_lora = yn; if (suc) SystemSettings.use_comm_lora = yn;

@ -27,6 +27,9 @@ struct system_settings {
uint32_t comm_uart_baud; // baud rate for the uart transport uint32_t comm_uart_baud; // baud rate for the uart transport
bool use_comm_lora; // SX1276/8 bool use_comm_lora; // SX1276/8
bool use_comm_nordic; // nRF24L01+ 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 // 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 volatile bool editable; //!< True if we booted with the LOCK jumper removed

@ -297,3 +297,46 @@ uint32_t cfg_enum4_parse(const char *value,
*suc = false; *suc = false;
return na; 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;
}
}
}

@ -116,6 +116,18 @@ uint32_t cfg_enum4_parse(const char *tpl,
const char *d, uint32_t nd, const char *d, uint32_t nd,
bool *suc); 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 */ /** Convert bool to a Y or N constant string */
#define str_yn(cond) ((cond) ? ("Y") : ("N")) #define str_yn(cond) ((cond) ? ("Y") : ("N"))

Loading…
Cancel
Save