summaryrefslogtreecommitdiff
path: root/flashloaders/stm32f0.s
blob: 23f1c43feb8945cd6f44098969d4fb14f016201a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    .syntax unified
    .text

    /*
     * Arguments:
     *   r0 - source memory ptr
     *   r1 - target memory ptr
     *   r2 - count of bytes
     *   r3 - flash register offset
     */

    .global copy
copy:
    /*
     * These two NOPs here are a safety precaution, added by Pekka Nikander
     * while debugging the STM32F05x support.  They may not be needed, but
     * there were strange problems with simpler programs, like a program
     * that had just a breakpoint or a program that first moved zero to register r2
     * and then had a breakpoint.  So, it appears safest to have these two nops.
     *
     * Feel free to remove them, if you dare, but then please do test the result
     * rigorously.  Also, if you remove these, it may be a good idea first to
     * #if 0 them out, with a comment when these were taken out, and to remove
     * these only a few months later...  But YMMV.
     */
    nop
    nop

    # 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 r4, =0x1
    str r4, [r6]

loop:
    # copy 2 bytes
    ldrh r4, [r0]
    strh r4, [r1]

    # increment address
    adds r0, r0, #0x2
    adds r1, r1, #0x2

    # BUSY flag
    ldr r7, =0x01
wait:
    # get FLASH_SR
    ldr r4, [r5]

    # 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 count > 0
    subs r2, r2, #0x2
    bgt loop

exit:
    # FLASH_CR &= ~1
    ldr r7, =0x1
    ldr r4, [r6]
    bics r4, r4, r7
    str r4, [r6]

    bkpt

    .align 2
flash_base:
    .word 0x40022000
flash_off_cr:
    .word 0x10
flash_off_sr:
    .word 0x0c