stm32f1: use new flash interface.

This commit is contained in:
Gareth McMullin 2015-04-03 23:01:11 -07:00
parent 7cd3432994
commit 622497f7e2
1 changed files with 40 additions and 99 deletions

View File

@ -46,43 +46,10 @@ const struct command_s stm32f1_cmd_list[] = {
}; };
static int stm32md_flash_erase(target *t, uint32_t addr, size_t len); static int stm32f1_flash_erase(struct target_flash *f,
static int stm32hd_flash_erase(target *t, uint32_t addr, size_t len); uint32_t addr, size_t len);
static int stm32f1_flash_erase(target *t, uint32_t addr, size_t len, static int stm32f1_flash_write(struct target_flash *f,
uint32_t pagesize); uint32_t dest, const void *src, size_t len);
static int stm32f1_flash_write(target *t, uint32_t dest,
const uint8_t *src, size_t len);
static const char stm32f1_driver_str[] = "STM32, Medium density.";
static const char stm32hd_driver_str[] = "STM32, High density.";
static const char stm32f3_driver_str[] = "STM32F3xx";
static const char stm32f03_driver_str[] = "STM32F03x";
static const char stm32f04_driver_str[] = "STM32F04x";
static const char stm32f05_driver_str[] = "STM32F05x";
static const char stm32f07_driver_str[] = "STM32F07x";
static const char stm32f09_driver_str[] = "STM32F09x";
static const char stm32f1_xml_memory_map[] = "<?xml version=\"1.0\"?>"
/* "<!DOCTYPE memory-map "
" PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"*/
"<memory-map>"
" <memory type=\"flash\" start=\"0x8000000\" length=\"0x20000\">"
" <property name=\"blocksize\">0x400</property>"
" </memory>"
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x5000\"/>"
"</memory-map>";
static const char stm32hd_xml_memory_map[] = "<?xml version=\"1.0\"?>"
/* "<!DOCTYPE memory-map "
" PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"*/
"<memory-map>"
" <memory type=\"flash\" start=\"0x8000000\" length=\"0x80000\">"
" <property name=\"blocksize\">0x800</property>"
" </memory>"
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x10000\"/>"
"</memory-map>";
/* Flash Program ad Erase Controller Register Map */ /* Flash Program ad Erase Controller Register Map */
#define FPEC_BASE 0x40022000 #define FPEC_BASE 0x40022000
@ -127,6 +94,20 @@ static const uint16_t stm32f1_flash_write_stub[] = {
#define SRAM_BASE 0x20000000 #define SRAM_BASE 0x20000000
#define STUB_BUFFER_BASE ALIGN(SRAM_BASE + sizeof(stm32f1_flash_write_stub), 4) #define STUB_BUFFER_BASE ALIGN(SRAM_BASE + sizeof(stm32f1_flash_write_stub), 4)
static void stm32f1_add_flash(target *t,
uint32_t addr, size_t length, size_t erasesize)
{
struct target_flash *f = calloc(1, sizeof(*f));
f->start = addr;
f->length = length;
f->blocksize = erasesize;
f->erase = stm32f1_flash_erase;
f->write = stm32f1_flash_write;
f->align = 2;
f->erased = 0xff;
target_add_flash(t, f);
}
bool stm32f1_probe(target *t) bool stm32f1_probe(target *t)
{ {
t->idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xfff; t->idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xfff;
@ -134,27 +115,24 @@ bool stm32f1_probe(target *t)
case 0x410: /* Medium density */ case 0x410: /* Medium density */
case 0x412: /* Low denisty */ case 0x412: /* Low denisty */
case 0x420: /* Value Line, Low-/Medium density */ case 0x420: /* Value Line, Low-/Medium density */
t->driver = stm32f1_driver_str; t->driver = "STM32F1 medium density";
t->xml_mem_map = stm32f1_xml_memory_map; target_add_ram(t, 0x20000000, 0x5000);
t->flash_erase = stm32md_flash_erase; stm32f1_add_flash(t, 0x8000000, 0x20000, 0x400);
t->flash_write = stm32f1_flash_write;
target_add_commands(t, stm32f1_cmd_list, "STM32 LD/MD"); target_add_commands(t, stm32f1_cmd_list, "STM32 LD/MD");
return true; return true;
case 0x414: /* High density */ case 0x414: /* High density */
case 0x418: /* Connectivity Line */ case 0x418: /* Connectivity Line */
case 0x428: /* Value Line, High Density */ case 0x428: /* Value Line, High Density */
t->driver = stm32hd_driver_str; t->driver = "STM32F1 high density";
t->xml_mem_map = stm32hd_xml_memory_map; target_add_ram(t, 0x20000000, 0x10000);
t->flash_erase = stm32hd_flash_erase; stm32f1_add_flash(t, 0x8000000, 0x80000, 0x800);
t->flash_write = stm32f1_flash_write;
target_add_commands(t, stm32f1_cmd_list, "STM32 HD/CL"); target_add_commands(t, stm32f1_cmd_list, "STM32 HD/CL");
return true; return true;
case 0x422: /* STM32F30x */ case 0x422: /* STM32F30x */
case 0x432: /* STM32F37x */ case 0x432: /* STM32F37x */
t->driver = stm32f3_driver_str; t->driver = "STM32F3";
t->xml_mem_map = stm32hd_xml_memory_map; target_add_ram(t, 0x20000000, 0x10000);
t->flash_erase = stm32hd_flash_erase; stm32f1_add_flash(t, 0x8000000, 0x80000, 0x800);
t->flash_write = stm32f1_flash_write;
target_add_commands(t, stm32f1_cmd_list, "STM32F3"); target_add_commands(t, stm32f1_cmd_list, "STM32F3");
return true; return true;
} }
@ -166,26 +144,9 @@ bool stm32f1_probe(target *t)
case 0x440: /* STM32F05 RM0091 Rev.7 */ case 0x440: /* STM32F05 RM0091 Rev.7 */
case 0x448: /* STM32F07 RM0091 Rev.7 */ case 0x448: /* STM32F07 RM0091 Rev.7 */
case 0x442: /* STM32F09 RM0091 Rev.7 */ case 0x442: /* STM32F09 RM0091 Rev.7 */
switch(t->idcode) { t->driver = "STM32F0";
case 0x444: /* STM32F03 */ target_add_ram(t, 0x20000000, 0x5000);
t->driver = stm32f03_driver_str; stm32f1_add_flash(t, 0x8000000, 0x20000, 0x400);
break;
case 0x445: /* STM32F04 */
t->driver = stm32f04_driver_str;
break;
case 0x440: /* STM32F05 */
t->driver = stm32f05_driver_str;
break;
case 0x448: /* STM32F07 */
t->driver = stm32f07_driver_str;
break;
case 0x442: /* STM32F09 */
t->driver = stm32f09_driver_str;
break;
}
t->xml_mem_map = stm32f1_xml_memory_map;
t->flash_erase = stm32md_flash_erase;
t->flash_write = stm32f1_flash_write;
target_add_commands(t, stm32f1_cmd_list, "STM32F0"); target_add_commands(t, stm32f1_cmd_list, "STM32F0");
return true; return true;
} }
@ -199,14 +160,12 @@ static void stm32f1_flash_unlock(target *t)
target_mem_write32(t, FLASH_KEYR, KEY2); target_mem_write32(t, FLASH_KEYR, KEY2);
} }
static int stm32f1_flash_erase(target *t, uint32_t addr, static int stm32f1_flash_erase(struct target_flash *f,
size_t len, uint32_t pagesize) uint32_t addr, size_t len)
{ {
target *t = f->t;
uint16_t sr; uint16_t sr;
addr &= ~(pagesize - 1);
len = (len + pagesize - 1) & ~(pagesize - 1);
stm32f1_flash_unlock(t); stm32f1_flash_unlock(t);
while(len) { while(len) {
@ -222,8 +181,8 @@ static int stm32f1_flash_erase(target *t, uint32_t addr,
if(target_check_error(t)) if(target_check_error(t))
return -1; return -1;
len -= pagesize; len -= f->blocksize;
addr += pagesize; addr += f->blocksize;
} }
/* Check for error */ /* Check for error */
@ -234,33 +193,15 @@ static int stm32f1_flash_erase(target *t, uint32_t addr,
return 0; return 0;
} }
static int stm32hd_flash_erase(target *t, uint32_t addr, size_t len) static int stm32f1_flash_write(struct target_flash *f,
uint32_t dest, const void *src, size_t len)
{ {
return stm32f1_flash_erase(t, addr, len, 0x800); target *t = f->t;
}
static int stm32md_flash_erase(target *t, uint32_t addr, size_t len)
{
return stm32f1_flash_erase(t, addr, len, 0x400);
}
static int stm32f1_flash_write(target *t, uint32_t dest,
const uint8_t *src, size_t len)
{
uint32_t offset = dest % 4;
uint8_t data[ALIGN(offset + len, 4)];
/* Construct data buffer used by stub */
/* pad partial words with all 1s to avoid damaging overlapping areas */
memset(data, 0xff, sizeof(data));
memcpy((uint8_t *)data + offset, src, len);
/* Write stub and data to target ram and set PC */ /* Write stub and data to target ram and set PC */
target_mem_write(t, SRAM_BASE, stm32f1_flash_write_stub, target_mem_write(t, SRAM_BASE, stm32f1_flash_write_stub,
sizeof(stm32f1_flash_write_stub)); sizeof(stm32f1_flash_write_stub));
target_mem_write(t, STUB_BUFFER_BASE, data, sizeof(data)); target_mem_write(t, STUB_BUFFER_BASE, src, len);
return cortexm_run_stub(t, SRAM_BASE, dest - offset, return cortexm_run_stub(t, SRAM_BASE, dest, STUB_BUFFER_BASE, len, 0);
STUB_BUFFER_BASE, sizeof(data), 0);
} }
static bool stm32f1_cmd_erase_mass(target *t) static bool stm32f1_cmd_erase_mass(target *t)