add read, write option byte for g4 and g0

use g0 code, same logic with different base address.
also cleanup some duplicate lock/unlock code.
pull/927/head
Guillaume Revaillot 2020-04-06 14:01:35 +02:00
rodzic ee4a52288a
commit 8430a6e6fa
4 zmienionych plików z 41 dodań i 27 usunięć

Wyświetl plik

@ -236,6 +236,7 @@ typedef struct flash_loader {
int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size);
int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size);
int stlink_load_device_params(stlink_t *sl); int stlink_load_device_params(stlink_t *sl);
int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte);
int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte);
int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte); int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte);

Wyświetl plik

@ -15,6 +15,7 @@
#define STM32_FLASH_BASE ((uint32_t)0x08000000) #define STM32_FLASH_BASE ((uint32_t)0x08000000)
#define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_SRAM_BASE ((uint32_t)0x20000000)
#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800)
#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800)
#define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000)
#define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000)
#define STM32_L496X_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L496X_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800)

Wyświetl plik

@ -2736,7 +2736,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) {
* @param base option bytes to write * @param base option bytes to write
* @return 0 on success, -ve on failure. * @return 0 on success, -ve on failure.
*/ */
static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t len) { static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, uint32_t len) {
uint32_t val; uint32_t val;
@ -2750,25 +2750,16 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l
/* Check if chip is supported and for correct address */ /* Check if chip is supported and for correct address */
if (sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 && if (sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 &&
sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2) { sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2 &&
ELOG("Option bytes writing is currently only supported for the STM32G0\n"); sl->chip_id != STLINK_CHIPID_STM32_G4_CAT2 &&
sl->chip_id != STLINK_CHIPID_STM32_G4_CAT3) {
ELOG("Option bytes writing is currently only supported for the STM32G0/G4\n");
return -1; return -1;
} }
/* Unlock flash if necessary (ref manuel page 52) */ if (unlock_flash_if(sl)) {
stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n");
if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { return -1;
/* disable flash write protection. */
stlink_write_debug32(sl, STM32Gx_FLASH_KEYR, 0x45670123);
stlink_write_debug32(sl, STM32Gx_FLASH_KEYR, 0xCDEF89AB);
// check that the lock is no longer set.
stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val);
if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) {
ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n");
return -1;
}
} }
/* Unlock option bytes if necessary (ref manuel page 61) */ /* Unlock option bytes if necessary (ref manuel page 61) */
@ -2802,7 +2793,9 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l
/* Wait for 'busy' bit in FLASH_SR to clear. */ /* Wait for 'busy' bit in FLASH_SR to clear. */
do { do {
stlink_read_debug32(sl, STM32Gx_FLASH_SR, &val); stlink_read_debug32(sl, STM32Gx_FLASH_SR, &val);
} while ((val & (1 << 16)) != 0); } while ((val & (1 << STM32Gx_FLASH_SR_BSY)) != 0);
check_flash_error(sl);
/* apply options bytes immediate */ /* apply options bytes immediate */
stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val);
@ -2813,10 +2806,9 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l
stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val);
val |= (1u << STM32Gx_FLASH_CR_OPTLOCK); val |= (1u << STM32Gx_FLASH_CR_OPTLOCK);
stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val);
/* Re-lock flash. */ /* Re-lock flash. */
stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); lock_flash(sl);
val |= (1u << STM32Gx_FLASH_CR_LOCK);
stlink_write_debug32(sl, STM32Gx_FLASH_CR, val);
return 0; return 0;
} }
@ -3147,6 +3139,19 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) {
return 0; return 0;
} }
/**
* Read option bytes
* @param sl
* @param option_byte value to write
* @return 0 on success, -ve on failure.
*/
int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte)
{
uint32_t ret = stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte);
WLOG("option bytes CR = %#010x\n", *option_byte);
return ret;
}
/** /**
* Read option bytes * Read option bytes
* @param sl * @param sl
@ -3183,7 +3188,7 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) {
/** /**
* Read option bytes * Read option bytes
* @param sl * @param sl
* @param option_byte value to write * @param option_byte value to read
* @return 0 on success, -ve on failure. * @return 0 on success, -ve on failure.
*/ */
int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) {
@ -3230,9 +3235,13 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui
/* Check if chip is supported and for correct address */ /* Check if chip is supported and for correct address */
if (((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) || if (((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) ||
(sl->chip_id == STLINK_CHIPID_STM32_G0_CAT2)) && (addr == STM32_G0_OPTION_BYTES_BASE)) { (sl->chip_id == STLINK_CHIPID_STM32_G0_CAT2)) && (addr == STM32_G0_OPTION_BYTES_BASE)) {
return stlink_write_option_bytes_g0x(sl, base, len); return stlink_write_option_bytes_gx(sl, base, len);
} }
else if ((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { else if (((sl->chip_id == STLINK_CHIPID_STM32_G4_CAT2) ||
(sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3)) && (addr == STM32_G4_OPTION_BYTES_BASE)) {
return stlink_write_option_bytes_gx(sl, base, len);
}
else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) {
return stlink_write_option_bytes_l0_cat2(sl, base, len); return stlink_write_option_bytes_l0_cat2(sl, base, len);
} }
else if ((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { else if ((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) {

Wyświetl plik

@ -208,16 +208,19 @@ int main(int ac, char** av)
else /* read */ else /* read */
{ {
if (o.area == FLASH_OPTION_BYTES){ if (o.area == FLASH_OPTION_BYTES){
uint32_t option_byte = 0;
if (sl->chip_id == STLINK_CHIPID_STM32_F2){ if (sl->chip_id == STLINK_CHIPID_STM32_F2){
uint32_t option_byte = 0;
err = stlink_read_option_bytes_f2(sl,&option_byte); err = stlink_read_option_bytes_f2(sl,&option_byte);
printf("%x\n",option_byte); printf("%x\n",option_byte);
} else if (sl->chip_id == STLINK_CHIPID_STM32_F446){ } else if (sl->chip_id == STLINK_CHIPID_STM32_F446){
uint32_t option_byte = 0;
err = stlink_read_option_bytes_f4(sl,&option_byte); err = stlink_read_option_bytes_f4(sl,&option_byte);
printf("%x\n",option_byte); printf("%x\n",option_byte);
}else if(sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) {
err = stlink_read_option_bytes_Gx(sl,&option_byte);
printf("%x\n",option_byte);
} else { } else {
printf("This format is available for STM32F2 and STM32F4 only\n"); printf("This format is only available for STM32F2, STM32F4, STM32G0 and STM32G4\n");
}
if (err == -1) if (err == -1)
{ {
printf("could not read option bytes\n"); printf("could not read option bytes\n");