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

remotes/github/master
Ondřej Hruška 6 年前
父節點 a66c453820
當前提交 9182c666ea
簽署人: MightyPork
GPG 金鑰 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 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;
}

@ -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;
}

@ -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"))

載入中…
取消
儲存