Merge pull request #456 from newbrain/STM32L4memmap
Correction of #445 attach-detach problem
This commit is contained in:
commit
2b4000b2b4
|
@ -124,6 +124,108 @@ struct stm32l4_flash {
|
|||
uint32_t bank1_start;
|
||||
};
|
||||
|
||||
enum ID_STM32L4 {
|
||||
ID_STM32L41 = 0x464u, /* RM0394, Rev.4 */
|
||||
ID_STM32L43 = 0x435u, /* RM0394, Rev.4 */
|
||||
ID_STM32L45 = 0x462u, /* RM0394, Rev.4 */
|
||||
ID_STM32L47 = 0x415u, /* RM0351, Rev.5 */
|
||||
ID_STM32L49 = 0x461u, /* RM0351, Rev.5 */
|
||||
ID_STM32L4R = 0x470u, /* RM0432, Rev.5 */
|
||||
ID_STM32G07 = 0x460u, /* RM0444/454, Rev.1 */
|
||||
};
|
||||
|
||||
enum FAM_STM32L4 {
|
||||
FAM_STM32L4xx = 1,
|
||||
FAM_STM32L4Rx = 2,
|
||||
FAM_STM32G0x = 3,
|
||||
FAM_STM32WBxx = 4,
|
||||
};
|
||||
|
||||
#define DUAL_BANK 0x80u
|
||||
#define RAM_COUNT_MSK 0x07u
|
||||
|
||||
struct stm32l4_info {
|
||||
char designator[10];
|
||||
uint16_t sram1;
|
||||
uint16_t sram2;
|
||||
uint16_t sram3;
|
||||
enum ID_STM32L4 idcode;
|
||||
enum FAM_STM32L4 family;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct stm32l4_info const L4info[] = {
|
||||
{
|
||||
.idcode = ID_STM32L41,
|
||||
.family = FAM_STM32L4xx,
|
||||
.designator = "STM32L41x",
|
||||
.sram1 = 32,
|
||||
.sram2 = 8,
|
||||
.flags = 2,
|
||||
},
|
||||
{
|
||||
.idcode = ID_STM32L43,
|
||||
.family = FAM_STM32L4xx,
|
||||
.designator = "STM32L43x",
|
||||
.sram1 = 48,
|
||||
.sram2 = 16,
|
||||
.flags = 2,
|
||||
},
|
||||
{
|
||||
.idcode = ID_STM32L45,
|
||||
.family = FAM_STM32L4xx,
|
||||
.designator = "STM32L45x",
|
||||
.sram1 = 128,
|
||||
.sram2 = 32,
|
||||
.flags = 2,
|
||||
},
|
||||
{
|
||||
.idcode = ID_STM32L47,
|
||||
.family = FAM_STM32L4xx,
|
||||
.designator = "STM32L47x",
|
||||
.sram1 = 96,
|
||||
.sram2 = 32,
|
||||
.flags = 2 | DUAL_BANK,
|
||||
},
|
||||
{
|
||||
.idcode = ID_STM32L49,
|
||||
.family = FAM_STM32L4xx,
|
||||
.designator = "STM32L49x",
|
||||
.sram1 = 256,
|
||||
.sram2 = 64,
|
||||
.flags = 2 | DUAL_BANK,
|
||||
},
|
||||
{
|
||||
.idcode = ID_STM32L4R,
|
||||
.family = FAM_STM32L4Rx,
|
||||
.designator = "STM32L4Rx",
|
||||
.sram1 = 192,
|
||||
.sram2 = 64,
|
||||
.sram3 = 384,
|
||||
.flags = 3 | DUAL_BANK,
|
||||
},
|
||||
{
|
||||
.idcode = ID_STM32G07,
|
||||
.family = FAM_STM32G0x,
|
||||
.designator = "STM32G07",
|
||||
.sram1 = 36,
|
||||
.flags = 1,
|
||||
},
|
||||
{
|
||||
/* Terminator */
|
||||
.idcode = 0,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* Retrieve chip basic information, just add to the vector to extend */
|
||||
static struct stm32l4_info const * stm32l4_get_chip_info(uint32_t idcode) {
|
||||
struct stm32l4_info const *p = L4info;
|
||||
while (p->idcode && (p->idcode != idcode))
|
||||
p++;
|
||||
return p;
|
||||
}
|
||||
|
||||
static void stm32l4_add_flash(target *t,
|
||||
uint32_t addr, size_t length, size_t blocksize,
|
||||
uint32_t bank1_start)
|
||||
|
@ -141,61 +243,61 @@ static void stm32l4_add_flash(target *t,
|
|||
target_add_flash(t, f);
|
||||
}
|
||||
|
||||
enum ID_STM32L4 {
|
||||
ID_STM32L43 = 0x435, /* RM0394, Rev.4 */
|
||||
ID_STM32L45 = 0x462, /* RM0394, Rev.4 */
|
||||
ID_STM32L41 = 0x464, /* RM0394, Rev.4 */
|
||||
ID_STM32L47 = 0x415, /* RM0351, Rev.5 */
|
||||
ID_STM32G07 = 0x460, /* RM0444/454, Rev.1 */
|
||||
ID_STM32L49 = 0x461, /* RM0351, Rev.5 */
|
||||
ID_STM32L4R = 0x470, /* RM0432, Rev.5 */
|
||||
};
|
||||
|
||||
static bool stm32l4_attach(target *t)
|
||||
{
|
||||
if (!cortexm_attach(t))
|
||||
return false;
|
||||
|
||||
bool dual_bank = false;
|
||||
uint32_t idcodereg = STM32L4_DBGMCU_IDCODE_PHYS;
|
||||
uint32_t size = 0;
|
||||
/* Retrive chip information, no need to check return */
|
||||
struct stm32l4_info const *chip = stm32l4_get_chip_info(t->idcode);
|
||||
|
||||
|
||||
uint32_t idcodereg = (chip->family == FAM_STM32G0x)
|
||||
? STM32G0_DBGMCU_IDCODE_PHYS
|
||||
: STM32L4_DBGMCU_IDCODE_PHYS;
|
||||
|
||||
switch(t->idcode) {
|
||||
case ID_STM32L47:
|
||||
case ID_STM32L49:
|
||||
case ID_STM32L4R:
|
||||
dual_bank = true;
|
||||
break;
|
||||
case ID_STM32G07:
|
||||
idcodereg = STM32G0_DBGMCU_IDCODE_PHYS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Save DBGMCU_CR to restore it when detaching*/
|
||||
uint32_t dbgmcu_cr = target_mem_read32(t, DBGMCU_CR(idcodereg));
|
||||
t->target_storage = dbgmcu_cr;
|
||||
|
||||
/* Enable debugging during all low power modes*/
|
||||
target_mem_write32(t, DBGMCU_CR(idcodereg), DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_DBG_STOP);
|
||||
|
||||
size = (target_mem_read32(t, FLASH_SIZE_REG) & 0xffff);
|
||||
if (dual_bank) {
|
||||
uint32_t options = target_mem_read32(t, FLASH_OPTR);
|
||||
if (t->idcode == ID_STM32L4R) {
|
||||
/* rm0432 Rev. 2 does not mention 1 MB devices or explain DB1M.*/
|
||||
if (options & OR_DBANK) {
|
||||
stm32l4_add_flash(t, 0x08000000, 0x00100000, 0x1000, 0x08100000);
|
||||
stm32l4_add_flash(t, 0x08100000, 0x00100000, 0x1000, 0x08100000);
|
||||
} else
|
||||
stm32l4_add_flash(t, 0x08000000, 0x00200000, 0x2000, -1);
|
||||
|
||||
/* Free previously loaded memory map */
|
||||
target_mem_map_free(t);
|
||||
|
||||
/* Add RAM to memory map */
|
||||
if (chip->family == FAM_STM32G0x) {
|
||||
target_add_ram(t, 0x20000000, chip->sram1 << 10);
|
||||
} else {
|
||||
target_add_ram(t, 0x10000000, chip->sram2 << 10);
|
||||
/* All L4 beside L47 alias SRAM2 after SRAM1.*/
|
||||
uint32_t ramsize = (t->idcode == ID_STM32L47)?
|
||||
chip->sram1 : (chip->sram1 + chip->sram2 + chip->sram3);
|
||||
target_add_ram(t, 0x20000000, ramsize << 10);
|
||||
}
|
||||
|
||||
/* Add the flash to memory map. */
|
||||
uint32_t size = target_mem_read16(t, FLASH_SIZE_REG);
|
||||
uint32_t options = target_mem_read32(t, FLASH_OPTR);
|
||||
|
||||
if (chip->family == FAM_STM32L4Rx) {
|
||||
/* rm0432 Rev. 2 does not mention 1 MB devices or explain DB1M.*/
|
||||
if (options & OR_DBANK) {
|
||||
stm32l4_add_flash(t, 0x08000000, 0x00100000, 0x1000, 0x08100000);
|
||||
stm32l4_add_flash(t, 0x08100000, 0x00100000, 0x1000, 0x08100000);
|
||||
} else
|
||||
stm32l4_add_flash(t, 0x08000000, 0x00200000, 0x2000, -1);
|
||||
} else if (chip->flags & DUAL_BANK) {
|
||||
if (options & OR_DUALBANK) {
|
||||
uint32_t banksize = size << 9;
|
||||
stm32l4_add_flash(t, 0x08000000 , banksize, 0x0800, 0x08000000 + banksize);
|
||||
stm32l4_add_flash(t, 0x08000000 + banksize, banksize, 0x0800, 0x08000000 + banksize);
|
||||
} else {
|
||||
if (options & OR_DUALBANK) {
|
||||
uint32_t banksize = size << 9;
|
||||
stm32l4_add_flash(t, 0x08000000 , banksize, 0x0800, 0x08000000 + banksize);
|
||||
stm32l4_add_flash(t, 0x08000000 + banksize, banksize, 0x0800, 0x08000000 + banksize);
|
||||
} else {
|
||||
uint32_t banksize = size << 10;
|
||||
stm32l4_add_flash(t, 0x08000000 , banksize, 0x0800, -1);
|
||||
}
|
||||
uint32_t banksize = size << 10;
|
||||
stm32l4_add_flash(t, 0x08000000 , banksize, 0x0800, -1);
|
||||
}
|
||||
} else
|
||||
stm32l4_add_flash(t, 0x08000000, size << 10, 0x800, -1);
|
||||
|
@ -218,71 +320,22 @@ static void stm32l4_detach(target *t)
|
|||
|
||||
bool stm32l4_probe(target *t)
|
||||
{
|
||||
const char* designator = NULL;
|
||||
bool is_stm32g0 = false;
|
||||
uint16_t sram1_size = 0;
|
||||
uint16_t sram2_size = 0;
|
||||
uint16_t sram3_size = 0;
|
||||
|
||||
uint32_t idcode_reg = STM32L4_DBGMCU_IDCODE_PHYS;
|
||||
ADIv5_AP_t *ap = cortexm_ap(t);
|
||||
if (ap->dp->idcode == 0x0BC11477)
|
||||
idcode_reg = STM32G0_DBGMCU_IDCODE_PHYS;
|
||||
uint32_t idcode = target_mem_read32(t, idcode_reg) & 0xfff;
|
||||
switch(idcode) {
|
||||
case ID_STM32G07:
|
||||
designator = "STM32G07";
|
||||
is_stm32g0 = true;
|
||||
sram1_size = 36;
|
||||
break;
|
||||
case ID_STM32L41:
|
||||
designator = "STM32L41x";
|
||||
sram1_size = 32;
|
||||
sram2_size = 8;
|
||||
break;
|
||||
case ID_STM32L43:
|
||||
designator = "STM32L43x";
|
||||
sram1_size = 48;
|
||||
sram2_size = 16;
|
||||
break;
|
||||
case ID_STM32L45:
|
||||
designator = "STM32L45x";
|
||||
sram1_size = 128;
|
||||
sram2_size = 32;
|
||||
break;
|
||||
case ID_STM32L47:
|
||||
designator = "STM32L47x";
|
||||
sram1_size = 96;
|
||||
sram2_size = 32;
|
||||
break;
|
||||
case ID_STM32L49:
|
||||
designator = "STM32L49x";
|
||||
sram1_size = 256;
|
||||
sram2_size = 64;
|
||||
break;
|
||||
case ID_STM32L4R:
|
||||
designator = "STM32L4Rx";
|
||||
sram1_size = 192;
|
||||
sram2_size = 64;
|
||||
sram3_size = 384;
|
||||
break;
|
||||
default:
|
||||
|
||||
struct stm32l4_info const *chip = stm32l4_get_chip_info(idcode);
|
||||
|
||||
if( !chip->idcode ) /* Not found */
|
||||
return false;
|
||||
}
|
||||
|
||||
t->idcode = idcode;
|
||||
t->driver = designator;
|
||||
t->driver = chip->designator;
|
||||
t->attach = stm32l4_attach;
|
||||
t->detach = stm32l4_detach;
|
||||
if (is_stm32g0) {
|
||||
target_add_ram(t, 0x20000000, sram1_size << 10);
|
||||
} else {
|
||||
target_add_ram(t, 0x10000000, sram2_size << 10);
|
||||
/* All L4 beside L47 alias SRAM2 after SRAM1.*/
|
||||
uint32_t ramsize = (idcode == ID_STM32L47)?
|
||||
sram1_size : (sram1_size + sram2_size + sram3_size);
|
||||
target_add_ram(t, 0x20000000, ramsize << 10);
|
||||
}
|
||||
target_add_commands(t, stm32l4_cmd_list, designator);
|
||||
target_add_commands(t, stm32l4_cmd_list, chip->designator);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -413,7 +466,7 @@ static const uint8_t g0_i2offset[7] = {
|
|||
static bool stm32l4_option_write(
|
||||
target *t,const uint32_t *values, int len, const uint8_t *i2offset)
|
||||
{
|
||||
tc_printf(t, "Device will loose connection. Rescan!\n");
|
||||
tc_printf(t, "Device will lose connection. Rescan!\n");
|
||||
stm32l4_flash_unlock(t);
|
||||
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY1);
|
||||
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY2);
|
||||
|
@ -459,7 +512,7 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[])
|
|||
const uint8_t *i2offset = l4_i2offset;
|
||||
if (t->idcode == 0x435) {/* L43x */
|
||||
len = 5;
|
||||
} else if (t->idcode == 0x460) {/* G07x */
|
||||
} else if (t->idcode == ID_STM32G07) {/* G07x */
|
||||
i2offset = g0_i2offset;
|
||||
len = 7;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue