initial import from picomap firmware
This commit is contained in:
104
src/handlers.cpp
Normal file
104
src/handlers.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "handlers.h"
|
||||
#include "pico/unique_id.h"
|
||||
#include "pico/bootrom.h"
|
||||
#include "hardware/flash.h"
|
||||
#include "hardware/watchdog.h"
|
||||
#include "flash.h"
|
||||
#include "dispatch.h"
|
||||
#include "net.h"
|
||||
#include "debug_log.h"
|
||||
|
||||
static boot_reason detected_boot_reason;
|
||||
|
||||
static void poke_watchdog() {
|
||||
watchdog_update();
|
||||
dispatch_schedule_ms(500, poke_watchdog);
|
||||
}
|
||||
|
||||
void handlers_init() {
|
||||
auto val = static_cast<boot_reason>(watchdog_hw->scratch[0]);
|
||||
if (val == boot_reason::request_reboot || val == boot_reason::watchdog)
|
||||
detected_boot_reason = val;
|
||||
else
|
||||
detected_boot_reason = boot_reason::cold_boot;
|
||||
watchdog_hw->scratch[0] = static_cast<uint32_t>(boot_reason::watchdog);
|
||||
watchdog_enable(1000, true);
|
||||
}
|
||||
|
||||
void handlers_start() {
|
||||
poke_watchdog();
|
||||
}
|
||||
|
||||
std::optional<ResponseInfo> handle_info(const responder&, const RequestInfo&) {
|
||||
ResponseInfo resp;
|
||||
pico_unique_board_id_t uid;
|
||||
pico_get_unique_board_id(&uid);
|
||||
std::copy(uid.id, uid.id + 8, resp.board_id.begin());
|
||||
auto& ns = net_get_state();
|
||||
resp.mac = ns.mac;
|
||||
resp.ip = ns.ip;
|
||||
resp.firmware_name = firmware_name;
|
||||
resp.boot = detected_boot_reason;
|
||||
resp.build_epoch = BUILD_EPOCH;
|
||||
return resp;
|
||||
}
|
||||
|
||||
std::optional<ResponseLog> handle_log(const responder&, const RequestLog&) {
|
||||
ResponseLog resp;
|
||||
for (auto& e : g_debug_log)
|
||||
resp.entries.push_back(LogEntry{e.timestamp_us, e.message});
|
||||
return resp;
|
||||
}
|
||||
|
||||
std::optional<ResponseFlashErase> handle_flash_erase(const responder&, const RequestFlashErase& req) {
|
||||
if (req.addr < flash::FLASH_BASE || req.addr + req.len > flash::FLASH_BASE + flash::FLASH_SIZE) {
|
||||
dlogf("flash erase: out of range %08lx+%lu",
|
||||
static_cast<unsigned long>(req.addr), static_cast<unsigned long>(req.len));
|
||||
return std::nullopt;
|
||||
}
|
||||
uint32_t offset = req.addr - flash::FLASH_BASE;
|
||||
if (offset % FLASH_SECTOR_SIZE != 0 || req.len % FLASH_SECTOR_SIZE != 0 || req.len == 0) {
|
||||
dlogf("flash erase: bad alignment %08lx+%lu",
|
||||
static_cast<unsigned long>(req.addr), static_cast<unsigned long>(req.len));
|
||||
return std::nullopt;
|
||||
}
|
||||
flash_range_erase(offset, req.len);
|
||||
return ResponseFlashErase{};
|
||||
}
|
||||
|
||||
std::optional<ResponseFlashWrite> handle_flash_write(const responder&, const RequestFlashWrite& req) {
|
||||
if (req.addr < flash::FLASH_BASE || req.addr + req.data.size() > flash::FLASH_BASE + flash::FLASH_SIZE) {
|
||||
dlogf("flash write: out of range %08lx+%zu",
|
||||
static_cast<unsigned long>(req.addr), req.data.size());
|
||||
return std::nullopt;
|
||||
}
|
||||
uint32_t offset = req.addr - flash::FLASH_BASE;
|
||||
if (offset % FLASH_PAGE_SIZE != 0 || req.data.size() % FLASH_PAGE_SIZE != 0 || req.data.empty()) {
|
||||
dlogf("flash write: bad alignment %08lx+%zu",
|
||||
static_cast<unsigned long>(req.addr), req.data.size());
|
||||
return std::nullopt;
|
||||
}
|
||||
flash_range_program(offset, req.data.data(), req.data.size());
|
||||
return ResponseFlashWrite{};
|
||||
}
|
||||
|
||||
std::optional<ResponseFlashStatus> handle_flash_status(const responder&, const RequestFlashStatus&) {
|
||||
ResponseFlashStatus resp;
|
||||
boot_info_t bi;
|
||||
if (rom_get_boot_info(&bi))
|
||||
resp.boot_partition = bi.partition;
|
||||
else
|
||||
resp.boot_partition = -1;
|
||||
resp.slot_a = flash::scan(0x00000);
|
||||
resp.slot_b = flash::scan(0x80000);
|
||||
return resp;
|
||||
}
|
||||
|
||||
std::optional<ResponseReboot> handle_reboot(const responder&, const RequestReboot&) {
|
||||
dispatch_schedule_ms(100, []{
|
||||
watchdog_hw->scratch[0] = static_cast<uint32_t>(boot_reason::request_reboot);
|
||||
watchdog_reboot(0, 0, 0);
|
||||
});
|
||||
return ResponseReboot{};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user