Skip to content

Commit

Permalink
Merge pull request #1 from rovo89/config_flash
Browse files Browse the repository at this point in the history
Config flash
  • Loading branch information
Apehaenger authored Oct 12, 2024
2 parents bca5826 + 1ff7d31 commit 7899164
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 286 deletions.
84 changes: 0 additions & 84 deletions Firmware/LowLevel/include/nv_config.h

This file was deleted.

1 change: 1 addition & 0 deletions Firmware/LowLevel/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ lib_deps =
Wire
SPI
FastCRC
LittleFS
bakercp/PacketSerial@^1.4.0
powerbroker2/FireTimer@^1.0.5
https://github.com/ClemensElflein/NeoPixelConnect.git
Expand Down
94 changes: 73 additions & 21 deletions Firmware/LowLevel/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "ui_board.h"
#include "imu.h"
#include "debug.h"
#include "nv_config.h"
#include <LittleFS.h>

#ifdef ENABLE_SOUND_MODULE
#include <soundsystem.h>
Expand Down Expand Up @@ -119,13 +119,16 @@ uint8_t ui_topic_bitmask = Topic_set_leds; // UI subscription, default to Set_LE
uint16_t ui_interval = 1000; // UI send msg (LED/State) interval (ms)

struct ll_high_level_config llhl_config; // LL/HL configuration (is initialized with YF-C500 defaults)
nv_config::Config *nv_cfg; // Non-volatile configuration
const String CONFIG_FILENAME = "/openmower.cfg";
uint16_t config_crc_in_flash = 0;

void sendMessage(void *message, size_t size);
void sendUIMessage(void *message, size_t size);
void onPacketReceived(const uint8_t *buffer, size_t size);
void onUIPacketReceived(const uint8_t *buffer, size_t size);
void manageUISubscriptions();
void saveConfigToFlash();
void readConfigFromFlash();

void setRaspiPower(bool power) {
// Update status bits in the status message
Expand Down Expand Up @@ -416,6 +419,10 @@ void setup() {
UISerial.setStream(&UI1_SERIAL);
UISerial.setPacketHandler(&onUIPacketReceived);

// Initialize flash and try to read config
LittleFS.begin();
readConfigFromFlash();

/*
* IMU INITIALIZATION
*/
Expand Down Expand Up @@ -550,6 +557,29 @@ void sendConfigMessage(uint8_t pkt_type) {
free(msg);
}

void applyConfig(const uint8_t *buffer, size_t size) {
// This is a flexible length package where the size may vary when ll_high_level_config struct got enhanced only on one side.
// If payload size is larger than our struct size, ensure that we only copy those we know of = our struct size.
// If payload size is smaller than our struct size, copy only the payload we got, but ensure that the unsent member(s) have reasonable defaults.
size_t payload_size = min(sizeof(ll_high_level_config), size - 2); // exclude crc

// Use a temporary config for easier sanity adaption and copy our live config, which has at least reasonable defaults.
// The live config copy ensures that we've reasonable values for the case that HL config struct is older (smaller) than ours.
auto tmp_config = llhl_config;

// Copy payload to temporary config
memcpy(&tmp_config, buffer, payload_size);

// Sanity
tmp_config.v_charge_cutoff = min(tmp_config.v_charge_cutoff, V_CHARGE_ABS_MAX); // Fix exceed of hardware limits
tmp_config.i_charge_cutoff = min(tmp_config.i_charge_cutoff, I_CHARGE_ABS_MAX); // Fix exceed of hardware limits

// Make config live
llhl_config = tmp_config;

// PR-80: Assign volume & language if not already stored in flash-config
}

void onPacketReceived(const uint8_t *buffer, size_t size) {
// sanity check for CRC to work (1 type, 1 data, 2 CRC)
if (size < 4)
Expand Down Expand Up @@ -585,26 +615,10 @@ void onPacketReceived(const uint8_t *buffer, size_t size) {
// copy the state
last_high_level_state = *((struct ll_high_level_state *) buffer);
} else if (buffer[0] == PACKET_ID_LL_HIGH_LEVEL_CONFIG_REQ || buffer[0] == PACKET_ID_LL_HIGH_LEVEL_CONFIG_RSP) {
// This is a flexible length package where the size may vary when ll_high_level_config struct got enhanced only on one side.
// If payload size is larger than our struct size, ensure that we only copy those we know of = our struct size.
// If payload size is smaller than our struct size, copy only the payload we got, but ensure that the unsent member(s) have reasonable defaults.
size_t payload_size = min(sizeof(ll_high_level_config), size - 3); // -1 type -2 crc
applyConfig(buffer + 1, size - 1); // Skip type

// Use a temporary config for easier sanity adaption and copy our live config, which has at least reasonable defaults.
// The live config copy ensures that we've reasonable values for the case that HL config struct is older (smaller) than ours.
auto tmp_config = llhl_config;

// Copy payload to temporary config (behind type)
memcpy(&tmp_config, buffer + 1, payload_size);

// Sanity
tmp_config.v_charge_cutoff = min(tmp_config.v_charge_cutoff, V_CHARGE_ABS_MAX); // Fix exceed of hardware limits
tmp_config.i_charge_cutoff = min(tmp_config.i_charge_cutoff, I_CHARGE_ABS_MAX); // Fix exceed of hardware limits

// Make config live
llhl_config = tmp_config;

// PR-80: Assign volume & language if not already stored in flash-config
// Store in flash
saveConfigToFlash();

if (buffer[0] == PACKET_ID_LL_HIGH_LEVEL_CONFIG_REQ)
sendConfigMessage(PACKET_ID_LL_HIGH_LEVEL_CONFIG_RSP);
Expand Down Expand Up @@ -794,3 +808,41 @@ void sendUIMessage(void *message, size_t size) {

UISerial.send((uint8_t *) message, size);
}

void saveConfigToFlash() {
uint16_t crc = CRC16.ccitt((const uint8_t*) &llhl_config, sizeof(llhl_config));
if (crc == config_crc_in_flash) return;

File f = LittleFS.open(CONFIG_FILENAME, "w");
f.write((const uint8_t*) &llhl_config, sizeof(llhl_config));
f.write((const uint8_t*) &crc, 2);
f.close();
}

void readConfigFromFlash() {
File f = LittleFS.open(CONFIG_FILENAME, "r");
if (!f) return;

// sanity check for CRC to work (1 data, 2 CRC)
const size_t size = f.size();
if (size < 3) {
f.close();
return;
}

// read config
uint8_t *buffer = (uint8_t *)malloc(f.size());
f.read(buffer, size);
f.close();

// check the CRC
uint16_t crc = CRC16.ccitt(buffer, size - 2);

if (buffer[size - 1] != ((crc >> 8) & 0xFF) ||
buffer[size - 2] != (crc & 0xFF))
return;

config_crc_in_flash = crc;
applyConfig(buffer, size);
free(buffer);
}
Loading

0 comments on commit 7899164

Please sign in to comment.