Compare commits

...

1 Commits

Author SHA1 Message Date
alexcekay 07053ab823 v6s: support EEPROM-only boards alongside FRAM variants 2026-04-09 11:42:20 +02:00
3 changed files with 192 additions and 23 deletions
@@ -202,6 +202,9 @@ extern void stm32_spiinitialize(void);
extern void board_peripheral_reset(int ms);
/* Initialise the FRAM MTD. */
extern void board_configure_fram(void);
#include <px4_platform_common/board_common.h>
#endif /* __ASSEMBLY__ */
+128 -8
View File
@@ -55,10 +55,12 @@
#include <nuttx/config.h>
#include <nuttx/board.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/spi/spi.h>
#include <nuttx/sdio.h>
#include <nuttx/mmcsd.h>
#include <nuttx/analog/adc.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/mm/gran.h>
#include <chip.h>
#include <stm32_uart.h>
@@ -70,10 +72,14 @@
#include <systemlib/px4_macros.h>
#include <px4_arch/io_timer.h>
#include <px4_platform_common/init.h>
#include <px4_platform_common/micro_hal.h>
#include <px4_platform_common/px4_manifest.h>
#include <px4_platform/gpio.h>
#include <px4_platform_common/px4_mtd.h>
#include <px4_platform/board_determine_hw_info.h>
#include <px4_platform/board_dma_alloc.h>
#include <px4_platform/board_hw_eeprom_rev_ver.h>
#include <px4_platform/gpio.h>
#include <lib/crc/crc.h>
/****************************************************************************
* Pre-Processor Definitions
@@ -158,6 +164,80 @@ stm32_boardinitialize(void)
px4_gpio_init(gpio, arraySize(gpio));
}
#if !defined(BOOTLOADER)
/****************************************************************************
* Name: eeprom_read_and_check_mft
*
* Description:
* Read an mtd_mft_v0_t from the EEPROM at the given byte offset and
* validate its CRC. Returns true if the record has a recognised version
* field and a matching CRC16.
****************************************************************************/
static bool eeprom_read_and_check_mft(struct i2c_master_s *i2c, uint16_t address)
{
uint8_t addr_write[2] = { (uint8_t)(address >> 8), (uint8_t)(address & 0xFF) };
mtd_mft_v0_t mft = {};
struct i2c_msg_s msgs[2] = {
{ .frequency = 400000, .addr = 0x50, .flags = 0, .buffer = addr_write, .length = sizeof(addr_write) },
{ .frequency = 400000, .addr = 0x50, .flags = I2C_M_READ, .buffer = (uint8_t *) &mft, .length = sizeof(mft) },
};
int retries = 5;
while (I2C_TRANSFER(i2c, msgs, 2) != OK) {
if (--retries == 0) {
syslog(LOG_WARNING, "[boot] EEPROM I2C comm failed\n");
return false;
}
}
if (mft.version.id != MTD_MFT_v0) { return false; }
uint16_t computed = crc16_signature(CRC16_INITIAL, sizeof(mft) - sizeof(mft.crc), (const uint8_t *)&mft);
return computed == mft.crc;
}
/****************************************************************************
* Name: detect_layout_is_fram
*
* Description:
* Determine which EEPROM layout is present by reading MTD_MFT_VER from
* the two possible byte offsets and validating its CRC.
****************************************************************************/
static bool detect_layout_is_fram(void)
{
struct i2c_master_s *i2c = px4_i2cbus_initialize(4);
bool ret;
if (!i2c) {
syslog(LOG_WARNING, "[boot] EEPROM I2C init failed, defaulting to FRAM layout\n");
ret = true;
goto out;
}
/* FRAM-variant: MTD_MFT_VER after MTD_CALDATA (224 blocks x 32 B). */
if (eeprom_read_and_check_mft(i2c, 224u * 32u)) {
ret = true;
goto out;
}
/* EEPROM-only: MTD_MFT_VER is the first partition (0 blocks x 32 B)*/
if (eeprom_read_and_check_mft(i2c, 0u)) {
ret = false;
goto out;
}
/* Neither offset contains a valid record, default to FRAM layout. */
ret = true;
out:
px4_i2cbus_uninitialize(i2c);
return ret;
}
#endif /* !defined(BOOTLOADER) */
/****************************************************************************
* Name: board_app_initialize
*
@@ -187,15 +267,19 @@ __EXPORT int board_app_initialize(uintptr_t arg)
{
#if !defined(BOOTLOADER)
/* Need hrt running before using the ADC */
px4_platform_init();
// Use the default HW_VER_REV(0x0,0x0) for Ramtron
/* First SPI init. HW version is not enabled yet, so only always-enabled
* buses/devices can be used. */
stm32_spiinitialize();
/* Configure the HW based on the manifest */
bool fram_available = detect_layout_is_fram();
if (fram_available) {
board_configure_fram();
}
/* Configure the HW based on the manifest */
px4_platform_configure();
if (OK == board_determine_hw_info()) {
@@ -206,14 +290,24 @@ __EXPORT int board_app_initialize(uintptr_t arg)
syslog(LOG_ERR, "[boot] Failed to read HW revision and version\n");
}
/* Configure the Actual SPI interfaces (after we determined the HW version) */
/* EEPROM-only boards use a 128Kbit chip: 512 pages × 32 B = 16 KB.
* FRAM boards use a 64Kbit EEPROM: 256 pages × 32 B = 8 KB.
* Always use 32-byte page writes (safe for 64-byte page chips too). */
unsigned int mtd_count = 0;
mtd_instance_s **instances = px4_mtd_get_instances(&mtd_count);
uint16_t eeprom_npages = fram_available ? 256 : 512;
/* instances[0] is always EEPROM on both board variants. */
if (mtd_count > 0 && instances[0]->mtd_dev != NULL) {
px4_at24c_set_npages(instances[0]->mtd_dev, eeprom_npages);
}
/* Second SPI init. Now HW version is determined and complete init can be done. */
stm32_spiinitialize();
board_spi_reset(10, 0xffff);
/* Configure the DMA allocator */
if (board_dma_alloc_init() < 0) {
syslog(LOG_ERR, "[boot] DMA alloc FAILED\n");
}
@@ -234,7 +328,33 @@ __EXPORT int board_app_initialize(uintptr_t arg)
led_on(LED_RED);
}
if (nx_mount("/dev/mtdblock0", "/fs/microsd", "littlefs", 0, "autoformat") != 0) {
/* Mount LittleFS as /fs/microsd:
* FRAM boards: EEPROM->mtdblock0-4, FRAM->mtdblock5 (LittleFS).
* EEPROM-only: EEPROM->mtdblock0-2, FTL on free EEPROM region mtdblock3 (LittleFS). */
const char *lfs_dev;
if (fram_available) {
lfs_dev = "/dev/mtdblock5";
} else {
if (mtd_count > 0 && instances[0]->mtd_dev != NULL) {
FAR struct mtd_dev_s *eeprom_fs = mtd_partition(instances[0]->mtd_dev, 3, eeprom_npages - 3);
if (!eeprom_fs || ftl_initialize(3, eeprom_fs) != 0) {
syslog(LOG_ERR, "[boot] EEPROM: FTL init failed\n");
led_on(LED_RED);
}
} else {
syslog(LOG_ERR, "[boot] EEPROM not found\n");
led_on(LED_RED);
}
lfs_dev = "/dev/mtdblock3";
}
if (nx_mount(lfs_dev, "/fs/microsd", "littlefs", 0, "autoformat") != 0) {
syslog(LOG_ERR, "[boot] failed to mount /fs/microsd\n");
led_on(LED_RED);
}
+61 -15
View File
@@ -37,16 +37,15 @@
#include <nuttx/spi/spi.h>
#include <px4_platform_common/px4_manifest.h>
static const px4_mft_device_t spi4 = { // FM25V02A on FMUM native: 128K X 8, emulated as (1024 Blocks of 32)
static const px4_mft_device_t spi4 = { // MB85RS1MT on FMUM native: 1Mbit, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
static const px4_mft_device_t i2c4 = { // 24LC64T 8K 32 X 256
static const px4_mft_device_t i2c4 = { // 24LC64T 8K 32 X 256 or 16K for EEPROM only boards
.bus_type = px4_mft_device_t::I2C,
.devid = PX4_MK_I2C_DEVID(4, 0x50)
};
static const px4_mtd_entry_t fmum_fram = {
.device = &spi4,
.npart = 1,
@@ -59,7 +58,36 @@ static const px4_mtd_entry_t fmum_fram = {
},
};
/* EEPROM layout for EEPROM-only boards (128Kbit, 512 pages x 32B = 16KB). */
static constexpr uint32_t kEepromParts = 3;
static const px4_mtd_entry_t fmum_eeprom = {
.device = &i2c4,
.npart = kEepromParts,
.partd = {
{
.type = MTD_MFT_VER,
.path = "/fs/mtd_mft_ver",
.nblocks = 1
},
{
.type = MTD_MFT_REV,
.path = "/fs/mtd_mft_rev",
.nblocks = 1
},
{
.type = MTD_NET,
.path = "/fs/mtd_net",
.nblocks = 1
}
},
};
static_assert(kEepromParts == 3,
"EEPROM partition count changed: update init.c accordingly");
/* EEPROM layout for FRAM boards (64Kbit, 256 pages x 32B = 8KB).
* Matches existing layout for backwards compatibility reasons. */
static const px4_mtd_entry_t fmum_eeprom_fram = {
.device = &i2c4,
.npart = 5,
.partd = {
@@ -81,22 +109,24 @@ static const px4_mtd_entry_t fmum_eeprom = {
{
.type = MTD_ID,
.path = "/fs/mtd_id",
.nblocks = 8 // 256 = 32 * 8
.nblocks = 8
},
{
.type = MTD_NET,
.path = "/fs/mtd_net",
.nblocks = 8 // 256 = 32 * 8
.nblocks = 8
}
},
};
static const px4_mtd_manifest_t board_mtd_config = {
.nconfigs = 2,
.entries = {
&fmum_fram,
&fmum_eeprom
}
.nconfigs = 1,
.entries = { &fmum_eeprom }
};
static const px4_mtd_manifest_t board_mtd_config_fram = {
.nconfigs = 2,
.entries = { &fmum_eeprom_fram, &fmum_fram }
};
static const px4_mft_entry_s mtd_mft = {
@@ -104,20 +134,36 @@ static const px4_mft_entry_s mtd_mft = {
.pmft = (void *) &board_mtd_config,
};
static const px4_mft_entry_s mtd_mft_fram = {
.type = MTD,
.pmft = (void *) &board_mtd_config_fram,
};
static const px4_mft_entry_s mft_mft = {
.type = MFT,
.pmft = (void *) system_query_manifest,
};
/* Manifest for EEPROM only boards */
static const px4_mft_s mft = {
.nmft = 2,
.mfts = {
&mtd_mft,
&mft_mft,
}
.mfts = { &mtd_mft, &mft_mft }
};
/* Manifest for EEPROM + FRAM boards */
static const px4_mft_s mft_fram = {
.nmft = 2,
.mfts = { &mtd_mft_fram, &mft_mft }
};
static const px4_mft_s *g_manifest = &mft;
const px4_mft_s *board_get_manifest(void)
{
return &mft;
return g_manifest;
}
void board_configure_fram(void)
{
g_manifest = &mft_fram;
}