mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-05-24 23:07:35 +08:00
Compare commits
1 Commits
main
...
pr-s-eeprom
| Author | SHA1 | Date | |
|---|---|---|---|
| 07053ab823 |
@@ -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__ */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user