storage impl for modes

This commit is contained in:
Triss 2021-08-26 04:11:08 +02:00
parent 1318e0f9c2
commit 9d2a970161
5 changed files with 79 additions and 8 deletions

View File

@ -3,6 +3,7 @@
#include <tusb.h>
#include "mode.h"
#include "storage.h"
#include "thread.h"
#include "usbstdio.h"
#include "vnd_cfg.h"
@ -35,6 +36,8 @@ enum m_default_feature {
mdef_feat_tempsense = 1<<4,
};
static bool data_dirty = false;
#ifdef DBOARD_HAS_UART
static cothread_t uartthread;
static uint8_t uartstack[THREAD_STACK_SIZE];
@ -81,6 +84,17 @@ static void enter_cb(void) {
serprogthread = co_derive(serprogstack, sizeof serprogstack, serprog_thread_fn);
thread_enter(serprogthread); // will call cdc_serprog_init() on correct thread
#endif
if (!data_dirty) { // only read when not read yet
struct mode_info mi = storage_mode_get_info(1);
if (mi.size != 0 && mi.version == 0x0010 /* TODO: version migration? */) {
uint8_t dst[2];
storage_mode_read(1, dst, 0, 2);
cdc_uart_set_hwflow(dst[0]);
tempsense_set_addr(dst[1]);
}
}
}
static void leave_cb(void) {
// TODO: CMSISDAP?
@ -144,7 +158,12 @@ static void handle_cmd_cb(uint8_t cmd) {
break;
case mdef_cmd_tempsense:
#ifdef DBOARD_HAS_TEMPSENSOR
tempsense_bulk_cmd();
{
uint8_t addra = tempsense_get_addr();
tempsense_bulk_cmd();
uint8_t addrb = tempsense_get_addr();
data_dirty |= addra != addrb;
}
#else
vnd_cfg_write_str(cfg_resp_illcmd, "temperature sensor not implemented on this device");
#endif
@ -156,9 +175,10 @@ static void handle_cmd_cb(uint8_t cmd) {
resp = cdc_uart_get_hwflow() ? 1 : 0;
vnd_cfg_write_resp(cfg_resp_ok, 1, &resp);
} else {
if (cdc_uart_set_hwflow(resp != 0))
if (cdc_uart_set_hwflow(resp != 0)) {
vnd_cfg_write_resp(cfg_resp_ok, 0, NULL);
else
data_dirty = true;
} else
vnd_cfg_write_str(cfg_resp_illcmd, "UART flow control setting not supported on this device");
}
#else
@ -387,6 +407,19 @@ static bool my_vendor_control_xfer_cb(uint8_t rhport, uint8_t ep_addr,
}
#endif
static uint16_t my_get_size(void) { return 2; }
static void my_get_data(void* dst, size_t offset, size_t maxsize) {
(void)offset; (void)maxsize;
uint8_t* d = dst;
d[0] = cdc_uart_get_hwflow() ? 1 : 0;
d[1] = tempsense_get_addr();
data_dirty = false;
}
static bool my_is_dirty(void) { return data_dirty; }
extern struct mode m_01_default;
// clang-format off
struct mode m_01_default = {
@ -402,6 +435,13 @@ struct mode m_01_default = {
.task = task_cb,
.handle_cmd = handle_cmd_cb,
.storage = {
.stclass = mode_storage_32b,
.get_size = my_get_size,
.get_data = my_get_data,
.is_dirty = my_is_dirty
},
#if defined(DBOARD_HAS_CMSISDAP) && CFG_TUD_HID > 0
#if 0
.tud_hid_get_report_cb = my_hid_get_report_cb,

View File

@ -3,6 +3,7 @@
#include <tusb.h>
#include "mode.h"
#include "storage.h"
#include "thread.h"
#include "usbstdio.h"
#include "vnd_cfg.h"
@ -20,6 +21,8 @@ enum m_sump_feature {
msump_feat_sump = 1<<0,
};
static bool data_dirty = false;
#ifdef DBOARD_HAS_SUMP
static cothread_t sumpthread;
static uint8_t sumpstack[THREAD_STACK_SIZE];
@ -44,6 +47,16 @@ static void enter_cb(void) {
sumpthread = co_derive(sumpstack, sizeof sumpstack, sump_thread_fn);
thread_enter(sumpthread);
#endif
if (!data_dirty) { // only read when not read yet
struct mode_info mi = storage_mode_get_info(4);
if (mi.size != 0 && mi.version == 0x0010 /* TODO: version migration? */) {
uint8_t dst[1];
storage_mode_read(4, dst, 0, 1);
sump_hw_set_overclock(dst[0]);
}
}
}
static void leave_cb(void) {
#ifdef DBOARD_HAS_SUMP
@ -133,7 +146,6 @@ enum {
#define EPNUM_CDC_STDIO_NOTIF 0x85
// clang-format off
// TODO: replace magic 64s by actual buffer size macros
static const uint8_t desc_configuration[] = {
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM__TOTAL, STRID_CONFIG, CONFIG_TOTAL_LEN,
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
@ -178,6 +190,17 @@ static void my_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_cod
}
#endif
static uint16_t my_get_size(void) { return 1; }
static void my_get_data(void* dst, size_t offset, size_t maxsize) {
(void)offset; (void)maxsize;
uint8_t* d = dst;
d[0] = sump_hw_get_overclock();
data_dirty = false;
}
static bool my_is_dirty(void) { return data_dirty; }
extern struct mode m_04_sump;
// clang-format off
struct mode m_04_sump = {
@ -188,6 +211,13 @@ struct mode m_04_sump = {
.usb_desc = desc_configuration,
.string_desc = string_desc_arr,
.storage = {
.stclass = mode_storage_32b,
.get_size = my_get_size,
.get_data = my_get_data,
.is_dirty = my_is_dirty
},
.enter = enter_cb,
.leave = leave_cb,
.task = task_cb,

View File

@ -6,14 +6,14 @@
#include "storage.h"
#if !defined(PERSISTENT_STORAGE) || !defined(DBOARD_HAS_STORAGE)
/*int storage_init(void) { return -1; }
int storage_init(void) { return -1; }
bool storage_flush_data(void) { return false; }
struct mode_info storage_mode_get_size(int _) {
struct mode_info storage_mode_get_info(int _) {
(void)_; return (struct mode_info){ .size = 0, .version = 0 };
}
void storage_mode_read(int _, void* __, size_t ___, size_t ____) {
(void)_; (void)__; (void)___; (void)____;
}*/
}
#else
#include "storage_internal.h"

View File

@ -20,6 +20,7 @@ enum mode_storage_class {
struct mode_storage {
enum mode_storage_class stclass;
uint16_t (*get_size)(void);
// if stclass < 512b, offset & maxsize can be ignored
void (*get_data)(void* dst, size_t offset, size_t maxsize);
bool (*is_dirty)(void); // if data was changed since last mode_read/get_data call
};

View File

@ -48,7 +48,7 @@ static size_t storage_allocate_new(void) {
uint16_t dsize = mode_list[mode]->storage.get_size();
if (dsize > stclass_sz[stcls]) continue;
if (current_wrhead + dsize > current_page_end) { // welp
if (current_wrhead + dsize > current_page_end) { // FIXME: data that is >1 page size (do we want to support this?)
current_page_end = current_page;
current_page -= STORAGE_ERASEWRITE_ALIGN;
current_wrhead = current_page;