Support STM32F7 1MB devices (#2659)
* modify linker script for 1MB devices * handle null flash address * actually support 1MB F7 * comment
This commit is contained in:
parent
1f0983c2ab
commit
155bfd9aeb
|
@ -86,8 +86,12 @@ void writeToFlashIfPending() {
|
||||||
|
|
||||||
// Erase and write a copy of the configuration at the specified address
|
// Erase and write a copy of the configuration at the specified address
|
||||||
template <typename TStorage>
|
template <typename TStorage>
|
||||||
int eraseAndFlashCopy(flashaddr_t storageAddress, const TStorage& data)
|
int eraseAndFlashCopy(flashaddr_t storageAddress, const TStorage& data) {
|
||||||
{
|
// error already reported, return
|
||||||
|
if (!storageAddress) {
|
||||||
|
return FLASH_RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
auto err = intFlashErase(storageAddress, sizeof(TStorage));
|
auto err = intFlashErase(storageAddress, sizeof(TStorage));
|
||||||
if (FLASH_RETURN_SUCCESS != err) {
|
if (FLASH_RETURN_SUCCESS != err) {
|
||||||
firmwareError(OBD_PCM_Processor_Fault, "Failed to erase flash at %#010x", storageAddress);
|
firmwareError(OBD_PCM_Processor_Fault, "Failed to erase flash at %#010x", storageAddress);
|
||||||
|
@ -145,6 +149,12 @@ typedef enum {
|
||||||
|
|
||||||
static persisted_configuration_state_e doReadConfiguration(flashaddr_t address) {
|
static persisted_configuration_state_e doReadConfiguration(flashaddr_t address) {
|
||||||
efiPrintf("readFromFlash %x", address);
|
efiPrintf("readFromFlash %x", address);
|
||||||
|
|
||||||
|
// error already reported, return
|
||||||
|
if (!address) {
|
||||||
|
return CRC_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
intFlashRead(address, (char *) &persistentState, sizeof(persistentState));
|
intFlashRead(address, (char *) &persistentState, sizeof(persistentState));
|
||||||
|
|
||||||
if (!isValidCrc(&persistentState)) {
|
if (!isValidCrc(&persistentState)) {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* STM32F76xxI generic setup.
|
* STM32F7 memory setup.
|
||||||
*
|
*
|
||||||
* RAM0 - Data, Heap.
|
* RAM0 - Data, Heap.
|
||||||
* RAM3 - Main Stack, Process Stack, BSS, NOCACHE, ETH.
|
* RAM3 - Main Stack, Process Stack, BSS, NOCACHE, ETH.
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
bl : org = 0x08000000, len = 16k /* bootloader section */
|
bl : org = 0x08000000, len = 16k /* bootloader section */
|
||||||
flash0 (rx) : org = DEFINED(BOOTLOADER) ? 0x08008000 : 0x08000000, len = DEFINED(BOOTLOADER) ? 1992k : 2048k
|
flash0 (rx) : org = DEFINED(BOOTLOADER) ? 0x08008000 : 0x08000000, len = DEFINED(BOOTLOADER) ? 736k : 768k /* change address & length if bootloader */
|
||||||
flash1 (rx) : org = 0x00200000, len = 2M /* Flash as ITCM */ /* TODO: do we need BOOTLOADER logic here? */
|
flash1 (rx) : org = 0x00200000, len = 2M /* Flash as ITCM */ /* TODO: do we need BOOTLOADER logic here? */
|
||||||
flash2 (rx) : org = 0x00000000, len = 0
|
flash2 (rx) : org = 0x00000000, len = 0
|
||||||
flash3 (rx) : org = 0x00000000, len = 0
|
flash3 (rx) : org = 0x00000000, len = 0
|
|
@ -8,7 +8,7 @@ HW_LAYER_EMS_CPP += $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f7/mpu_util.cpp \
|
||||||
|
|
||||||
DDEFS += -DSTM32F767xx
|
DDEFS += -DSTM32F767xx
|
||||||
MCU = cortex-m7
|
MCU = cortex-m7
|
||||||
LDSCRIPT = $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f7/STM32F76xxI.ld
|
LDSCRIPT = $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f7/STM32F7.ld
|
||||||
ALLCSRC += $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_F767ZI/board.c
|
ALLCSRC += $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_F767ZI/board.c
|
||||||
CONFDIR = $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f7/cfg
|
CONFDIR = $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f7/cfg
|
||||||
|
|
||||||
|
|
|
@ -5,23 +5,106 @@
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2020
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
#include "flash_int.h"
|
#include "flash_int.h"
|
||||||
|
|
||||||
|
static bool isDualBank() {
|
||||||
|
// cleared bit indicates dual bank
|
||||||
|
return (FLASH->OPTCR & FLASH_OPTCR_nDBANK) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t flashSize() {
|
||||||
|
return *reinterpret_cast<const volatile uint16_t*>(FLASHSIZE_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class DeviceType {
|
||||||
|
DualBank1MB,
|
||||||
|
DualBank2MB,
|
||||||
|
SingleBank1MB,
|
||||||
|
SingleBank2MB,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
static DeviceType determineDevice() {
|
||||||
|
bool db = isDualBank();
|
||||||
|
uint16_t fs = flashSize();
|
||||||
|
|
||||||
|
if (db) {
|
||||||
|
if (fs == 1024) {
|
||||||
|
return DeviceType::DualBank1MB;
|
||||||
|
} else if (fs == 2048) {
|
||||||
|
return DeviceType::DualBank2MB;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fs == 1024) {
|
||||||
|
// Unsupported scenario! Not enough space for program plus two config copies
|
||||||
|
firmwareError(OBD_PCM_Processor_Fault, "1MB single bank MCU detected: please clear nDBANK option bit and reinstall FW.");
|
||||||
|
return DeviceType::SingleBank1MB;
|
||||||
|
} else if (fs == 2048) {
|
||||||
|
return DeviceType::SingleBank2MB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
firmwareError(OBD_PCM_Processor_Fault, "Unrecognized flash memory layout db=%d, size=%d", db, fs);
|
||||||
|
return DeviceType::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See ST AN4826
|
||||||
size_t flashSectorSize(flashsector_t sector) {
|
size_t flashSectorSize(flashsector_t sector) {
|
||||||
// sectors 0..11 are the 1st memory bank (1Mb), and 12..23 are the 2nd (the same structure).
|
// 1MB devices have 8 sectors per bank
|
||||||
if (sector <= 3 || (sector >= 12 && sector <= 15))
|
// 2MB devices have 12 sectors per bank
|
||||||
return 32 * 1024;
|
// However, the second bank always starts at index 12 (1MB devices have a 4 sector discontinuity between banks)
|
||||||
else if (sector == 4 || sector == 16)
|
|
||||||
return 128 * 1024;
|
if (sector >= 12) {
|
||||||
else if ((sector >= 5 && sector <= 11) || (sector >= 17 && sector <= 23))
|
// The second bank has the same structure as the first
|
||||||
return 256 * 1024;
|
return flashSectorSize(sector - 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pages are twice the size when in single bank mode
|
||||||
|
size_t dbMul = isDualBank() ? 1 : 2;
|
||||||
|
|
||||||
|
if (sector <= 3)
|
||||||
|
return 16 * 1024 * dbMul;
|
||||||
|
else if (sector == 4)
|
||||||
|
return 64 * 1024 * dbMul;
|
||||||
|
else if (sector >= 5)
|
||||||
|
return 128 * 1024 * dbMul;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t getFlashAddrFirstCopy() {
|
uintptr_t getFlashAddrFirstCopy() {
|
||||||
return 0x08100000;
|
switch (determineDevice()) {
|
||||||
|
case DeviceType::DualBank1MB:
|
||||||
|
// Sector 18, second to last 128K sector
|
||||||
|
return 0x080C0000;
|
||||||
|
case DeviceType::SingleBank1MB:
|
||||||
|
// Sector 7, last 256K sector
|
||||||
|
return 0x080C0000;
|
||||||
|
case DeviceType::DualBank2MB: /* falls thru */
|
||||||
|
case DeviceType::SingleBank2MB:
|
||||||
|
// Start of the second megabyte
|
||||||
|
// Sector 12 for dual bank
|
||||||
|
// Sector 8 for single bank
|
||||||
|
return 0x08100000;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t getFlashAddrSecondCopy() {
|
uintptr_t getFlashAddrSecondCopy() {
|
||||||
return 0x08140000;
|
switch (determineDevice()) {
|
||||||
|
case DeviceType::DualBank1MB:
|
||||||
|
// Sector 19, last 128K sector, 128K after the first copy
|
||||||
|
return 0x080E0000;
|
||||||
|
case DeviceType::DualBank2MB:
|
||||||
|
// Sector 14, 32K after the first copy
|
||||||
|
return 0x08108000;
|
||||||
|
case DeviceType::SingleBank2MB:
|
||||||
|
// Sector 9, 256K after the first copy
|
||||||
|
return 0x08140000;
|
||||||
|
case DeviceType::SingleBank1MB:
|
||||||
|
// We can't fit a second copy in this config, fall thru to failure case
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue