kopia lustrzana https://github.com/stlink-org/stlink
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
rodzic
ee4a52288a
commit
8430a6e6fa
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
57
src/common.c
57
src/common.c
|
@ -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)) {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Ładowanie…
Reference in New Issue