mirror of https://github.com/rusefi/rusefi-1.git
H7 flash (#2408)
* enable * defines and mpu util * implement flash for h7 * format
This commit is contained in:
parent
af5cefae43
commit
520fc2b4ec
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#undef EFI_INTERNAL_FLASH
|
|
||||||
#define EFI_INTERNAL_FLASH FALSE
|
|
||||||
|
|
||||||
#undef EFI_MC33816
|
#undef EFI_MC33816
|
||||||
#define EFI_MC33816 FALSE
|
#define EFI_MC33816 FALSE
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ extern "C" {
|
||||||
* 11 to program 64 bits per step
|
* 11 to program 64 bits per step
|
||||||
*/
|
*/
|
||||||
// Warning, flashdata_t must be unsigned!!!
|
// Warning, flashdata_t must be unsigned!!!
|
||||||
#if defined(STM32F4XX) || defined(STM32F7XX)
|
#if defined(STM32F4XX) || defined(STM32F7XX) || defined(STM32H7XX)
|
||||||
#define FLASH_CR_PSIZE_MASK FLASH_CR_PSIZE_0 | FLASH_CR_PSIZE_1
|
#define FLASH_CR_PSIZE_MASK FLASH_CR_PSIZE_0 | FLASH_CR_PSIZE_1
|
||||||
#if ((STM32_VDD >= 270) && (STM32_VDD <= 360))
|
#if ((STM32_VDD >= 270) && (STM32_VDD <= 360))
|
||||||
#define FLASH_CR_PSIZE_VALUE FLASH_CR_PSIZE_1
|
#define FLASH_CR_PSIZE_VALUE FLASH_CR_PSIZE_1
|
||||||
|
|
|
@ -15,6 +15,30 @@
|
||||||
#include "flash_int.h"
|
#include "flash_int.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef STM32H7XX
|
||||||
|
// Use bank 2 on H7
|
||||||
|
#define FLASH_CR FLASH->CR2
|
||||||
|
#define FLASH_SR FLASH->SR2
|
||||||
|
#define FLASH_KEYR FLASH->KEYR2
|
||||||
|
|
||||||
|
// I have no idea why ST changed the register name from STRT -> START
|
||||||
|
#define FLASH_CR_STRT FLASH_CR_START
|
||||||
|
|
||||||
|
#undef FLASH_BASE
|
||||||
|
// This is the start of the second bank, since H7 sector numbers are bank relative
|
||||||
|
#define FLASH_BASE 0x08100000
|
||||||
|
|
||||||
|
// QW bit supercedes the older BSY bit
|
||||||
|
#define intFlashWaitWhileBusy() { while (FLASH_SR & FLASH_SR_QW) {} }
|
||||||
|
#else
|
||||||
|
#define FLASH_CR FLASH->CR
|
||||||
|
#define FLASH_SR FLASH->SR
|
||||||
|
#define FLASH_KEYR FLASH->KEYR
|
||||||
|
|
||||||
|
// Wait for the flash operation to finish
|
||||||
|
#define intFlashWaitWhileBusy() { while (FLASH->SR & FLASH_SR_BSY) {} }
|
||||||
|
#endif
|
||||||
|
|
||||||
flashaddr_t intFlashSectorBegin(flashsector_t sector) {
|
flashaddr_t intFlashSectorBegin(flashsector_t sector) {
|
||||||
flashaddr_t address = FLASH_BASE;
|
flashaddr_t address = FLASH_BASE;
|
||||||
while (sector > 0) {
|
while (sector > 0) {
|
||||||
|
@ -35,11 +59,6 @@ flashsector_t intFlashSectorAt(flashaddr_t address) {
|
||||||
return sector;
|
return sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wait for the flash operation to finish.
|
|
||||||
*/
|
|
||||||
#define intFlashWaitWhileBusy() { while (FLASH->SR & FLASH_SR_BSY) {} }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unlock the flash memory for write access.
|
* @brief Unlock the flash memory for write access.
|
||||||
* @return HAL_SUCCESS Unlock was successful.
|
* @return HAL_SUCCESS Unlock was successful.
|
||||||
|
@ -47,15 +66,15 @@ flashsector_t intFlashSectorAt(flashaddr_t address) {
|
||||||
*/
|
*/
|
||||||
static bool intFlashUnlock(void) {
|
static bool intFlashUnlock(void) {
|
||||||
/* Check if unlock is really needed */
|
/* Check if unlock is really needed */
|
||||||
if (!(FLASH->CR & FLASH_CR_LOCK))
|
if (!(FLASH_CR & FLASH_CR_LOCK))
|
||||||
return HAL_SUCCESS;
|
return HAL_SUCCESS;
|
||||||
|
|
||||||
/* Write magic unlock sequence */
|
/* Write magic unlock sequence */
|
||||||
FLASH->KEYR = 0x45670123;
|
FLASH_KEYR = 0x45670123;
|
||||||
FLASH->KEYR = 0xCDEF89AB;
|
FLASH_KEYR = 0xCDEF89AB;
|
||||||
|
|
||||||
/* Check if unlock was successful */
|
/* Check if unlock was successful */
|
||||||
if (FLASH->CR & FLASH_CR_LOCK)
|
if (FLASH_CR & FLASH_CR_LOCK)
|
||||||
return HAL_FAILED;
|
return HAL_FAILED;
|
||||||
return HAL_SUCCESS;
|
return HAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +82,7 @@ static bool intFlashUnlock(void) {
|
||||||
/**
|
/**
|
||||||
* @brief Lock the flash memory for write access.
|
* @brief Lock the flash memory for write access.
|
||||||
*/
|
*/
|
||||||
#define intFlashLock() { FLASH->CR |= FLASH_CR_LOCK; }
|
#define intFlashLock() { FLASH_CR |= FLASH_CR_LOCK; }
|
||||||
|
|
||||||
int intFlashSectorErase(flashsector_t sector) {
|
int intFlashSectorErase(flashsector_t sector) {
|
||||||
/* Unlock flash for write access */
|
/* Unlock flash for write access */
|
||||||
|
@ -74,8 +93,8 @@ int intFlashSectorErase(flashsector_t sector) {
|
||||||
intFlashWaitWhileBusy();
|
intFlashWaitWhileBusy();
|
||||||
|
|
||||||
/* Setup parallelism before any program/erase */
|
/* Setup parallelism before any program/erase */
|
||||||
FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
|
FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
|
||||||
FLASH->CR |= FLASH_CR_PSIZE_VALUE;
|
FLASH_CR |= FLASH_CR_PSIZE_VALUE;
|
||||||
|
|
||||||
/* Start deletion of sector.
|
/* Start deletion of sector.
|
||||||
* SNB(4:1) is defined as:
|
* SNB(4:1) is defined as:
|
||||||
|
@ -87,31 +106,35 @@ int intFlashSectorErase(flashsector_t sector) {
|
||||||
* ...
|
* ...
|
||||||
* 10111 sector 23 (the end of 2nd bank, 2Mb border)
|
* 10111 sector 23 (the end of 2nd bank, 2Mb border)
|
||||||
* others not allowed */
|
* others not allowed */
|
||||||
#ifndef FLASH_CR_SNB_4
|
#ifndef FLASH_CR_SNB_3
|
||||||
FLASH->CR &= ~(FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2 | FLASH_CR_SNB_3);
|
FLASH_CR &= ~(FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2);
|
||||||
|
#elif !defined(FLASH_CR_SNB_4)
|
||||||
|
FLASH_CR &= ~(FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2 | FLASH_CR_SNB_3);
|
||||||
#else
|
#else
|
||||||
FLASH->CR &= ~(FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2 | FLASH_CR_SNB_3 | FLASH_CR_SNB_4);
|
FLASH_CR &= ~(FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2 | FLASH_CR_SNB_3 | FLASH_CR_SNB_4);
|
||||||
#endif
|
#endif
|
||||||
if (sector & 0x1)
|
if (sector & 0x1)
|
||||||
FLASH->CR |= FLASH_CR_SNB_0;
|
FLASH_CR |= FLASH_CR_SNB_0;
|
||||||
if (sector & 0x2)
|
if (sector & 0x2)
|
||||||
FLASH->CR |= FLASH_CR_SNB_1;
|
FLASH_CR |= FLASH_CR_SNB_1;
|
||||||
if (sector & 0x4)
|
if (sector & 0x4)
|
||||||
FLASH->CR |= FLASH_CR_SNB_2;
|
FLASH_CR |= FLASH_CR_SNB_2;
|
||||||
|
#ifdef FLASH_CR_SNB_4
|
||||||
if (sector & 0x8)
|
if (sector & 0x8)
|
||||||
FLASH->CR |= FLASH_CR_SNB_3;
|
FLASH_CR |= FLASH_CR_SNB_3;
|
||||||
|
#endif
|
||||||
#ifdef FLASH_CR_SNB_4
|
#ifdef FLASH_CR_SNB_4
|
||||||
if (sector & 0x10)
|
if (sector & 0x10)
|
||||||
FLASH->CR |= FLASH_CR_SNB_4;
|
FLASH_CR |= FLASH_CR_SNB_4;
|
||||||
#endif
|
#endif
|
||||||
FLASH->CR |= FLASH_CR_SER;
|
FLASH_CR |= FLASH_CR_SER;
|
||||||
FLASH->CR |= FLASH_CR_STRT;
|
FLASH_CR |= FLASH_CR_STRT;
|
||||||
|
|
||||||
/* Wait until it's finished. */
|
/* Wait until it's finished. */
|
||||||
intFlashWaitWhileBusy();
|
intFlashWaitWhileBusy();
|
||||||
|
|
||||||
/* Sector erase flag does not clear automatically. */
|
/* Sector erase flag does not clear automatically. */
|
||||||
FLASH->CR &= ~FLASH_CR_SER;
|
FLASH_CR &= ~FLASH_CR_SER;
|
||||||
|
|
||||||
/* Lock flash again */
|
/* Lock flash again */
|
||||||
intFlashLock()
|
intFlashLock()
|
||||||
|
@ -187,6 +210,61 @@ int intFlashRead(flashaddr_t address, char* buffer, size_t size) {
|
||||||
return FLASH_RETURN_SUCCESS;
|
return FLASH_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef STM32H7XX
|
||||||
|
int intFlashWrite(flashaddr_t address, const char* buffer, size_t size) {
|
||||||
|
/* Unlock flash for write access */
|
||||||
|
if (intFlashUnlock() == HAL_FAILED)
|
||||||
|
return FLASH_RETURN_NO_PERMISSION;
|
||||||
|
|
||||||
|
/* Wait for any busy flags */
|
||||||
|
intFlashWaitWhileBusy();
|
||||||
|
|
||||||
|
/* Setup parallelism before program */
|
||||||
|
FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
|
||||||
|
FLASH_CR |= FLASH_CR_PSIZE_VALUE;
|
||||||
|
|
||||||
|
// Round up to the next number of full 32 byte words
|
||||||
|
size_t flashWordCount = (size - 1) / 32 + 1;
|
||||||
|
|
||||||
|
// Read units of flashdata_t from the buffer, writing to flash
|
||||||
|
const flashdata_t* pRead = (const flashdata_t*)buffer;
|
||||||
|
flashdata_t* pWrite = (flashdata_t*)address;
|
||||||
|
|
||||||
|
for (size_t word = 0; word < flashWordCount; word++) {
|
||||||
|
/* Enter flash programming mode */
|
||||||
|
FLASH_CR |= FLASH_CR_PG;
|
||||||
|
|
||||||
|
// Flush pipelines
|
||||||
|
__ISB();
|
||||||
|
__DSB();
|
||||||
|
|
||||||
|
// Write 32 bytes
|
||||||
|
for (size_t i = 0; i < 8; i++) {
|
||||||
|
*pWrite++ = *pRead++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush pipelines
|
||||||
|
__ISB();
|
||||||
|
__DSB();
|
||||||
|
|
||||||
|
/* Wait for completion */
|
||||||
|
intFlashWaitWhileBusy();
|
||||||
|
|
||||||
|
/* Exit flash programming mode */
|
||||||
|
FLASH_CR &= ~FLASH_CR_PG;
|
||||||
|
|
||||||
|
// Flush pipelines
|
||||||
|
__ISB();
|
||||||
|
__DSB();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock flash again */
|
||||||
|
intFlashLock();
|
||||||
|
|
||||||
|
return FLASH_RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // not STM32H7XX
|
||||||
static void intFlashWriteData(flashaddr_t address, const flashdata_t data) {
|
static void intFlashWriteData(flashaddr_t address, const flashdata_t data) {
|
||||||
/* Enter flash programming mode */
|
/* Enter flash programming mode */
|
||||||
FLASH->CR |= FLASH_CR_PG;
|
FLASH->CR |= FLASH_CR_PG;
|
||||||
|
@ -276,5 +354,6 @@ int intFlashWrite(flashaddr_t address, const char* buffer, size_t size) {
|
||||||
|
|
||||||
return FLASH_RETURN_SUCCESS;
|
return FLASH_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* EFI_INTERNAL_FLASH */
|
#endif /* EFI_INTERNAL_FLASH */
|
||||||
|
|
|
@ -76,6 +76,12 @@
|
||||||
#define STM32_HSE_BYPASS
|
#define STM32_HSE_BYPASS
|
||||||
#endif /* EFI_USE_OSC */
|
#endif /* EFI_USE_OSC */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Board voltages.
|
||||||
|
* Required for performance limits calculation.
|
||||||
|
*/
|
||||||
|
#define STM32_VDD 330U
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MCU type as defined in the ST header.
|
* MCU type as defined in the ST header.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @file mpu_util.cpp
|
||||||
|
*
|
||||||
|
* @date Feb 26, 2021
|
||||||
|
* @author Matthew Kennedy, (c) 2021
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flash_int.h"
|
||||||
|
|
||||||
|
size_t flashSectorSize(flashsector_t sector) {
|
||||||
|
// All sectors on H7 are 128k
|
||||||
|
return 128 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t getFlashAddrFirstCopy() {
|
||||||
|
return 0x08100000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t getFlashAddrSecondCopy() {
|
||||||
|
// Second copy is one sector past the first
|
||||||
|
return getFlashAddrFirstCopy() + 128 * 1024;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue