stm32f4: Use buffered direct flash write with choosen size.
This commit is contained in:
parent
54f73858f9
commit
bfeb6f0db9
|
@ -11,12 +11,10 @@ endif
|
||||||
CFLAGS=-Os -std=gnu99 -mcpu=cortex-m0 -mthumb -I../../../libopencm3/include
|
CFLAGS=-Os -std=gnu99 -mcpu=cortex-m0 -mthumb -I../../../libopencm3/include
|
||||||
ASFLAGS=-mcpu=cortex-m3 -mthumb
|
ASFLAGS=-mcpu=cortex-m3 -mthumb
|
||||||
|
|
||||||
all: lmi.stub stm32f4_x8.stub stm32f4_x32.stub stm32l4.stub nrf51.stub \
|
all: lmi.stub stm32l4.stub nrf51.stub \
|
||||||
stm32f1.stub efm32.stub
|
stm32f1.stub efm32.stub
|
||||||
|
|
||||||
stm32f1.o: CFLAGS += -DSTM32F1
|
stm32f1.o: CFLAGS += -DSTM32F1
|
||||||
stm32f4_x8.o: CFLAGS += -DSTM32F4
|
|
||||||
stm32f4_x32.o: CFLAGS += -DSTM32F4
|
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(Q)echo " CC $<"
|
$(Q)echo " CC $<"
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the Black Magic Debug project.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2015 Black Sphere Technologies Ltd.
|
|
||||||
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "libopencm3/stm32/flash.h"
|
|
||||||
#include "stub.h"
|
|
||||||
|
|
||||||
#define SR_ERROR_MASK 0xF2
|
|
||||||
|
|
||||||
void __attribute__((naked))
|
|
||||||
stm32f4_flash_write_x32_stub(uint32_t *dest, uint32_t *src, uint32_t size)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < size; i += 4) {
|
|
||||||
FLASH_CR = FLASH_CR_PROGRAM_X32 | FLASH_CR_PG;
|
|
||||||
*dest++ = *src++;
|
|
||||||
__asm("dsb");
|
|
||||||
while (FLASH_SR & FLASH_SR_BSY)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FLASH_SR & SR_ERROR_MASK)
|
|
||||||
stub_exit(1);
|
|
||||||
|
|
||||||
stub_exit(0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
0x2300, 0x4C0A, 0x4293, 0xD20B, 0x4E09, 0x4D0A, 0x602E, 0x58CD, 0x50C5, 0xF3BF, 0x8F4F, 0x6825, 0x03ED, 0xD4FC, 0x3304, 0xE7F0, 0x23F2, 0x6822, 0x421A, 0xD000, 0xBE01, 0xBE00, 0x3C0C, 0x4002, 0x0201, 0x0000, 0x3C10, 0x4002,
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the Black Magic Debug project.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 Black Sphere Technologies Ltd.
|
|
||||||
* Written by Gordon Smith <gordonhj.smith@gmail.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "libopencm3/stm32/flash.h"
|
|
||||||
#include "stub.h"
|
|
||||||
|
|
||||||
#define SR_ERROR_MASK 0xF2
|
|
||||||
|
|
||||||
void __attribute__((naked))
|
|
||||||
stm32f4_flash_write_x8_stub(uint32_t *dest, uint32_t *src, uint32_t size)
|
|
||||||
{
|
|
||||||
uint8_t *b_dest, *b_src;
|
|
||||||
b_dest = (void *)dest;
|
|
||||||
b_src = (void *)src;
|
|
||||||
for (int i = 0; i < size; i += 1) {
|
|
||||||
FLASH_CR = FLASH_CR_PROGRAM_X8 | FLASH_CR_PG;
|
|
||||||
*b_dest++ = *b_src++;
|
|
||||||
__asm("dsb");
|
|
||||||
while (FLASH_SR & FLASH_SR_BSY)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FLASH_SR & SR_ERROR_MASK)
|
|
||||||
stub_exit(1);
|
|
||||||
|
|
||||||
stub_exit(0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
0x2300, 0x4C0A, 0x4293, 0xD00B, 0x2601, 0x4D09, 0x602E, 0x5CCD, 0x54C5, 0xF3BF, 0x8F4F, 0x6825, 0x03ED, 0xD4FC, 0x3301, 0xE7F0, 0x23F2, 0x6822, 0x421A, 0xD000, 0xBE01, 0xBE00, 0x3C0C, 0x4002, 0x3C10, 0x4002,
|
|
|
@ -3,6 +3,8 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Black Sphere Technologies Ltd.
|
* Copyright (C) 2011 Black Sphere Technologies Ltd.
|
||||||
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
|
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
|
||||||
|
* Copyright (C) 2017, 2018 Uwe Bonnes
|
||||||
|
* <bon@elektron.ikp.physik.tu-darmstadt.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -44,7 +46,7 @@ const struct command_s stm32f4_cmd_list[] = {
|
||||||
"Erase entire flash memory"},
|
"Erase entire flash memory"},
|
||||||
{"option", (cmd_handler)stm32f4_cmd_option, "Manipulate option bytes"},
|
{"option", (cmd_handler)stm32f4_cmd_option, "Manipulate option bytes"},
|
||||||
{"psize", (cmd_handler)stm32f4_cmd_psize,
|
{"psize", (cmd_handler)stm32f4_cmd_psize,
|
||||||
"Configure flash write parallelism: (x8|x32(default))"},
|
"Configure flash write parallelism: (x8|x16|x32(default))"},
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,28 +110,13 @@ static int stm32f4_flash_write(struct target_flash *f,
|
||||||
#define DBG_WWDG_STOP (1 << 11)
|
#define DBG_WWDG_STOP (1 << 11)
|
||||||
#define DBG_IWDG_STOP (1 << 12)
|
#define DBG_IWDG_STOP (1 << 12)
|
||||||
|
|
||||||
/* This routine uses word access. Only usable on target voltage >2.7V */
|
|
||||||
static const uint16_t stm32f4_flash_write_x32_stub[] = {
|
|
||||||
#include "flashstub/stm32f4_x32.stub"
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This routine uses byte access. Usable on target voltage <2.2V */
|
|
||||||
static const uint16_t stm32f4_flash_write_x8_stub[] = {
|
|
||||||
#include "flashstub/stm32f4_x8.stub"
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SRAM_BASE 0x20000000
|
|
||||||
#define STUB_BUFFER_BASE \
|
|
||||||
ALIGN(SRAM_BASE + MAX(sizeof(stm32f4_flash_write_x8_stub), \
|
|
||||||
sizeof(stm32f4_flash_write_x32_stub)), 4)
|
|
||||||
|
|
||||||
#define AXIM_BASE 0x8000000
|
#define AXIM_BASE 0x8000000
|
||||||
#define ITCM_BASE 0x0200000
|
#define ITCM_BASE 0x0200000
|
||||||
|
|
||||||
struct stm32f4_flash {
|
struct stm32f4_flash {
|
||||||
struct target_flash f;
|
struct target_flash f;
|
||||||
|
enum align psize;
|
||||||
uint8_t base_sector;
|
uint8_t base_sector;
|
||||||
uint8_t psize;
|
|
||||||
uint8_t bank_split;
|
uint8_t bank_split;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,10 +148,11 @@ static void stm32f4_add_flash(target *t,
|
||||||
f->blocksize = blocksize;
|
f->blocksize = blocksize;
|
||||||
f->erase = stm32f4_flash_erase;
|
f->erase = stm32f4_flash_erase;
|
||||||
f->write = stm32f4_flash_write;
|
f->write = stm32f4_flash_write;
|
||||||
|
f->buf_size = 1024;
|
||||||
f->erased = 0xff;
|
f->erased = 0xff;
|
||||||
sf->base_sector = base_sector;
|
sf->base_sector = base_sector;
|
||||||
sf->psize = 32;
|
|
||||||
sf->bank_split = split;
|
sf->bank_split = split;
|
||||||
|
sf->psize = ALIGN_WORD;
|
||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,17 +405,27 @@ static int stm32f4_flash_write(struct target_flash *f,
|
||||||
if ((dest >= ITCM_BASE) && (dest < AXIM_BASE)) {
|
if ((dest >= ITCM_BASE) && (dest < AXIM_BASE)) {
|
||||||
dest = AXIM_BASE + (dest - ITCM_BASE);
|
dest = AXIM_BASE + (dest - ITCM_BASE);
|
||||||
}
|
}
|
||||||
|
target *t = f->t;
|
||||||
|
uint32_t sr;
|
||||||
|
enum align psize = ((struct stm32f4_flash *)f)->psize;
|
||||||
|
target_mem_write32(t, FLASH_CR,
|
||||||
|
(psize * FLASH_CR_PSIZE16) | FLASH_CR_PG);
|
||||||
|
cortexm_mem_write_sized(t, dest, src, len, psize);
|
||||||
|
/* Read FLASH_SR to poll for BSY bit */
|
||||||
|
/* Wait for completion or an error */
|
||||||
|
do {
|
||||||
|
sr = target_mem_read32(t, FLASH_SR);
|
||||||
|
if(target_check_error(t)) {
|
||||||
|
DEBUG("stm32f4 flash write: comm error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (sr & FLASH_SR_BSY);
|
||||||
|
|
||||||
/* Write buffer to target ram call stub */
|
if (sr & SR_ERROR_MASK) {
|
||||||
if (((struct stm32f4_flash *)f)->psize == 32)
|
DEBUG("stm32f4 flash write error 0x%" PRIx32 "\n", sr);
|
||||||
target_mem_write(f->t, SRAM_BASE, stm32f4_flash_write_x32_stub,
|
return -1;
|
||||||
sizeof(stm32f4_flash_write_x32_stub));
|
}
|
||||||
else
|
return 0;
|
||||||
target_mem_write(f->t, SRAM_BASE, stm32f4_flash_write_x8_stub,
|
|
||||||
sizeof(stm32f4_flash_write_x8_stub));
|
|
||||||
target_mem_write(f->t, STUB_BUFFER_BASE, src, len);
|
|
||||||
return cortexm_run_stub(f->t, SRAM_BASE, dest,
|
|
||||||
STUB_BUFFER_BASE, len, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool stm32f4_cmd_erase_mass(target *t)
|
static bool stm32f4_cmd_erase_mass(target *t)
|
||||||
|
@ -665,22 +663,25 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
|
||||||
static bool stm32f4_cmd_psize(target *t, int argc, char *argv[])
|
static bool stm32f4_cmd_psize(target *t, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
uint8_t psize = 8;
|
enum align psize = ALIGN_WORD;
|
||||||
for (struct target_flash *f = t->flash; f; f = f->next) {
|
for (struct target_flash *f = t->flash; f; f = f->next) {
|
||||||
if (f->write == stm32f4_flash_write) {
|
if (f->write == stm32f4_flash_write) {
|
||||||
psize = ((struct stm32f4_flash *)f)->psize;
|
psize = ((struct stm32f4_flash *)f)->psize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tc_printf(t, "Flash write parallelism: %s\n",
|
tc_printf(t, "Flash write parallelism: %s\n",
|
||||||
psize == 32 ? "x32" : "x8");
|
psize == ALIGN_WORD ? "x32" :
|
||||||
|
psize == ALIGN_HALFWORD ? "x16" : "x8");
|
||||||
} else {
|
} else {
|
||||||
uint8_t psize;
|
enum align psize;
|
||||||
if (!strcmp(argv[1], "x8")) {
|
if (!strcmp(argv[1], "x8")) {
|
||||||
psize = 8;
|
psize = ALIGN_BYTE;
|
||||||
|
} else if (!strcmp(argv[1], "x16")) {
|
||||||
|
psize = ALIGN_HALFWORD;
|
||||||
} else if (!strcmp(argv[1], "x32")) {
|
} else if (!strcmp(argv[1], "x32")) {
|
||||||
psize = 32;
|
psize = ALIGN_WORD;
|
||||||
} else {
|
} else {
|
||||||
tc_printf(t, "usage: monitor psize (x8|x32)\n");
|
tc_printf(t, "usage: monitor psize (x8|x16|x32)\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (struct target_flash *f = t->flash; f; f = f->next) {
|
for (struct target_flash *f = t->flash; f; f = f->next) {
|
||||||
|
|
Loading…
Reference in New Issue