diff --git a/contrib/loaders/flash/stm32x.s b/contrib/loaders/flash/stm32x.s index dcf2b83cc..6cf9f5791 100644 --- a/contrib/loaders/flash/stm32x.s +++ b/contrib/loaders/flash/stm32x.s @@ -19,7 +19,10 @@ ***************************************************************************/ .text - .arm + .syntax unified + .thumb + .thumb_func + .global write /* r0 - source address @@ -27,26 +30,27 @@ r2 - count (halfword-16bit) r3 - result r4 - temp - r5 - temp */ -write: - ldr r4, STM32_FLASH_CR - ldr r5, STM32_FLASH_SR - mov r3, #1 - str r3, [r4, #0] - ldrh r3, [r0], #2 - strh r3, [r1], #2 -busy: - ldr r3, [r5, #0] - tst r3, #0x01 - beq busy - tst r3, #0x14 - bne exit - subs r2, r2, #1 - bne write -exit: - bkpt #0 +#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 */ -STM32_FLASH_CR: .word 0x40022010 -STM32_FLASH_SR: .word 0x4002200C +write: + ldr r4, STM32_FLASH_BASE +write_half_word: + movs r3, #0x01 + str r3, [r4, #STM32_FLASH_CR_OFFSET] /* PG (bit0) == 1 => flash programming enabled */ + ldrh r3, [r0], #0x02 /* read one half-word from src, increment ptr */ + strh r3, [r1], #0x02 /* write one half-word from src, increment ptr */ +busy: + ldr r3, [r4, #STM32_FLASH_SR_OFFSET] + tst r3, #0x01 /* BSY (bit0) == 1 => operation in progress */ + beq busy /* wait more... */ + tst r3, #0x14 /* PGERR (bit2) == 1 or WRPRTERR (bit4) == 1 => error */ + bne exit /* fail... */ + subs r2, r2, #0x01 /* decrement counter */ + bne write_half_word /* write next half-word if anything left */ +exit: + bkpt #0x00 + +STM32_FLASH_BASE: .word 0x40022000 /* base address of FLASH struct */ diff --git a/src/flash/nor/stm32x.c b/src/flash/nor/stm32x.c index 6b46afc8d..7779ea3aa 100644 --- a/src/flash/nor/stm32x.c +++ b/src/flash/nor/stm32x.c @@ -503,25 +503,26 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer, /* see contib/loaders/flash/stm32x.s for src */ static const uint8_t stm32x_flash_write_code[] = { + /* #define STM32_FLASH_CR_OFFSET 0x10 */ + /* #define STM32_FLASH_SR_OFFSET 0x0C */ /* write: */ - 0xDF, 0xF8, 0x24, 0x40, /* ldr r4, STM32_FLASH_CR */ - 0x09, 0x4D, /* ldr r5, STM32_FLASH_SR */ - 0x4F, 0xF0, 0x01, 0x03, /* mov r3, #1 */ - 0x23, 0x60, /* str r3, [r4, #0] */ - 0x30, 0xF8, 0x02, 0x3B, /* ldrh r3, [r0], #2 */ - 0x21, 0xF8, 0x02, 0x3B, /* strh r3, [r1], #2 */ + 0xdf, 0xf8, 0x20, 0x40, /* ldr r4, STM32_FLASH_BASE */ + /* write_half_word: */ + 0x01, 0x23, /* movs r3, #0x01 */ + 0x23, 0x61, /* str r3, [r4, #STM32_FLASH_CR_OFFSET] */ + 0x30, 0xf8, 0x02, 0x3b, /* ldrh r3, [r0], #0x02 */ + 0x21, 0xf8, 0x02, 0x3b, /* strh r3, [r1], #0x02 */ /* busy: */ - 0x2B, 0x68, /* ldr r3, [r5, #0] */ - 0x13, 0xF0, 0x01, 0x0F, /* tst r3, #0x01 */ - 0xFB, 0xD0, /* beq busy */ - 0x13, 0xF0, 0x14, 0x0F, /* tst r3, #0x14 */ - 0x01, 0xD1, /* bne exit */ - 0x01, 0x3A, /* subs r2, r2, #1 */ - 0xED, 0xD1, /* bne write */ + 0xe3, 0x68, /* ldr r3, [r4, #STM32_FLASH_SR_OFFSET] */ + 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #0x01 */ + 0xfb, 0xd0, /* beq busy */ + 0x13, 0xf0, 0x14, 0x0f, /* tst r3, #0x14 */ + 0x01, 0xd1, /* bne exit */ + 0x01, 0x3a, /* subs r2, r2, #0x01 */ + 0xf0, 0xd1, /* bne write_half_word */ /* exit: */ - 0x00, 0xBE, /* bkpt #0 */ - 0x10, 0x20, 0x02, 0x40, /* STM32_FLASH_CR: .word 0x40022010 */ - 0x0C, 0x20, 0x02, 0x40 /* STM32_FLASH_SR: .word 0x4002200C */ + 0x00, 0xbe, /* bkpt #0x00 */ + 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ }; /* flash write code */