This commit is contained in:
hank 2025-05-11 22:34:17 -07:00
commit 0c3c162835
33 changed files with 4989 additions and 23 deletions

View file

@ -73,7 +73,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
}
void CommonCLI::savePrefs(FILESYSTEM* fs) {
#if defined(NRF52_PLATFORM)
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
File file = fs->open("/com_prefs", FILE_O_WRITE);
if (file) { file.seek(0); file.truncate(); }
#elif defined(RP2040_PLATFORM)

View file

@ -0,0 +1,17 @@
#pragma once
#include <RadioLib.h>
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
class CustomSTM32WLx : public STM32WLx {
public:
CustomSTM32WLx(STM32WLx_Module *mod) : STM32WLx(mod) { }
bool isReceiving() {
uint16_t irq = getIrqFlags();
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
return detected;
}
};

View file

@ -0,0 +1,30 @@
#pragma once
#include "CustomSTM32WLx.h"
#include "RadioLibWrappers.h"
#include <math.h>
class CustomSTM32WLxWrapper : public RadioLibWrapper {
public:
CustomSTM32WLxWrapper(CustomSTM32WLx& radio, mesh::MainBoard& board) : RadioLibWrapper(radio, board) { }
bool isReceiving() override {
if (((CustomSTM32WLx *)_radio)->isReceiving()) return true;
idle(); // put sx126x into standby
// do some basic CAD (blocks for ~12780 micros (on SF 10)!)
bool activity = (((CustomSTM32WLx *)_radio)->scanChannel() == RADIOLIB_LORA_DETECTED);
if (activity) {
startRecv();
} else {
idle();
}
return activity;
}
float getLastRSSI() const override { return ((CustomSTM32WLx *)_radio)->getRSSI(); }
float getLastSNR() const override { return ((CustomSTM32WLx *)_radio)->getSNR(); }
float packetScore(float snr, int packet_len) override {
int sf = ((CustomSTM32WLx *)_radio)->spreadingFactor;
return packetScoreInt(snr, sf, packet_len);
}
};

View file

@ -46,7 +46,7 @@ bool IdentityStore::save(const char *name, const mesh::LocalIdentity& id) {
char filename[40];
sprintf(filename, "%s/%s.id", _dir, name);
#if defined(NRF52_PLATFORM)
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
File file = _fs->open(filename, FILE_O_WRITE);
if (file) { file.seek(0); file.truncate(); }
#elif defined(RP2040_PLATFORM)
@ -68,7 +68,7 @@ bool IdentityStore::save(const char *name, const mesh::LocalIdentity& id, const
char filename[40];
sprintf(filename, "%s/%s.id", _dir, name);
#if defined(NRF52_PLATFORM)
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
File file = _fs->open(filename, FILE_O_WRITE);
if (file) { file.seek(0); file.truncate(); }
#elif defined(RP2040_PLATFORM)

View file

@ -3,7 +3,7 @@
#if defined(ESP32) || defined(RP2040_PLATFORM)
#include <FS.h>
#define FILESYSTEM fs::FS
#elif defined(NRF52_PLATFORM)
#elif defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
#include <Adafruit_LittleFS.h>
#define FILESYSTEM Adafruit_LittleFS

View file

@ -0,0 +1,139 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 hathach for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <Arduino.h>
#include "InternalFileSystem.h"
//--------------------------------------------------------------------+
// LFS Disk IO
//--------------------------------------------------------------------+
static int _internal_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
{
if (!buffer || !size) return LFS_ERR_INVAL;
lfs_block_t address = LFS_FLASH_ADDR_BASE + (block * FLASH_PAGE_SIZE + off);
memcpy(buffer, (void *)address, size);
return LFS_ERR_OK;
}
// Program a region in a block. The block must have previously
// been erased. Negative error codes are propogated to the user.
// May return LFS_ERR_CORRUPT if the block should be considered bad.
static int _internal_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
{
HAL_StatusTypeDef hal_rc = HAL_OK;
lfs_block_t addr = LFS_FLASH_ADDR_BASE + (block * FLASH_PAGE_SIZE + off);
uint64_t *bufp = (uint64_t *) buffer;
if (HAL_FLASH_Unlock() != HAL_OK) return LFS_ERR_IO;
for (uint32_t i = 0; i < size/8; i++) {
if ((addr < LFS_FLASH_ADDR_BASE) || (addr > FLASH_END_ADDR)) {
HAL_FLASH_Lock();
return LFS_ERR_INVAL;
}
hal_rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, *bufp);
addr += 8;
bufp += 1;
}
if (HAL_FLASH_Lock() != HAL_OK) return LFS_ERR_IO;
return hal_rc == HAL_OK ? LFS_ERR_OK : LFS_ERR_IO;
}
// Erase a block. A block must be erased before being programmed.
// The state of an erased block is undefined. Negative error codes
// are propogated to the user.
// May return LFS_ERR_CORRUPT if the block should be considered bad.
static int _internal_flash_erase(const struct lfs_config *c, lfs_block_t block)
{
HAL_StatusTypeDef hal_rc;
lfs_block_t address = LFS_FLASH_ADDR_BASE + (block * FLASH_PAGE_SIZE);
uint32_t pageError = 0;
FLASH_EraseInitTypeDef EraseInitStruct = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.Page = 0,
.NbPages = 1
};
if ((address < LFS_FLASH_ADDR_BASE) || (address > FLASH_END_ADDR)) {
return LFS_ERR_INVAL;
}
EraseInitStruct.Page = (address - FLASH_BASE) / FLASH_PAGE_SIZE;
HAL_FLASH_Unlock();
hal_rc = HAL_FLASHEx_Erase(&EraseInitStruct, &pageError);
HAL_FLASH_Lock();
return hal_rc == HAL_OK ? LFS_ERR_OK : LFS_ERR_IO;
}
// Sync the state of the underlying block device. Negative error codes
// are propogated to the user.
static int _internal_flash_sync(const struct lfs_config *c)
{
return LFS_ERR_OK; // don't need sync
}
struct lfs_config _InternalFSConfig = {
.context = NULL,
.read = _internal_flash_read,
.prog = _internal_flash_prog,
.erase = _internal_flash_erase,
.sync = _internal_flash_sync,
.read_size = LFS_BLOCK_SIZE,
.prog_size = LFS_BLOCK_SIZE,
.block_size = LFS_BLOCK_SIZE,
.block_count = LFS_FLASH_TOTAL_SIZE / LFS_BLOCK_SIZE,
.lookahead = 128,
.read_buffer = NULL,
.prog_buffer = NULL,
.lookahead_buffer = NULL,
.file_buffer = NULL
};
InternalFileSystem InternalFS;
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
InternalFileSystem::InternalFileSystem(void)
: Adafruit_LittleFS(&_InternalFSConfig)
{
}
bool InternalFileSystem::begin(void)
{
// failed to mount, erase all sector then format and mount again
if ( !Adafruit_LittleFS::begin() )
{
// lfs format
this->format();
// mount again if still failed, give up
if ( !Adafruit_LittleFS::begin() ) return false;
}
return true;
}

View file

@ -0,0 +1,48 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 hathach for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef INTERNALFILESYSTEM_H_
#define INTERNALFILESYSTEM_H_
#include "Adafruit_LittleFS.h"
#ifndef LFS_FLASH_TOTAL_SIZE /* Flash size can be configured in platformio.ini */
#define LFS_FLASH_TOTAL_SIZE (16 * 2048) /* defaults to 32k flash */
#endif
#define LFS_BLOCK_SIZE (2048)
#define LFS_FLASH_ADDR_BASE (FLASH_END_ADDR - LFS_FLASH_TOTAL_SIZE + 1)
class InternalFileSystem : public Adafruit_LittleFS
{
public:
InternalFileSystem(void);
// overwrite to also perform low level format (sector erase of whole flash region)
bool begin(void);
};
extern InternalFileSystem InternalFS;
#endif /* INTERNALFILESYSTEM_H_ */

View file

@ -0,0 +1,29 @@
#pragma once
#include <MeshCore.h>
#include <Arduino.h>
class STM32Board : public mesh::MainBoard {
protected:
uint8_t startup_reason;
public:
void begin() {
startup_reason = BD_STARTUP_NORMAL;
}
uint8_t getStartupReason() const override { return startup_reason; }
uint16_t getBattMilliVolts() override {
return 0; // not supported
}
const char* getManufacturerName() const override {
return "Generic STM32";
}
void reboot() override {
}
bool startOTAUpdate(const char* id, char reply[]) override { return false; };
};