STM32F76xxx: Added flashing in dual bank mode

(Closes #1174)
pull/1373/head
nightwalker-87 2023-11-27 22:00:27 +01:00
rodzic 4637b1497b
commit ba335a47ab
6 zmienionych plików z 145 dodań i 52 usunięć

Wyświetl plik

@ -233,6 +233,8 @@ struct _stlink {
uint32_t max_trace_freq; // set by stlink_open_usb()
bool dual_bank; // set for F7xxx devices by reading optcr
uint32_t otp_base;
uint32_t otp_size;
};

Wyświetl plik

@ -142,6 +142,7 @@
#define FLASH_F7_OPTCR_START 1
#define FLASH_F7_OPTCR1_BOOT_ADD0 0
#define FLASH_F7_OPTCR1_BOOT_ADD1 16
#define FLASH_F7_OPTCR_DBANK (29) /* FLASH_OPTCR Dual Bank Mode */
// F7 Flash control register
#define FLASH_F7_CR_STRT 16
@ -332,7 +333,7 @@
#define FLASH_L4_OPTR (FLASH_REGS_ADDR + 0x20)
// L4 Flash status register
#define FLASH_L4_SR_ERROR_MASK 0x3f8 /* SR [9:3] */
#define FLASH_L4_SR_ERROR_MASK 0x3f8 // SR [9:3]
#define FLASH_L4_SR_PROGERR 3
#define FLASH_L4_SR_WRPERR 4
#define FLASH_L4_SR_PGAERR 5
@ -428,7 +429,7 @@
#define FLASH_WB_CR_LOCK (31) /* Lock */
// WB Flash status register
#define FLASH_WB_SR_ERROR_MASK (0x3f8) /* SR [9:3] */
#define FLASH_WB_SR_ERROR_MASK (0x3f8) // SR [9:3]
#define FLASH_WB_SR_PROGERR (3) /* Programming alignment error */
#define FLASH_WB_SR_WRPERR (4) /* Write protection error */
#define FLASH_WB_SR_PGAERR (5) /* Programming error */

Wyświetl plik

@ -36,7 +36,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr) {
}
}
uint32_t calculate_F7_sectornum(uint32_t flashaddr) {
uint32_t calculate_F7_sectornum_old(uint32_t flashaddr) {
flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address
if (flashaddr < 0x20000) {
@ -49,10 +49,8 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) {
}
uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, uint32_t bank) {
flashaddr &=
~((bank == BANK_1)
? STM32_FLASH_BASE
: STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address
// sector holding the flash address
flashaddr &= ~((bank == BANK_1) ? STM32_FLASH_BASE : STM32_H7_FLASH_BANK2_BASE);
return (flashaddr / sl->flash_pgsz);
}

Wyświetl plik

@ -318,6 +318,19 @@ int32_t stlink_load_device_params(stlink_t *sl) {
}
}
// F76xxx device with dual bank
if (sl->chip_id == STM32_CHIPID_F76xxx) {
// Check the nDBANK bit in OPTCR
uint32_t optcr;
stlink_read_option_control_register32(sl, & optcr);
if (!(optcr & (1 << STM32F7_FLASH_OPTCR_DBANK)))
{
sl->dual_bank = true;
}
DLOG("*** stm32f76xx dual-bank %d ***\n", sl->dual_bank);
}
// H7 devices with small flash has one bank
if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK &&
sl->flash_type == STM32_FLASH_TYPE_H7) {
@ -830,8 +843,87 @@ int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *bu
return (ret);
}
/* STM32F7 Series Flash memory dual bank mode
* See application note AN4826 pp.18
*/
struct sectors_f7 {
int sector;
uint32_t base;
uint32_t size;
};
static const struct sectors_f7 f7_single[] = {
{ 0, 0x08000000, 0x8000 },
{ 1, 0x08008000, 0x8000 },
{ 2, 0x08010000, 0x8000 },
{ 3, 0x08018000, 0x8000 },
{ 4, 0x08020000, 0x20000 },
{ 5, 0x08040000, 0x40000 },
{ 6, 0x08080000, 0x40000 },
{ 7, 0x080C0000, 0x40000 },
{ 0, 0, 0 },
};
static const struct sectors_f7 f7_dual[] = {
{ 0, 0x08000000, 0x4000 },
{ 1, 0x08004000, 0x4000 },
{ 2, 0x08008000, 0x4000 },
{ 3, 0x0800C000, 0x4000 },
{ 4, 0x08010000, 0x10000 },
{ 5, 0x08020000, 0x20000 },
{ 6, 0x08040000, 0x20000 },
{ 7, 0x08060000, 0x20000 },
{ 8, 0x08080000, 0x20000 },
{ 9, 0x080A0000, 0x20000 },
{ 10, 0x080C0000, 0x20000 },
{ 11, 0x080E0000, 0x20000 },
{ 12, 0x08100000, 0x4000 },
{ 13, 0x08104000, 0x4000 },
{ 14, 0x08108000, 0x4000 },
{ 15, 0x0810C000, 0x4000 },
{ 16, 0x08110000, 0x10000 },
{ 17, 0x08120000, 0x20000 },
{ 18, 0x08140000, 0x20000 },
{ 19, 0x08160000, 0x20000 },
{ 20, 0x08180000, 0x20000 },
{ 21, 0x081A0000, 0x20000 },
{ 22, 0x081C0000, 0x20000 },
{ 23, 0x081E0000, 0x20000 },
{ 0, 0, 0 },
};
static const struct sectors_f7 *get_f7_info(stlink_t *sl) {
return sl->dual_bank ? f7_dual : f7_single;
}
static const struct sectors_f7 *find_sector(stlink_t *sl, uint32_t flashaddr) {
for (const struct sectors_f7 *s = get_f7_info(sl); s->base; s++) {
const uint32_t end = s->base + s->size;
if ((s->base <= flashaddr) && (flashaddr < end)) {
return s;
}
}
fprintf(stderr, "Bad address %#x\n", flashaddr);
exit(0);
}
uint32_t calculate_F7_sectornum(stlink_t *sl, uint32_t flashaddr) {
if (sl->chip_id == STM32_CHIPID_F76xxx) {
const struct sectors_f7 *s = find_sector(sl, flashaddr);
return s->sector;
}
return calculate_F7_sectornum_old(flashaddr);
}
// 291
uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) {
if (sl->chip_id == STM32_CHIPID_F76xxx) {
const struct sectors_f7 *s = find_sector(sl, flashaddr);
return s->size;
}
if ((sl->chip_id == STM32_CHIPID_F2) ||
(sl->chip_id == STM32_CHIPID_F4) ||
(sl->chip_id == STM32_CHIPID_F4_DE) ||
@ -857,7 +949,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) {
}
} else if (sl->chip_id == STM32_CHIPID_F7 ||
sl->chip_id == STM32_CHIPID_F76xxx) {
uint32_t sector = calculate_F7_sectornum(flashaddr);
uint32_t sector = calculate_F7_sectornum(sl, flashaddr);
if (sector < 4) {
sl->flash_pgsz = 0x8000;

Wyświetl plik

@ -145,7 +145,7 @@ static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val)
} else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) {
sr_reg = FLASH_F4_SR;
} else if (sl->flash_type == STM32_FLASH_TYPE_F7) {
sr_reg = FLASH_F7_SR;
sr_reg = (bank == BANK_1) ? FLASH_F7_SR1 : FLASH_F7_SR2;
} else if (sl->flash_type == STM32_FLASH_TYPE_G0 ||
sl->flash_type == STM32_FLASH_TYPE_G4) {
sr_reg = FLASH_Gx_SR;
@ -1025,7 +1025,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) {
} else if (sl->chip_id == STM32_CHIPID_F7 ||
sl->chip_id == STM32_CHIPID_F76xxx) {
// calculate the actual page from the address
uint32_t sector = calculate_F7_sectornum(flashaddr);
uint32_t sector = calculate_F7_sectornum(sl, flashaddr);
fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector,
stlink_calculate_pagesize(sl, flashaddr));