flash_loader: fix check BUSY flag, code simplified

pull/1113/head
anton 2021-03-18 19:28:40 +05:00
rodzic ebcf04f02b
commit 41bbbc2e96
12 zmienionych plików z 317 dodań i 301 usunięć

Wyświetl plik

@ -4,35 +4,60 @@
# This makefile will save your time from dealing with compile errors
# Adjust CC if needed
CC = /opt/local/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc
CROSS_COMPILE ?= /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-
CFLAGS_thumb1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib
CFLAGS_thumb2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib
CC = $(CROSS_COMPILE)gcc
OBJCOPY = $(CROSS_COMPILE)objcopy
all: stm32vl.o stm32f0.o stm32l.o stm32f4.o stm32f4_lv.o stm32l4.o stm32f7.o stm32f7_lv.o
XXD = xxd
XXDFLAGS = -i -c 4
stm32vl.o: stm32f0.s
$(CC) stm32f0.s $(CFLAGS_thumb2) -o stm32vl.o
stm32f0.o: stm32f0.s
$(CC) stm32f0.s $(CFLAGS_thumb1) -o stm32f0.o
stm32l.o: stm32lx.s
$(CC) stm32lx.s $(CFLAGS_thumb2) -o stm32l.o
stm32f4.o: stm32f4.s
$(CC) stm32f4.s $(CFLAGS_thumb2) -o stm32f4.o
stm32f4_lv.o: stm32f4lv.s
$(CC) stm32f4lv.s $(CFLAGS_thumb2) -o stm32f4_lv.o
stm32l4.o: stm32l4.s
$(CC) stm32l4.s $(CFLAGS_thumb2) -o stm32l4.o
stm32f7.o: stm32f7.s
$(CC) stm32f7.s $(CFLAGS_thumb2) -o stm32f7.o
stm32f7_lv.o: stm32f7lv.s
$(CC) stm32f7lv.s $(CFLAGS_thumb2) -o stm32f7_lv.o
CFLAGS_THUMB1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib
CFLAGS_THUMB2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib
all: stm32vl.h stm32f0.h stm32lx.h stm32f4.h stm32f4lv.h stm32l4.h stm32f7.h stm32f7lv.h
stm32f0.h: stm32f0.s
$(CC) stm32f0.s $(CFLAGS_THUMB1) -o stm32f0.o
$(OBJCOPY) -O binary stm32f0.o stm32f0.bin
$(XXD) $(XXDFLAGS) stm32f0.bin stm32f0.h
stm32vl.h: stm32f0.s
$(CC) stm32f0.s $(CFLAGS_THUMB2) -o stm32vl.o
$(OBJCOPY) -O binary stm32vl.o stm32vl.bin
$(XXD) $(XXDFLAGS) stm32vl.bin stm32vl.h
stm32lx.h: stm32lx.s
$(CC) stm32lx.s $(CFLAGS_THUMB2) -o stm32lx.o
$(OBJCOPY) -O binary stm32lx.o stm32lx.bin
$(XXD) $(XXDFLAGS) stm32lx.bin stm32lx.h
stm32f4.h: stm32f4.s
$(CC) stm32f4.s $(CFLAGS_THUMB2) -o stm32f4.o
$(OBJCOPY) -O binary stm32f4.o stm32f4.bin
$(XXD) $(XXDFLAGS) stm32f4.bin stm32f4.h
stm32f4lv.h: stm32f4lv.s
$(CC) stm32f4lv.s $(CFLAGS_THUMB2) -o stm32f4lv.o
$(OBJCOPY) -O binary stm32f4lv.o stm32f4lv.bin
$(XXD) $(XXDFLAGS) stm32f4lv.bin stm32f4lv.h
stm32l4.h: stm32l4.s
$(CC) stm32l4.s $(CFLAGS_THUMB2) -o stm32l4.o
$(OBJCOPY) -O binary stm32l4.o stm32l4.bin
$(XXD) $(XXDFLAGS) stm32l4.bin stm32l4.h
stm32f7.h: stm32f7.s
$(CC) stm32f7.s $(CFLAGS_THUMB2) -o stm32f7.o
$(OBJCOPY) -O binary stm32f7.o stm32f7.bin
$(XXD) $(XXDFLAGS) stm32f7.bin stm32f7.h
stm32f7lv.h: stm32f7lv.s
$(CC) stm32f7lv.s $(CFLAGS_THUMB2) -o stm32f7lv.o
$(OBJCOPY) -O binary stm32f7lv.o stm32f7lv.bin
$(XXD) $(XXDFLAGS) stm32f7lv.bin stm32f7lv.h
clean:
rm *.o
rm *.bin
rm *.h

Wyświetl plik

@ -1,6 +1,4 @@
Original Chinese version can be found below.
# Clean Room Documentation English Version
# Flash Loader Documentation
Code is situated in section `.text`
@ -12,11 +10,12 @@ All parameters would be passed over registers
`r0`: the base address of the copy source
`r1`: the base address of the copy destination
`r2`: the total word (4 bytes) count to be copied (with expeptions)
`r2`: the count of byte to be copied
`r3`: flash register offset (used to support two banks)
**What the program is expected to do**:
Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be cleared to zero to indicate that the copy is done.
Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be less or equal to zero to indicate that the copy is done.
**Limitation**: No stack operations are permitted. Registers ranging from `r3` to `r12` are free to use. Note that `r13` is `sp`(stack pointer), `r14` is `lr`(commonly used to store jump address), `r15` is `pc`(program counter).
@ -24,8 +23,6 @@ Copy data from source to destination, after which trigger a breakpint to exit. B
## stm32f0.s
**Exception**: `r2` stores the total half word (2 bytes) count to be copied
`flash_base`: 0x40022000
`FLASH_CR`: offset from `flash_base` is 16
@ -37,11 +34,11 @@ Copy data from source to destination, after which trigger a breakpint to exit. B
**Special requirements**:
Before every copy, read a word from FLASH_CR, set the lowest bit to 1 and write back. Copy one half word each time.
Before every copy, read a word from FLASH_CR, set the PG bit to 1 and write back. Copy one half word each time.
How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is 4, otherwise exit.
How to wait for the write process: read a word from FLASH_SR, loop until the busy bit is reset. After that, FLASH_SR is check. The process is interrupted if the error bit (0x04) is set.
Exit: after the copying process and before triggering the breakpoint, clear the lowest bit in FLASH_CR.
Exit: after the copying process and before triggering the breakpoint, clear the PG bit in FLASH_CR.
## stm32f4.s
@ -56,7 +53,8 @@ Exit: after the copying process and before triggering the breakpoint, clear the
**Special requirements**:
Copy one word each time.
How to wait for the write process: read a half word from FLASH_SR, loop until the content is not 1.
How to wait for the write process: read a word from FLASH_SR, loop until the busy bit is reset.
## stm32f4lv.s
@ -71,7 +69,7 @@ How to wait for the write process: read a half word from FLASH_SR, loop until th
Copy one byte each time.
How to wait from the write process: read a half word from FLASH_SR, loop until the content is not 1.
How to wait from the write process: read a half word from FLASH_SR, loop until the busy bit is reset.
## stm32f7.s
@ -89,7 +87,7 @@ Mostly same with `stm32f4.s`. Require establishing a memory barrier after every
Mostly same with `stm32f7.s`. Copy one byte each time.
## stm32l0x.s
## stm32lx.s
**Special Requirements**:
@ -97,8 +95,6 @@ Copy one word each time. No wait for write.
## stm32l4.s
**Exception**: r2 stores the double word count to be copied.
`flash_base`: 0x40022000
`FLASH_BSY`: offset from `flash_base` is 0x12
@ -109,14 +105,10 @@ Copy one word each time. No wait for write.
Copy one double word each time (More than one registers are allowed).
How to wait for the write process: read a half word from `FLASH_BSY`, loop until the lowest bit turns non-1.
## stm32lx.s
Same with stm32l0x.s.
How to wait for the write process: read a half word from `FLASH_BSY`, loop until the busy bit is reset.
# 净室工程文档-原始中文版
# 净室工程文档-原始中文版 (out of date)
代码位于的section`.text`
编译制导添加`.syntax unified`
@ -139,8 +131,6 @@ Same with stm32l0x.s.
## stm32f0.s
例外:`r2`:拷贝half word2字节
特殊地址定义:`flash_base`:定义为0x40022000
`FLASH_CR`: 相对`flash_base`的offset为16
@ -230,4 +220,4 @@ Same with stm32l0x.s.
## stm32lx.s
要求与stm32l0x.s相同
要求与stm32l0x.s相同

Wyświetl plik

@ -1,6 +1,14 @@
.syntax unified
.text
/*
* Arguments:
* r0 - source memory ptr
* r1 - target memory ptr
* r2 - count of bytes
* r3 - flash register offset
*/
.global copy
copy:
/*
@ -17,54 +25,56 @@ copy:
*/
nop
nop
ldr r7, =flash_base
ldr r4, [r7]
ldr r7, =flash_off_cr
ldr r6, [r7]
adds r6, r6, r4
ldr r7, =flash_off_sr
ldr r5, [r7]
adds r5, r5, r4
# load flash control register address
# add r3 to flash_base for support dual bank (see flash_loader.c)
ldr r7, flash_base
add r7, r7, r3
ldr r6, flash_off_cr
add r6, r6, r7
ldr r5, flash_off_sr
add r5, r5, r7
# FLASH_CR |= 0x01 (set PG)
ldr r7, =0x1
ldr r4, [r6]
orrs r4, r4, r7
str r4, [r6]
loop:
# FLASH_CR ^= 1
ldr r7, =0x1
ldr r3, [r6]
orrs r3, r3, r7
str r3, [r6]
# copy 2 bytes
ldrh r3, [r0]
strh r3, [r1]
ldrh r4, [r0]
strh r4, [r1]
ldr r7, =2
adds r0, r0, r7
adds r1, r1, r7
# increment address
adds r0, r0, #0x2
adds r1, r1, #0x2
# wait if FLASH_SR == 1
# BUSY flag
ldr r7, =0x01
wait:
ldr r7, =0x1
ldr r3, [r5]
tst r3, r7
beq wait
# get FLASH_SR
ldr r4, [r5]
# exit if FLASH_SR != 4
ldr r7, =0x4
tst r3, r7
# wait until BUSY flag is reset
tst r4, r7
bne wait
# test PGERR or WRPRTERR flag is reset
ldr r7, =0x14
tst r4, r7
bne exit
# loop if r2 != 0
ldr r7, =0x1
subs r2, r2, r7
cmp r2, #0
bne loop
# loop if count > 0
subs r2, r2, #0x2
bgt loop
exit:
# FLASH_CR &= ~1
ldr r7, =0x1
ldr r3, [r6]
bics r3, r3, r7
str r3, [r6]
ldr r4, [r6]
bics r4, r4, r7
str r4, [r6]
bkpt

Wyświetl plik

@ -1,6 +1,14 @@
.syntax unified
.text
/*
* Arguments:
* r0 - source memory ptr
* r1 - target memory ptr
* r2 - count of bytes
* r3 - flash register offset
*/
.global copy
copy:
ldr r12, flash_base
@ -9,22 +17,24 @@ copy:
loop:
# copy 4 bytes
ldr r3, [r0]
str r3, [r1]
ldr r4, [r0]
str r4, [r1]
# increment address
add r0, r0, #4
add r1, r1, #4
# wait if FLASH_SR == 1
wait:
ldrh r3, [r10]
tst r3, #0x1
beq wait
# get FLASH_SR
ldrh r4, [r10]
# loop if r2 != 0
sub r2, r2, #1
cmp r2, #0
bne loop
# wait until BUSY flag is reset
tst r4, #0x1
bne wait
# loop if count > 0
subs r2, r2, #4
bgt loop
exit:
bkpt

Wyświetl plik

@ -1,36 +1,40 @@
.syntax unified
.text
/*
* Arguments:
* r0 - source memory ptr
* r1 - target memory ptr
* r2 - count of bytes
* r3 - flash register offset
*/
.global copy
copy:
ldr r12, flash_base
ldr r10, flash_off_sr
add r10, r10, r12
# tip 1: original r2 indicates the count of 4 bytes need to copy,
# but we can only copy one byte each time.
# as we have no flash larger than 1GB, we do a little trick here.
# tip 2: r2 is always a power of 2
mov r2, r2, lsl#2
loop:
# copy 1 byte
ldrb r3, [r0]
strb r3, [r1]
ldrb r4, [r0]
strb r4, [r1]
# increment address
add r0, r0, #1
add r1, r1, #1
# wait if FLASH_SR == 1
wait:
ldrh r3, [r10]
tst r3, #0x1
beq wait
# get FLASH_SR
ldrh r4, [r10]
# loop if r2 != 0
sub r2, r2, #1
cmp r2, #0
bne loop
# wait until BUSY flag is reset
tst r4, #0x1
bne wait
# loop if count > 0
subs r2, r2, #1
bgt loop
exit:
bkpt

Wyświetl plik

@ -1,6 +1,14 @@
.syntax unified
.text
/*
* Arguments:
* r0 - source memory ptr
* r1 - target memory ptr
* r2 - count of bytes
* r3 - flash register offset
*/
.global copy
copy:
ldr r12, flash_base
@ -9,25 +17,27 @@ copy:
loop:
# copy 4 bytes
ldr r3, [r0]
str r3, [r1]
ldr r4, [r0]
str r4, [r1]
# increment address
add r0, r0, #4
add r1, r1, #4
# memory barrier
dsb sy
# wait if FLASH_SR == 1
wait:
ldrh r3, [r10]
tst r3, #0x1
beq wait
# get FLASH_SR
ldrh r4, [r10]
# loop if r2 != 0
sub r2, r2, #1
cmp r2, #0
bne loop
# wait until BUSY flag is reset
tst r4, #0x1
bne wait
# loop if count > 0
subs r2, r2, #4
bgt loop
exit:
bkpt

Wyświetl plik

@ -1,39 +1,43 @@
.syntax unified
.text
/*
* Arguments:
* r0 - source memory ptr
* r1 - target memory ptr
* r2 - count of bytes
* r3 - flash register offset
*/
.global copy
copy:
ldr r12, flash_base
ldr r10, flash_off_sr
add r10, r10, r12
# tip 1: original r2 indicates the count in 4 bytes need to copy,
# but we can only copy one byte each time.
# as we have no flash larger than 1GB, we do a little trick here.
# tip 2: r2 is always a power of 2
mov r2, r2, lsl#2
loop:
# copy 1 byte
ldrb r3, [r0]
strb r3, [r1]
ldrb r4, [r0]
strb r4, [r1]
# increment address
add r0, r0, #1
add r1, r1, #1
# memory barrier
dsb sy
# wait if FLASH_SR == 1
wait:
ldrh r3, [r10]
tst r3, #0x1
beq wait
# get FLASH_SR
ldrh r4, [r10]
# loop if r2 != 0
sub r2, r2, #1
cmp r2, #0
bne loop
# wait until BUSY flag is reset
tst r4, #0x1
bne wait
# loop if count > 0
subs r2, r2, #1
bgt loop
exit:
bkpt

Wyświetl plik

@ -1,22 +0,0 @@
.syntax unified
.text
.global copy
copy:
loop:
# copy 4 bytes
ldr r3, [r0]
str r3, [r1]
ldr r7, =4
add r0, r0, r7
add r1, r1, r7
# loop if r2 != 0
ldr r7, =1
subs r2, r2, r7
cmp r2, #0
bne loop
exit:
bkpt

Wyświetl plik

@ -1,6 +1,14 @@
.syntax unified
.text
/*
* Arguments:
* r0 - source memory ptr
* r1 - target memory ptr
* r2 - count of bytes
* r3 - flash register offset
*/
.global copy
copy:
ldr r12, flash_base
@ -9,24 +17,26 @@ copy:
loop:
# copy 8 bytes
ldr r3, [r0]
ldr r5, [r0]
ldr r4, [r0, #4]
str r3, [r1]
str r5, [r1]
str r4, [r1, #4]
# increment address
add r0, r0, #8
add r1, r1, #8
# wait if FLASH_BSY[0b] == 1
wait:
ldrh r3, [r10]
tst r3, #0x1
beq wait
# get FLASH_SR
ldr r4, [r10]
# loop if r2 != 0
sub r2, r2, #1
cmp r2, #0
bne loop
# wait until BUSY flag is reset
tst r4, #0x10000
bne wait
# loop if count > 0
subs r2, r2, #8
bgt loop
exit:
bkpt

Wyświetl plik

@ -1,22 +1,28 @@
.syntax unified
.text
/*
* Arguments:
* r0 - source memory ptr
* r1 - target memory ptr
* r2 - count of bytes
* r3 - flash register offset
*/
.global copy
copy:
loop:
# copy 4 bytes
ldr r3, [r0]
str r3, [r1]
ldr r4, [r0]
str r4, [r1]
ldr r7, =4
add r0, r0, r7
add r1, r1, r7
# increment address
add r0, r0, #4
add r1, r1, #4
# loop if r2 != 0
ldr r7, =1
subs r2, r2, r7
cmp r2, #0
bne loop
# loop if count > 0
subs r2, r2, #4
bgt loop
exit:
bkpt

Wyświetl plik

@ -13,89 +13,72 @@
/* flashloaders/stm32f0.s -- compiled with thumb2 */
static const uint8_t loader_code_stm32vl[] = {
0x16, 0x4f, 0x3c, 0x68,
0x16, 0x4f, 0x3e, 0x68,
0x36, 0x19, 0x16, 0x4f,
0x3d, 0x68, 0x2d, 0x19,
0x00, 0xbf, 0x00, 0xbf,
0x0f, 0x4f, 0x1f, 0x44,
0x0f, 0x4e, 0x3e, 0x44,
0x0f, 0x4d, 0x3d, 0x44,
0x4f, 0xf0, 0x01, 0x07,
0x33, 0x68, 0x3b, 0x43,
0x33, 0x60, 0x03, 0x88,
0x0b, 0x80, 0x4f, 0xf0,
0x02, 0x07, 0xc0, 0x19,
0xc9, 0x19, 0x4f, 0xf0,
0x01, 0x07, 0x2b, 0x68,
0x3b, 0x42, 0xfa, 0xd0,
0x4f, 0xf0, 0x04, 0x07,
0x3b, 0x42, 0x04, 0xd1,
0x34, 0x68, 0x3c, 0x43,
0x34, 0x60, 0x04, 0x88,
0x0c, 0x80, 0x02, 0x30,
0x02, 0x31, 0x4f, 0xf0,
0x01, 0x07, 0x2c, 0x68,
0x3c, 0x42, 0xfc, 0xd1,
0x4f, 0xf0, 0x14, 0x07,
0x3c, 0x42, 0x01, 0xd1,
0x02, 0x3a, 0xf0, 0xdc,
0x4f, 0xf0, 0x01, 0x07,
0xd2, 0x1b, 0x00, 0x2a,
0xe6, 0xd1, 0x4f, 0xf0,
0x01, 0x07, 0x33, 0x68,
0xbb, 0x43, 0x33, 0x60,
0x00, 0xbe, 0x00, 0xbf,
0x34, 0x68, 0xbc, 0x43,
0x34, 0x60, 0x00, 0xbe,
0x00, 0x20, 0x02, 0x40,
0x10, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x20,
0x54, 0x00, 0x00, 0x20,
0x58, 0x00, 0x00, 0x20
0x0c, 0x00, 0x00, 0x00
};
/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */
static const uint8_t loader_code_stm32f0[] = {
0xc0, 0x46, 0xc0, 0x46,
0x13, 0x4f, 0x3c, 0x68,
0x13, 0x4f, 0x3e, 0x68,
0x36, 0x19, 0x13, 0x4f,
0x3d, 0x68, 0x2d, 0x19,
0x12, 0x4f, 0x33, 0x68,
0x3b, 0x43, 0x33, 0x60,
0x03, 0x88, 0x0b, 0x80,
0x10, 0x4f, 0xc0, 0x19,
0xc9, 0x19, 0x0e, 0x4f,
0x2b, 0x68, 0x3b, 0x42,
0xfb, 0xd0, 0x0e, 0x4f,
0x3b, 0x42, 0x03, 0xd1,
0x0a, 0x4f, 0xd2, 0x1b,
0x00, 0x2a, 0xeb, 0xd1,
0x08, 0x4f, 0x33, 0x68,
0xbb, 0x43, 0x33, 0x60,
0x00, 0xbe, 0xc0, 0x46,
0x0d, 0x4f, 0x1f, 0x44,
0x0d, 0x4e, 0x3e, 0x44,
0x0d, 0x4d, 0x3d, 0x44,
0x0d, 0x4f, 0x34, 0x68,
0x3c, 0x43, 0x34, 0x60,
0x04, 0x88, 0x0c, 0x80,
0x02, 0x30, 0x02, 0x31,
0x09, 0x4f, 0x2c, 0x68,
0x3c, 0x42, 0xfc, 0xd1,
0x08, 0x4f, 0x3c, 0x42,
0x01, 0xd1, 0x02, 0x3a,
0xf2, 0xdc, 0x05, 0x4f,
0x34, 0x68, 0xbc, 0x43,
0x34, 0x60, 0x00, 0xbe,
0x00, 0x20, 0x02, 0x40,
0x10, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00,
0x48, 0x00, 0x00, 0x20,
0x4c, 0x00, 0x00, 0x20,
0x50, 0x00, 0x00, 0x20,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00
0x14, 0x00, 0x00, 0x00
};
static const uint8_t loader_code_stm32l[] = {
static const uint8_t loader_code_stm32lx[] = {
// flashloaders/stm32lx.s
0x03, 0x68, 0x0b, 0x60,
0x4f, 0xf0, 0x04, 0x07,
0x38, 0x44, 0x39, 0x44,
0x4f, 0xf0, 0x01, 0x07,
0xd2, 0x1b, 0x00, 0x2a,
0xf4, 0xd1, 0x00, 0xbe,
0x04, 0x68, 0x0c, 0x60,
0x00, 0xf1, 0x04, 0x00,
0x01, 0xf1, 0x04, 0x01,
0x04, 0x3a, 0xf7, 0xdc,
0x00, 0xbe
};
static const uint8_t loader_code_stm32f4[] = {
// flashloaders/stm32f4.s
0xdf, 0xf8, 0x28, 0xc0,
0xdf, 0xf8, 0x28, 0xa0,
0xe2, 0x44, 0x03, 0x68,
0x0b, 0x60, 0x00, 0xf1,
0xdf, 0xf8, 0x24, 0xc0,
0xdf, 0xf8, 0x24, 0xa0,
0xe2, 0x44, 0x04, 0x68,
0x0c, 0x60, 0x00, 0xf1,
0x04, 0x00, 0x01, 0xf1,
0x04, 0x01, 0xba, 0xf8,
0x00, 0x30, 0x13, 0xf0,
0x01, 0x0f, 0xfa, 0xd0,
0xa2, 0xf1, 0x01, 0x02,
0x00, 0x2a, 0xf0, 0xd1,
0x00, 0x40, 0x14, 0xf0,
0x01, 0x0f, 0xfa, 0xd1,
0x04, 0x3a, 0xf2, 0xdc,
0x00, 0xbe, 0x00, 0xbf,
0x00, 0x3c, 0x02, 0x40,
0x0e, 0x00, 0x00, 0x00
@ -103,17 +86,15 @@ static const uint8_t loader_code_stm32f4[] = {
static const uint8_t loader_code_stm32f4_lv[] = {
// flashloaders/stm32f4lv.s
0xdf, 0xf8, 0x2c, 0xc0,
0xdf, 0xf8, 0x2c, 0xa0,
0xe2, 0x44, 0x4f, 0xea,
0x82, 0x02, 0x03, 0x78,
0x0b, 0x70, 0x00, 0xf1,
0xdf, 0xf8, 0x24, 0xc0,
0xdf, 0xf8, 0x24, 0xa0,
0xe2, 0x44, 0x04, 0x78,
0x0c, 0x70, 0x00, 0xf1,
0x01, 0x00, 0x01, 0xf1,
0x01, 0x01, 0xba, 0xf8,
0x00, 0x30, 0x13, 0xf0,
0x01, 0x0f, 0xfa, 0xd0,
0xa2, 0xf1, 0x01, 0x02,
0x00, 0x2a, 0xf0, 0xd1,
0x00, 0x40, 0x14, 0xf0,
0x01, 0x0f, 0xfa, 0xd1,
0x01, 0x3a, 0xf2, 0xdc,
0x00, 0xbe, 0x00, 0xbf,
0x00, 0x3c, 0x02, 0x40,
0x0e, 0x00, 0x00, 0x00
@ -121,17 +102,16 @@ static const uint8_t loader_code_stm32f4_lv[] = {
static const uint8_t loader_code_stm32l4[] = {
// flashloaders/stm32l4.s
0xdf, 0xf8, 0x2c, 0xc0,
0xdf, 0xf8, 0x2c, 0xa0,
0xe2, 0x44, 0x03, 0x68,
0x44, 0x68, 0x0b, 0x60,
0xdf, 0xf8, 0x28, 0xc0,
0xdf, 0xf8, 0x28, 0xa0,
0xe2, 0x44, 0x05, 0x68,
0x44, 0x68, 0x0d, 0x60,
0x4c, 0x60, 0x00, 0xf1,
0x08, 0x00, 0x01, 0xf1,
0x08, 0x01, 0xba, 0xf8,
0x00, 0x30, 0x13, 0xf0,
0x01, 0x0f, 0xfa, 0xd0,
0xa2, 0xf1, 0x01, 0x02,
0x00, 0x2a, 0xee, 0xd1,
0x08, 0x01, 0xda, 0xf8,
0x00, 0x40, 0x14, 0xf4,
0x80, 0x3f, 0xfa, 0xd1,
0x08, 0x3a, 0xf0, 0xdc,
0x00, 0xbe, 0x00, 0xbf,
0x00, 0x20, 0x02, 0x40,
0x12, 0x00, 0x00, 0x00
@ -139,17 +119,16 @@ static const uint8_t loader_code_stm32l4[] = {
static const uint8_t loader_code_stm32f7[] = {
// flashloaders/stm32f7.s
0xdf, 0xf8, 0x2c, 0xc0,
0xdf, 0xf8, 0x2c, 0xa0,
0xe2, 0x44, 0x03, 0x68,
0x0b, 0x60, 0x00, 0xf1,
0xdf, 0xf8, 0x28, 0xc0,
0xdf, 0xf8, 0x28, 0xa0,
0xe2, 0x44, 0x04, 0x68,
0x0c, 0x60, 0x00, 0xf1,
0x04, 0x00, 0x01, 0xf1,
0x04, 0x01, 0xbf, 0xf3,
0x4f, 0x8f, 0xba, 0xf8,
0x00, 0x30, 0x13, 0xf0,
0x01, 0x0f, 0xfa, 0xd0,
0xa2, 0xf1, 0x01, 0x02,
0x00, 0x2a, 0xee, 0xd1,
0x00, 0x40, 0x14, 0xf0,
0x01, 0x0f, 0xfa, 0xd1,
0x04, 0x3a, 0xf0, 0xdc,
0x00, 0xbe, 0x00, 0xbf,
0x00, 0x3c, 0x02, 0x40,
0x0e, 0x00, 0x00, 0x00
@ -157,18 +136,16 @@ static const uint8_t loader_code_stm32f7[] = {
static const uint8_t loader_code_stm32f7_lv[] = {
// flashloaders/stm32f7lv.s
0xdf, 0xf8, 0x30, 0xc0,
0xdf, 0xf8, 0x30, 0xa0,
0xe2, 0x44, 0x4f, 0xea,
0x82, 0x02, 0x03, 0x78,
0x0b, 0x70, 0x00, 0xf1,
0xdf, 0xf8, 0x28, 0xc0,
0xdf, 0xf8, 0x28, 0xa0,
0xe2, 0x44, 0x04, 0x78,
0x0c, 0x70, 0x00, 0xf1,
0x01, 0x00, 0x01, 0xf1,
0x01, 0x01, 0xbf, 0xf3,
0x4f, 0x8f, 0xba, 0xf8,
0x00, 0x30, 0x13, 0xf0,
0x01, 0x0f, 0xfa, 0xd0,
0xa2, 0xf1, 0x01, 0x02,
0x00, 0x2a, 0xee, 0xd1,
0x00, 0x40, 0x14, 0xf0,
0x01, 0x0f, 0xfa, 0xd1,
0x01, 0x3a, 0xf0, 0xdc,
0x00, 0xbe, 0x00, 0xbf,
0x00, 0x3c, 0x02, 0x40,
0x0e, 0x00, 0x00, 0x00
@ -234,8 +211,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t*
sl->chip_id == STLINK_CHIPID_STM32_L0 ||
sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 ||
sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l
loader_code = loader_code_stm32l;
loader_size = sizeof(loader_code_stm32l);
loader_code = loader_code_stm32lx;
loader_size = sizeof(loader_code_stm32lx);
} else if (sl->core_id == STM32VL_CORE_ID ||
sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM ||
sl->chip_id == STLINK_CHIPID_STM32_F1_HIGH ||
@ -315,10 +292,9 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t*
int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) {
struct stlink_reg rr;
unsigned timeout;
size_t count = 0;
uint32_t flash_base = 0;
const char *error = NULL;
uint32_t dhcsr, dfsr;
uint32_t dhcsr, dfsr, cfsr, hfsr;
DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size);
@ -329,22 +305,6 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe
return(-1);
}
if ((sl->flash_type == STLINK_FLASH_TYPE_F0) ||
(sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) {
count = size / sizeof(uint16_t);
if (size % sizeof(uint16_t)) { ++count; }
} else if (sl->flash_type == STLINK_FLASH_TYPE_F4 ||
sl->flash_type == STLINK_FLASH_TYPE_L0) {
count = size / sizeof(uint32_t);
if (size % sizeof(uint32_t)) { ++count; }
} else if (sl->flash_type == STLINK_FLASH_TYPE_L4) {
count = size / sizeof(uint64_t);
if (size % sizeof(uint64_t)) { ++count; }
}
if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) {
flash_base = FLASH_REGS_BANK2_OFS;
}
@ -352,7 +312,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe
/* Setup core */
stlink_write_reg(sl, fl->buf_addr, 0); // source
stlink_write_reg(sl, target, 1); // target
stlink_write_reg(sl, (uint32_t)count, 2); // count
stlink_write_reg(sl, (uint32_t)size, 2); // count
stlink_write_reg(sl, flash_base, 3); // flash register base
// only used on VL/F1_XL, but harmless for others
stlink_write_reg(sl, fl->loader_addr, 15); // pc register
@ -376,9 +336,9 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe
usleep(10000);
if (stlink_is_core_halted(sl)) {
timeout = 0;
break;
}
timeout = 0;
break;
}
}
if (timeout) {
@ -397,11 +357,14 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe
return(0);
error:
dhcsr = dfsr = 0;
dhcsr = dfsr = cfsr = hfsr = 0;
stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr);
stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr);
stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr);
stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr);
stlink_read_all_regs(sl, &rr);
ELOG("%s (R2 0x%08X R15 0x%08X DHCSR 0x%08X DFSR 0x%08X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr);
ELOG("%s (R2 0x%X R15 0x%X DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr, cfsr, hfsr);
ELOG("(R0 0x%X R1 0x%X)\n", rr.r[0], rr.r[1]);
return(-1);
}

Wyświetl plik

@ -19,6 +19,12 @@
#define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16)
/* Cortex™-M3 Technical Reference Manual */
/* Configurable Fault Status Register */
#define STLINK_REG_CFSR 0xE000ED28
/* Hard Fault Status Register */
#define STLINK_REG_HFSR 0xE000ED2C
/* Debug Halting Control and Status Register */
#define STLINK_REG_DFSR 0xE000ED30
#define STLINK_REG_DFSR_HALT (1 << 0)