aboutsummaryrefslogtreecommitdiff
path: root/contrib/loaders
diff options
context:
space:
mode:
authorSpencer Oliver <spen@spen-soft.co.uk>2012-02-16 09:42:06 +0000
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>2012-02-26 01:05:48 +0000
commit94db77a0e612c7f4802668ad67d41f6414f04abf (patch)
tree9c6518b41a684cf7f82a00b05eedab024df093da /contrib/loaders
parent90cee3569611faabea6c9697836b4a75c7288832 (diff)
downloadriscv-openocd-94db77a0e612c7f4802668ad67d41f6414f04abf.zip
riscv-openocd-94db77a0e612c7f4802668ad67d41f6414f04abf.tar.gz
riscv-openocd-94db77a0e612c7f4802668ad67d41f6414f04abf.tar.bz2
flash: add stm32f2x async flash loader
This enable the stm32f2x flash driver to use the asynchronous algorithm support. Speed increase is as follows: before - wrote 1048576 bytes from file stm32f4x.bin in 30.453804s (33.625 KiB/s) after - wrote 1048576 bytes from file stm32f4x.bin in 23.679497s (43.244 KiB/s) This also fixes a bug that was in the old flash loader. The old loader waited while bit16 of the status reg was 0, the new loader waits until this bit is 0 as stated in the flash spec. Bizarrely this bug did not effect programming on any tested parts. Change-Id: I3efc94d42cbe81283673a8f4203700638080af6e Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk> Reviewed-on: http://openocd.zylin.com/460 Tested-by: jenkins
Diffstat (limited to 'contrib/loaders')
-rw-r--r--contrib/loaders/flash/stm32f2x.S67
1 files changed, 42 insertions, 25 deletions
diff --git a/contrib/loaders/flash/stm32f2x.S b/contrib/loaders/flash/stm32f2x.S
index 49c821b..7ac5e3c 100644
--- a/contrib/loaders/flash/stm32f2x.S
+++ b/contrib/loaders/flash/stm32f2x.S
@@ -21,43 +21,60 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-
-// Build : arm-eabi-gcc -c stm32f2xxx.S
.text
.syntax unified
.cpu cortex-m3
.thumb
.thumb_func
- .global write
/*
- r0 - source address
- r1 - target address
- r2 - count (halfword-16bit)
- r3 - result out
- r4 - flash base
-*/
+ * Params :
+ * r0 = workarea start, status (out)
+ * r1 = workarea end
+ * r2 = target address
+ * r3 = count (16bit words)
+ * r4 = flash base
+ *
+ * Clobbered:
+ * r6 - temp
+ * r7 - rp
+ * r8 - wp, tmp
+ */
#define STM32_FLASH_CR_OFFSET 0x10 /* offset of CR register in FLASH struct */
-#define STM32_FLASH_SR_OFFSET 0x0c /* offset of CR register in FLASH struct */
+#define STM32_FLASH_SR_OFFSET 0x0c /* offset of SR register in FLASH struct */
-write:
+wait_fifo:
+ ldr r8, [r0, #0] /* read wp */
+ cmp r8, #0 /* abort if wp == 0 */
+ beq exit
+ ldr r7, [r0, #4] /* read rp */
+ cmp r7, r8 /* wait until rp != wp */
+ beq wait_fifo
-write_half_word:
- ldr r3, STM32_PROG16
- str r3, [r4, #STM32_FLASH_CR_OFFSET]
- ldrh r3, [r0], #0x02 /* read one half-word from src, increment ptr */
- strh r3, [r1], #0x02 /* write one half-word from src, increment ptr */
+ ldr r6, STM32_PROG16
+ str r6, [r4, #STM32_FLASH_CR_OFFSET]
+ ldrh r6, [r7], #0x02 /* read one half-word from src, increment ptr */
+ strh r6, [r2], #0x02 /* write one half-word from src, increment ptr */
busy:
- ldr r3, [r4, #STM32_FLASH_SR_OFFSET]
- tst r3, #0x10000 /* BSY (bit0) == 1 => operation in progress */
- beq busy /* wait more... */
- tst r3, #0xf0 /* PGSERR | PGPERR | PGAERR | WRPERR */
- bne exit /* fail... */
- subs r2, r2, #0x01 /* decrement counter */
- bne write_half_word /* write next half-word if anything left */
+ ldr r6, [r4, #STM32_FLASH_SR_OFFSET]
+ tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */
+ bne busy /* wait more... */
+ tst r6, #0xf0 /* PGSERR | PGPERR | PGAERR | WRPERR */
+ bne error /* fail... */
+
+ cmp r7, r1 /* wrap rp at end of buffer */
+ it cs
+ addcs r7, r0, #8 /* skip loader args */
+ str r7, [r0, #4] /* store rp */
+ subs r3, r3, #1 /* decrement halfword count */
+ cbz r3, exit /* loop if not done */
+ b wait_fifo
+error:
+ movs r1, #0
+ str r1, [r0, #4] /* set rp = 0 on error */
exit:
+ mov r0, r6 /* return status in r0 */
bkpt #0x00
-
-STM32_PROG16: .word 0x101 /* PG | PSIZE_16*/
+STM32_PROG16: .word 0x101 /* PG | PSIZE_16*/