now it's possible to read and write SYSTEM.INI using bulk
This commit is contained in:
+41
-33
@@ -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
|
||||
// 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) {
|
||||
configure_interface(COMPORT_USART);
|
||||
// after nordic/lora
|
||||
if (configure_interface(COMPORT_USART)) {
|
||||
break;
|
||||
}
|
||||
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.");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return true; // always OK (TODO check voltage on Rx if it's 3V3 when idle?)
|
||||
}
|
||||
else {
|
||||
if (iface == COMPORT_NORDIC) {
|
||||
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 false;
|
||||
}
|
||||
}
|
||||
|
||||
if (iface == COMPORT_LORA) {
|
||||
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");
|
||||
iface = COMPORT_NONE; // fail
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
trap("Bad iface %d", iface);
|
||||
}
|
||||
|
||||
if (iface == COMPORT_NONE) {
|
||||
dbg("NO COM PORT AVAILABLE!");
|
||||
}
|
||||
|
||||
gActiveComport = iface;
|
||||
}
|
||||
|
||||
+31
-12
@@ -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;
|
||||
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->read = ini_bulkread_cb;
|
||||
bulk->userdata = (void *) (int)filenum;
|
||||
|
||||
if (filenum == 0) {
|
||||
bulk->len = iw_measure_total(settings_build_units_ini, 1);
|
||||
bulk->read = settings_bulkread_cb;
|
||||
bulk->userdata = NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// Created by MightyPork on 2017/12/02.
|
||||
//
|
||||
|
||||
#include <platform/debug_uart.h>
|
||||
#include <comm/interfaces.h>
|
||||
#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<<SystemSettings.mco_prediv));
|
||||
|
||||
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_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
|
||||
// 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user