Skip to content

Commit

Permalink
Wifi integration branch (#309)
Browse files Browse the repository at this point in the history
* wifi: separate StaticFramer and StaticFramerInclusive

* add wifi memory section in DDR

* wifi: add static 8MB receive buffer in dedicated memory region

* wifi: broadcast heartbeat every 1s without external trigger

* wifi: remove switch message (was only used for demonstration)

* wifi: update flatbuffers (unidrectional heartbeat and cleanup)

* wifi: use unidirectional heartbeat

* wifi: add separate management channel

* wifi: request ip update via management channel

* wifi: print ip changes in main loop

* Add InterCore comm channel for Wifi IP requests

* Add GUI element for display IP address

* Display IP on System Info tab

* Fix float/double warning

* wifi: use enums for virtual channel ids

* wifi: restructure file

* Expose and forward specific error code along with wifi module ip address

* wifi: add timeout to detect no answer for ip request

* Make GUI wifi status messages more clear

* Pull in changes on main

* wifi: receive and report port together with ip address of connected module

* patch_storage: add separate change listeners for wifi

* wifi: poll for media change and send updated patch list

* wifi: switch to 921600 baudrate for comm port

* update wifi images
- increase serial baudrate
- add separate management channel
- query ip and port over management channel
- wifi connect in separate task
- estimate file upload timeouts in frontend
- remove (arbitrary) file upload limits in frontend
- heartbeat initiated from metamodule every second
- stream file upload requests from web client to metamodule
- potential fix for micropython reformatting filesystem partition
- update to micropython v1.23.0

* wifi: do not broadcast patch list directly after patch file upload

* update wifi images:
- more specific error handling and error messages
- remove client side timeout
- hardcode request sent to response timeout to 30s

* wifi: Deframer: expose if currently latched on a frame or not

* wifi: circumvent rx overruns in certain scenarios
- after uploading a patch, first broadcast a new patch list before closing the request
- only send updated patchlist if currently not receiving a frame

* wifi: Deframer: reset does not require output function

* wifi: reset all queues and parsing on any overrun

* update wifi images:
- fix uploading identical files after each other ignored on some browsers
- only allow a single in-flight synchronous request at the webserver
- add progress bar for patch file uploads

* Simulator: use libc++ for clang build (try to get std::expected support)

* Simulator CI: install libc++18 packages

* Revert "Simulator: use libc++ for clang build (try to get std::expected support)"

This reverts commit 40a81f9.

* Revert "Simulator CI: install libc++18 packages"

This reverts commit 2beda55.

* simulator: workaround for std::expected on clang 18

---------

Co-authored-by: Dan Green <[email protected]>
  • Loading branch information
LnnrtS and danngreen authored Aug 2, 2024
1 parent 85ecac7 commit ad42e9c
Show file tree
Hide file tree
Showing 25 changed files with 450 additions and 60 deletions.
15 changes: 15 additions & 0 deletions firmware/src/core_intercom/intercore_message.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <cstdint>
#include <span>
#include <variant>
#include <expected>

namespace MetaModule
{
Expand Down Expand Up @@ -61,6 +62,10 @@ struct IntercoreStorageMessage {
DeleteFileFailed,
DeleteFileSuccess,

RequestWifiIP,
WifiIPSuccess,
WifiIPFailed,

NumRequests,
};

Expand All @@ -79,6 +84,16 @@ struct IntercoreStorageMessage {
uint32_t *bytes_processed;
enum FlashTarget : uint8_t { WIFI, QSPI };
FlashTarget flashTarget;

enum WifiIPError : uint8_t {NO_MODULE_CONNECTED, NO_IP};
struct Endpoint_t
{
std::array<uint8_t,4> ip;
uint16_t port;
};
using WifiIPResult = std::expected<Endpoint_t,WifiIPError>;

WifiIPResult wifi_ip_result ;

PluginFileList *plugin_file_list;
};
Expand Down
3 changes: 3 additions & 0 deletions firmware/src/fs/fs_messages.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "fw_update/firmware_file_finder.hh"
#include "fw_update/firmware_writer.hh"
#include "patch_file/patch_storage.hh"
#include "wifi/app_request_handler.hh"

namespace MetaModule
{
Expand Down Expand Up @@ -40,6 +41,7 @@ struct FilesystemMessages {
process_receiver(firmware_writer);
process_receiver(plugin_files);
process_receiver(calibration_handler);
process_receiver(wifi_app_handler);

if (message.message_type != IntercoreStorageMessage::MessageType::None) {
pr_err("ICC message of type %u not handled\n", message.message_type);
Expand Down Expand Up @@ -68,6 +70,7 @@ private:
FirmwareWriter firmware_writer{sd_fileio, usb_fileio, flash_loader};
PluginFileFinder plugin_files{sd_fileio, usb_fileio};
CalibrationMessageHandler calibration_handler{flash_loader};
WifiAppRequestHandler wifi_app_handler{};
};

} // namespace MetaModule
95 changes: 95 additions & 0 deletions firmware/src/gui/pages/system_info_tab.hh
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
#pragma once
#include "drivers/cache.hh"
#include "git_version.h"
#include "gui/helpers/lv_helpers.hh"
#include "gui/pages/system_menu_tab_base.hh"
#include "gui/slsexport/meta5/ui.h"
#include "patch_file/file_storage_proxy.hh"

namespace MetaModule
{

struct InfoTab : SystemMenuTab {

InfoTab(FileStorageProxy &storage)
: storage{storage} {
lv_label_set_text(ui_SystemMenuExpanders, "No wifi module found");
}

void prepare_focus(lv_group_t *group) override {
this->group = group;

Expand All @@ -16,9 +24,96 @@ struct InfoTab : SystemMenuTab {
fw_version.remove_prefix(9);

lv_label_set_text_fmt(ui_SystemMenuFWversion, "Firmware version: %s", fw_version.data());

wifi_ip_state = WifiIPState::Idle;
}

void update() override {
update_wifi_ip();
}

void update_wifi_ip() {
switch (wifi_ip_state) {

case WifiIPState::Idle: {
uint32_t now = lv_tick_get();
if (now - last_check_wifi_ip_tm > 1000) { //poll media once per second

last_check_wifi_ip_tm = now;

if (storage.request_wifi_ip()) {
wifi_ip_state = WifiIPState::Requested;
}
}
} break;

case WifiIPState::Requested: {
auto message = storage.get_message();

if (message.message_type == FileStorageProxy::WifiIPSuccess) {

lv_show(ui_SystemMenuExpanders);

if (message.wifi_ip_result) {

auto &newEndpoint = *message.wifi_ip_result;

pr_trace("Got Wifi IP: %u.%u.%u.%u:%U\n", newEndpoint.ip[0], newEndpoint.ip[1], newEndpoint.ip[2], newEndpoint.ip[3], newEndpoint.port);

if (newEndpoint.port != 80)
{
// only display port when it is non-default
lv_label_set_text_fmt(ui_SystemMenuExpanders,
"Wifi: http://%u.%u.%u.%u:%u",
newEndpoint.ip[0],
newEndpoint.ip[1],
newEndpoint.ip[2],
newEndpoint.ip[3],
newEndpoint.port);
}
else
{
lv_label_set_text_fmt(ui_SystemMenuExpanders,
"Wifi: http://%u.%u.%u.%u",
newEndpoint.ip[0],
newEndpoint.ip[1],
newEndpoint.ip[2],
newEndpoint.ip[3]);
}

} else {

switch (message.wifi_ip_result.error()) {

case IntercoreStorageMessage::WifiIPError::NO_MODULE_CONNECTED:
lv_label_set_text(ui_SystemMenuExpanders, "No wifi module found");
break;

case IntercoreStorageMessage::WifiIPError::NO_IP:
lv_label_set_text(ui_SystemMenuExpanders,
"Wifi module not connected\n to a wifi network");
break;
}
}

wifi_ip_state = WifiIPState::Idle;

} else if (message.message_type == FileStorageProxy::WifiIPFailed) {
lv_show(ui_SystemMenuExpanders);
lv_label_set_text(ui_SystemMenuExpanders, "Wifi module: Internal Error");

wifi_ip_state = WifiIPState::Idle;
}

} break;
}
}

private:
FileStorageProxy &storage;
lv_group_t *group = nullptr;

enum WifiIPState { Idle, Requested } wifi_ip_state = WifiIPState::Idle;
uint32_t last_check_wifi_ip_tm = 0;
};
} // namespace MetaModule
1 change: 1 addition & 0 deletions firmware/src/gui/pages/system_menu.hh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct SystemMenuPage : PageBase {

SystemMenuPage(PatchContext info)
: PageBase{info, PageId::SystemMenu}
, info_tab{patch_storage}
, plugin_tab{info.plugin_manager, info.notify_queue}
, prefs_tab{info.patch_playloader, info.settings.audio, gui_state}
, system_tab{patch_storage, params, metaparams, patch_playloader, patch_mod_queue}
Expand Down
35 changes: 27 additions & 8 deletions firmware/src/gui/slsexport/meta5/screens/ui_SystemMenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,21 +179,40 @@ lv_obj_set_align( ui_SystemMenuPCBversion, LV_ALIGN_CENTER );
lv_label_set_text(ui_SystemMenuPCBversion,"PCB version p11");
lv_obj_set_style_text_font(ui_SystemMenuPCBversion, &ui_font_MuseoSansRounded50014, LV_PART_MAIN| LV_STATE_DEFAULT);

ui_SystemMenuExpanders = lv_label_create(ui_SystemInfoCont);
lv_obj_set_width( ui_SystemMenuExpanders, LV_SIZE_CONTENT); /// 1
lv_obj_set_height( ui_SystemMenuExpanders, LV_SIZE_CONTENT); /// 1
lv_obj_set_align( ui_SystemMenuExpanders, LV_ALIGN_CENTER );
lv_label_set_text(ui_SystemMenuExpanders,"Expanders connected:");
lv_obj_add_flag( ui_SystemMenuExpanders, LV_OBJ_FLAG_HIDDEN ); /// Flags
lv_obj_set_style_text_font(ui_SystemMenuExpanders, &ui_font_MuseoSansRounded50014, LV_PART_MAIN| LV_STATE_DEFAULT);

ui_SystemMenuFWversion = lv_label_create(ui_SystemInfoCont);
lv_obj_set_width( ui_SystemMenuFWversion, LV_SIZE_CONTENT); /// 1
lv_obj_set_height( ui_SystemMenuFWversion, LV_SIZE_CONTENT); /// 1
lv_obj_set_align( ui_SystemMenuFWversion, LV_ALIGN_CENTER );
lv_label_set_text(ui_SystemMenuFWversion,"Firmware version 0.5.1");
lv_obj_set_style_text_font(ui_SystemMenuFWversion, &ui_font_MuseoSansRounded50014, LV_PART_MAIN| LV_STATE_DEFAULT);

ui_SystemMenuInfoExpanders = lv_label_create(ui_SystemInfoCont);
lv_obj_set_width( ui_SystemMenuInfoExpanders, lv_pct(100));
lv_obj_set_height( ui_SystemMenuInfoExpanders, LV_SIZE_CONTENT); /// 1
lv_obj_set_align( ui_SystemMenuInfoExpanders, LV_ALIGN_CENTER );
lv_label_set_long_mode(ui_SystemMenuInfoExpanders,LV_LABEL_LONG_CLIP);
lv_label_set_text(ui_SystemMenuInfoExpanders,"EXPANDERS");
lv_obj_set_style_text_color(ui_SystemMenuInfoExpanders, lv_color_hex(0xFD8B18), LV_PART_MAIN | LV_STATE_DEFAULT );
lv_obj_set_style_text_opa(ui_SystemMenuInfoExpanders, 255, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_text_letter_space(ui_SystemMenuInfoExpanders, 1, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_text_line_space(ui_SystemMenuInfoExpanders, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_text_font(ui_SystemMenuInfoExpanders, &ui_font_MuseoSansRounded70016, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_border_color(ui_SystemMenuInfoExpanders, lv_color_hex(0x888888), LV_PART_MAIN | LV_STATE_DEFAULT );
lv_obj_set_style_border_opa(ui_SystemMenuInfoExpanders, 255, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_border_width(ui_SystemMenuInfoExpanders, 2, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_border_side(ui_SystemMenuInfoExpanders, LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_left(ui_SystemMenuInfoExpanders, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(ui_SystemMenuInfoExpanders, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(ui_SystemMenuInfoExpanders, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(ui_SystemMenuInfoExpanders, 0, LV_PART_MAIN| LV_STATE_DEFAULT);

ui_SystemMenuExpanders = lv_label_create(ui_SystemInfoCont);
lv_obj_set_width( ui_SystemMenuExpanders, LV_SIZE_CONTENT); /// 1
lv_obj_set_height( ui_SystemMenuExpanders, LV_SIZE_CONTENT); /// 1
lv_obj_set_align( ui_SystemMenuExpanders, LV_ALIGN_CENTER );
lv_label_set_text(ui_SystemMenuExpanders,"No Expanders detected");
lv_obj_set_style_text_font(ui_SystemMenuExpanders, &ui_font_MuseoSansRounded50014, LV_PART_MAIN| LV_STATE_DEFAULT);

ui_SystemMenuPluginsTab = lv_tabview_add_tab(ui_SystemMenuTabView, "Plugins");
lv_obj_set_flex_flow(ui_SystemMenuPluginsTab,LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(ui_SystemMenuPluginsTab, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
Expand Down
1 change: 1 addition & 0 deletions firmware/src/gui/slsexport/meta5/ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ lv_obj_t *ui_SystemInfoCont;
lv_obj_t *ui_SystemMenuMetaModule;
lv_obj_t *ui_SystemMenuInfoHardware;
lv_obj_t *ui_SystemMenuPCBversion;
lv_obj_t *ui_SystemMenuInfoExpanders;
lv_obj_t *ui_SystemMenuExpanders;
lv_obj_t *ui_SystemMenuFWversion;
lv_obj_t *ui_SystemMenuPluginsTab;
Expand Down
1 change: 1 addition & 0 deletions firmware/src/gui/slsexport/meta5/ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ extern lv_obj_t *ui_SystemInfoCont;
extern lv_obj_t *ui_SystemMenuMetaModule;
extern lv_obj_t *ui_SystemMenuInfoHardware;
extern lv_obj_t *ui_SystemMenuPCBversion;
extern lv_obj_t *ui_SystemMenuInfoExpanders;
extern lv_obj_t *ui_SystemMenuExpanders;
extern lv_obj_t *ui_SystemMenuFWversion;
extern lv_obj_t *ui_SystemMenuPluginsTab;
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/medium/conf/wifi_uart_conf.hh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ constexpr inline UartConf WifiUartConfig{
.TXPin = {mdrivlib::GPIO::B, mdrivlib::PinNum::_13, mdrivlib::PinAF::AltFunc14},
.RXPin = {mdrivlib::GPIO::B, mdrivlib::PinNum::_12, mdrivlib::PinAF::AltFunc14},
.mode = UartConf::Mode::TXRX,
.baud = 115200, // 230400, 921600
.baud = 921600, // 230400, 921600
.wordlen = 8,
.parity = UartConf::Parity::None,
.stopbits = UartConf::StopBits::_1,
Expand Down
5 changes: 5 additions & 0 deletions firmware/src/patch_file/file_storage_proxy.hh
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ public:
return comm_.send_message(message);
}

[[nodiscard]] bool request_wifi_ip() {
IntercoreStorageMessage message{.message_type = RequestWifiIP};
return comm_.send_message(message);
}

private:
FileStorageComm &comm_;
PatchDirList &patch_dir_list_;
Expand Down
22 changes: 22 additions & 0 deletions firmware/src/patch_file/patch_storage.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class PatchStorage {

using enum IntercoreStorageMessage::MessageType;

PollChange usb_changes_wifi_{1000};
PollChange norflash_changes_wifi_{1000};
PollChange sd_changes_wifi_{1000};

public:
PatchStorage(FatFileIO &sdcard_fileio, FatFileIO &usb_fileio)
: sdcard_{sdcard_fileio}
Expand Down Expand Up @@ -68,20 +72,23 @@ public:
auto success = PatchFileIO::write_file(data, usbdrive_, filename);
if (success) {
usb_changes_.reset();
usb_changes_wifi_.reset();
}
return success;

} else if (vol == Volume::SDCard) {
auto success = PatchFileIO::write_file(data, sdcard_, filename);
if (success) {
sd_changes_.reset();
sd_changes_wifi_.reset();
}
return success;

} else if (vol == Volume::NorFlash) {
auto success = PatchFileIO::write_file(data, norflash_, filename);
if (success) {
norflash_changes_.reset();
norflash_changes_wifi_.reset();
}
return success;
} else {
Expand Down Expand Up @@ -241,6 +248,18 @@ public:
return patch_dir_list_;
}

bool has_media_changed()
{
sd_changes_wifi_.poll(HAL_GetTick(), [this] { return sdcard_.is_mounted(); });
usb_changes_wifi_.poll(HAL_GetTick(), [this] { return usbdrive_.is_mounted(); });

auto result = sd_changes_wifi_.take_change();
result |= usb_changes_wifi_.take_change();
result |= norflash_changes_wifi_.take_change();

return result;
}

private:
void poll_media_change() {
sd_changes_.poll(HAL_GetTick(), [this] { return sdcard_.is_mounted(); });
Expand Down Expand Up @@ -278,20 +297,23 @@ private:
auto success = usbdrive_.delete_file(filename);
if (success) {
usb_changes_.reset();
usb_changes_wifi_.reset();
}
return success;

} else if (vol == Volume::SDCard) {
auto success = sdcard_.delete_file(filename);
if (success) {
sd_changes_.reset();
sd_changes_wifi_.reset();
}
return success;

} else if (vol == Volume::NorFlash) {
auto success = norflash_.delete_file(filename);
if (success) {
norflash_changes_.reset();
norflash_changes_wifi_.reset();
}
return success;

Expand Down
Loading

0 comments on commit ad42e9c

Please sign in to comment.