73f4b6fde6cc501ce7f75d8b90a0616b54ade72f
[fw/openocd] / contrib / loaders / flash / mdr32fx.S
1 /***************************************************************************
2  *   Copyright (C) 2011 by Andreas Fritiofson                              *
3  *   andreas.fritiofson@gmail.com                                          *
4  *                                                                         *
5  *   Copyright (C) 2013 by Paul Fertser                                    *
6  *   fercerpav@gmail.com                                                   *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
22  ***************************************************************************/
23
24         .text
25         .syntax unified
26         .cpu cortex-m0
27         .thumb
28         .thumb_func
29         .global write
30
31         /* Params:
32          * r0 - flash base (in), status (out)
33          * r1 - count (32bit)
34          * r2 - workarea start
35          * r3 - workarea end
36          * r4 - target address
37          * Clobbered:
38          * r5 - rp
39          * r6 - wp, tmp
40          * r7 - current FLASH_CMD
41          */
42
43 #define FLASH_CMD       0x00
44 #define FLASH_ADR       0x04
45 #define FLASH_DI        0x08
46
47 #define FLASH_NVSTR     (1 << 13)
48 #define FLASH_PROG      (1 << 12)
49 #define FLASH_MAS1      (1 << 11)
50 #define FLASH_ERASE     (1 << 10)
51 #define FLASH_SE        (1 << 8)
52 #define FLASH_YE        (1 << 7)
53 #define FLASH_XE        (1 << 6)
54
55         ldr     r7, [r0, #FLASH_CMD]
56 wait_fifo:
57         ldr     r6, [r2, #0]    /* read wp */
58         cmp     r6, #0                  /* abort if wp == 0 */
59         beq     exit
60         ldr     r5, [r2, #4]    /* read rp */
61         cmp     r5, r6                  /* wait until rp != wp */
62         beq     wait_fifo
63
64         ldr     r6, [r5]        /* "*target_address++ = *rp++" */
65         str     r4, [r0, #FLASH_ADR]
66         str     r6, [r0, #FLASH_DI]
67
68         ldr     r6, =(FLASH_XE | FLASH_PROG)
69         orrs    r7, r7, r6
70         str     r7, [r0, #FLASH_CMD]
71         # wait 5us
72         movs    r6, #5
73         bl      delay
74         ldr     r6, =#FLASH_NVSTR
75         orrs    r7, r7, r6
76         str     r7, [r0, #FLASH_CMD]
77         # wait 10us
78         movs    r6, #13
79         bl      delay
80         movs    r6, #FLASH_YE
81         orrs    r7, r7, r6
82         str     r7, [r0, #FLASH_CMD]
83         # wait 40us
84         movs    r6, #61
85         bl      delay
86         movs    r6, #FLASH_YE
87         bics    r7, r7, r6
88         str     r7, [r0, #FLASH_CMD]
89         ldr     r6, =#FLASH_PROG
90         bics    r7, r7, r6
91         str     r7, [r0, #FLASH_CMD]
92         # wait 5us
93         movs    r6, #5
94         bl      delay
95         ldr     r6, =#(FLASH_XE | FLASH_NVSTR)
96         bics    r7, r7, r6
97         str     r7, [r0, #FLASH_CMD]
98
99         adds    r5, #4
100         adds    r4, #4
101
102         cmp     r5, r3                  /* wrap rp at end of buffer */
103         bcc     no_wrap
104         mov     r5, r2
105         adds    r5, #8
106 no_wrap:
107         str     r5, [r2, #4]    /* store rp */
108         subs    r1, r1, #1              /* decrement word count */
109         cmp     r1, #0
110         beq     exit            /* loop if not done */
111         b       wait_fifo
112 exit:
113         mov             r0, r6                  /* return status in r0 */
114         bkpt    #0
115
116         /* r6 - in
117          * for r6 == 1 it'll take:
118          *  1 (prepare operand) + 4 (bl) + 2 (subs+cmp) + 1 (bne) + 3 (b) ->
119          *  11 tacts == 1.4us with 8MHz
120          * every extra iteration will take 5 tacts == 0.6us */
121 delay:
122         subs    r6, r6, #1
123         cmp     r6, #0
124         bne     delay
125         bx      lr