Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Added support for STM32H742/743/753 #1052

Merged
merged 4 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion inc/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ enum stlink_flash_type {
STLINK_FLASH_TYPE_L4, // l4, l4+ */
STLINK_FLASH_TYPE_G0,
STLINK_FLASH_TYPE_G4,
STLINK_FLASH_TYPE_WB
STLINK_FLASH_TYPE_WB,
STLINK_FLASH_TYPE_H7,
};

struct stlink_reg {
Expand Down
123 changes: 114 additions & 9 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,22 @@
#define FLASH_F2_CR_SNB_MASK 0x78
#define FLASH_F2_SR_BSY 16

// STM32H7xx
#define FLASH_H7_CR_LOCK 0
#define FLASH_H7_CR_PG 1
#define FLASH_H7_CR_SER 2
#define FLASH_H7_CR_PSIZE 4
#define FLASH_H7_CR_START 7
#define FLASH_H7_CR_SNB 8
#define FLASH_H7_CR_SNB_MASK 0x700

#define FLASH_H7_SR_QW 2

#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000)
#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04)
#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c)
#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10)

#define L1_WRITE_BLOCK_SIZE 0x80
#define L0_WRITE_BLOCK_SIZE 0x40

Expand Down Expand Up @@ -381,6 +397,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) {
reg = STM32Gx_FLASH_CR;
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
reg = STM32WB_FLASH_CR;
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
reg = FLASH_H7_CR1;
} else {
reg = FLASH_CR;
}
Expand Down Expand Up @@ -431,6 +449,9 @@ static inline unsigned int is_flash_locked(stlink_t *sl) {
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
cr_reg = STM32WB_FLASH_CR;
cr_lock_shift = STM32WB_FLASH_CR_LOCK;
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
cr_reg = FLASH_H7_CR1;
cr_lock_shift = FLASH_H7_CR_LOCK;
} else {
ELOG("unsupported flash method, abort\n");
return(-1);
Expand Down Expand Up @@ -467,6 +488,8 @@ static void unlock_flash(stlink_t *sl) {
key_reg = STM32Gx_FLASH_KEYR;
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
key_reg = STM32WB_FLASH_KEYR;
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
key_reg = FLASH_H7_KEYR1;
} else {
ELOG("unsupported flash method, abort\n");
return;
Expand Down Expand Up @@ -498,6 +521,7 @@ static int unlock_flash_if(stlink_t *sl) {

static void lock_flash(stlink_t *sl) {
uint32_t cr_lock_shift, cr_reg, n;
uint32_t cr_mask = 0xffffffffu;

if (sl->flash_type == STLINK_FLASH_TYPE_F0 ||
sl->flash_type == STLINK_FLASH_TYPE_F1_XL) {
Expand All @@ -522,12 +546,17 @@ static void lock_flash(stlink_t *sl) {
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
cr_reg = STM32WB_FLASH_CR;
cr_lock_shift = STM32WB_FLASH_CR_LOCK;
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
cr_reg = FLASH_H7_CR1;
cr_lock_shift = FLASH_H7_CR_LOCK;
cr_mask = ~(1u << FLASH_H7_CR_SER);
} else {
ELOG("unsupported flash method, abort\n");
return;
}

stlink_read_debug32(sl, cr_reg, &n);
n &= cr_mask;
n |= (1u << cr_lock_shift);
stlink_write_debug32(sl, cr_reg, n);

Expand Down Expand Up @@ -724,6 +753,9 @@ static void set_flash_cr_pg(stlink_t *sl) {
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
cr_reg = STM32WB_FLASH_CR;
x |= (1 << FLASH_CR_PG);
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
cr_reg = FLASH_H7_CR1;
x |= (1 << FLASH_H7_CR_PG);
} else {
cr_reg = FLASH_CR;
x = (1 << FLASH_CR_PG);
Expand Down Expand Up @@ -902,6 +934,9 @@ static void set_flash_cr_strt(stlink_t *sl) {
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
cr_reg = STM32WB_FLASH_CR;
cr_strt = (1 << STM32WB_FLASH_CR_STRT);
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
cr_reg = FLASH_H7_CR1;
cr_strt = 1 << FLASH_H7_CR_START;
} else {
cr_reg = FLASH_CR;
cr_strt = (1 << FLASH_CR_STRT);
Expand Down Expand Up @@ -939,6 +974,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) {
sr_reg = STM32Gx_FLASH_SR;
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
sr_reg = STM32WB_FLASH_SR;
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
sr_reg = FLASH_H7_SR1;
} else {
ELOG("unsupported flash method, abort");
return(-1);
Expand Down Expand Up @@ -973,6 +1010,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) {
sr_busy_shift = STM32Gx_FLASH_SR_BSY;
} else if (sl->flash_type == STLINK_FLASH_TYPE_WB) {
sr_busy_shift = STM32WB_FLASH_SR_BSY;
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
sr_busy_shift = FLASH_H7_SR_QW;
} else {
ELOG("unsupported flash method, abort");
return(-1);
Expand Down Expand Up @@ -1064,25 +1103,48 @@ static inline void write_flash_ar2(stlink_t *sl, uint32_t n) {
}

static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) {
uint32_t cr_reg, psize_shift;
uint32_t x = read_flash_cr(sl);
x &= ~(0x03 << 8);
x |= (n << 8);

if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
cr_reg = FLASH_H7_CR1;
psize_shift = FLASH_H7_CR_PSIZE;
} else {
cr_reg = FLASH_F4_CR;
psize_shift = 8;
}

x &= ~(0x03 << psize_shift);
x |= (n << psize_shift);
#if DEBUG_FLASH
fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n);
#endif
stlink_write_debug32(sl, FLASH_F4_CR, x);
stlink_write_debug32(sl, cr_reg, x);
}


static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) {
uint32_t cr_reg, snb_mask, snb_shift, ser_shift;
uint32_t x = read_flash_cr(sl);
x &= ~FLASH_F4_CR_SNB_MASK;
x |= (n << FLASH_F4_CR_SNB);
x |= (1 << FLASH_F4_CR_SER);

if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
cr_reg = FLASH_H7_CR1;
snb_mask = FLASH_H7_CR_SNB_MASK;
snb_shift = FLASH_H7_CR_SNB;
ser_shift = FLASH_H7_CR_SER;
} else {
cr_reg = FLASH_F4_CR;
snb_mask = FLASH_F4_CR_SNB_MASK;
snb_shift = FLASH_F4_CR_SNB;
ser_shift = FLASH_F4_CR_SER;
}

x &= ~snb_mask;
x |= (n << snb_shift);
x |= (1 << ser_shift);
#if DEBUG_FLASH
fprintf(stdout, "SNB:0x%x 0x%x\n", x, n);
#endif
stlink_write_debug32(sl, FLASH_F4_CR, x);
stlink_write_debug32(sl, cr_reg, x);
}

static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) {
Expand Down Expand Up @@ -1172,6 +1234,11 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) {
return(ret);
}

if (*chip_id == 0) {
// STM32H7 chipid in 0x5c001000 (RM0433 pg3189)
ret = stlink_read_debug32(sl, 0x5c001000, chip_id);
}

if (*chip_id == 0) {
// Try Corex M0 DBGMCU_IDCODE register address
ret = stlink_read_debug32(sl, 0x40015800, chip_id);
Expand Down Expand Up @@ -2136,6 +2203,11 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) {

}

uint32_t calculate_H7_sectornum(uint32_t flashaddr) {
flashaddr &= ~STM32_FLASH_BASE; // sector holding the flash address
return(flashaddr / 0x20000);
}

// returns BKER:PNB for the given page address
uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) {
uint32_t bker = 0;
Expand Down Expand Up @@ -2209,7 +2281,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) {
int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) {
if (sl->flash_type == STLINK_FLASH_TYPE_F4 ||
sl->flash_type == STLINK_FLASH_TYPE_F7 ||
sl->flash_type == STLINK_FLASH_TYPE_L4) {
sl->flash_type == STLINK_FLASH_TYPE_L4 ||
sl->flash_type == STLINK_FLASH_TYPE_H7) {
// wait for ongoing op to finish
wait_flash_busy(sl);

Expand All @@ -2234,6 +2307,13 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) {
// calculate the actual page from the address
uint32_t sector = calculate_F7_sectornum(flashaddr);

fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ",
sector, stlink_calculate_pagesize(sl, flashaddr));
write_flash_cr_snb(sl, sector);
} else if (sl->chip_id == STLINK_CHIPID_STM32_H74XXX) {
// calculate the actual page from the address
uint32_t sector = calculate_H7_sectornum(flashaddr);

fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ",
sector, stlink_calculate_pagesize(sl, flashaddr));
write_flash_cr_snb(sl, sector);
Expand Down Expand Up @@ -2849,6 +2929,31 @@ int stlink_write_flash(
}

fprintf(stdout, "\n");
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
ILOG("Starting Flash write for H7 core id\n");

unlock_flash_if(sl); // unlock the cr
set_flash_cr_pg(sl); // set programming mode

for (off = 0; off < len;) {
// Program STM32H7x with 32-byte Flash words
size_t chunk = (len - off > 32) ? 32 : len - off;
memcpy(sl->q_buf, base + off, chunk);
stlink_write_mem32(sl, addr + (uint32_t)off, 32);
wait_flash_busy(sl);

off += chunk;

if (sl->verbose >= 1) {
// show progress
fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, (unsigned int)len);
fflush(stdout);
}
}
fprintf(stdout, "\n");

clear_flash_cr_pg(sl);
lock_flash(sl);
} else {
ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id);
return(-1);
Expand Down
4 changes: 3 additions & 1 deletion src/st-flash/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ int main(int ac, char** av) {

printf("st-flash %s\n", STLINK_VERSION);

sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq);
sl = stlink_open_usb(o.log_level,
o.connect_under_reset ? 2 : 1,
(char *)o.serial, o.freq);

if (sl == NULL) { return(-1); }

Expand Down
11 changes: 11 additions & 0 deletions src/stlink-lib/chipid.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,17 @@ static const struct stlink_chipid_params devices[] = {
.bootrom_base = 0x1fff0000, // see the memory map
.bootrom_size = 0x7000
},
{
// STM32H742/743/753 (from RM0433)
.chip_id = STLINK_CHIPID_STM32_H74XXX,
.description = "H742/743/753",
.flash_type = STLINK_FLASH_TYPE_H7,
.flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272)
.flash_pagesize = 0x20000, // 128k sector (pg147)
.sram_size = 0x20000, // 128k "DTCM" from Table 7
.bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7
.bootrom_size = 0x20000 // "System memory" byte size in hex from Table 7
},
{
// unknown
.chip_id = STLINK_CHIPID_UNKNOWN,
Expand Down
1 change: 1 addition & 0 deletions src/stlink-lib/chipid.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ enum stlink_stm32_chipids {
STLINK_CHIPID_STM32_L0_CAT5 = 0x447,
STLINK_CHIPID_STM32_F0_CAN = 0x448,
STLINK_CHIPID_STM32_F7 = 0x449, /* ID found on the NucleoF746ZG board */
STLINK_CHIPID_STM32_H74XXX = 0x450, /* Found on page 3189 in the RM0433*/
STLINK_CHIPID_STM32_F7XXXX = 0x451,
STLINK_CHIPID_STM32_F72XXX = 0x452, /* ID found on the NucleoF722ZE board */
STLINK_CHIPID_STM32_L011 = 0x457,
Expand Down