c8e6e05a8980fa0f0d6a3d2854a4f272cf328101
[fw/openocd] / contrib / loaders / flash / kinetis / kinetis_flash.s
1 /***************************************************************************
2  *   Copyright (C) 2015 by Ivan Meleca                                     *
3  *   ivan@artekit.eu                                                       *
4  *                                                                         *
5  *   Copyright (C) 2016 by Tomas Vanek                                     *
6  *   vanekt@fbl.cz                                                         *
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
19         /* Params:
20          * r0 = flash destination address in/out
21          * r1 = longword count
22          * r2 = workarea start address
23          * r3 = workarea end address
24          * r4 = FTFx base
25          */
26
27         .text
28         .cpu cortex-m0plus
29         .code 16
30         .thumb_func
31
32         .align  2
33
34         /* r5 = rp
35          * r6 = wp, tmp
36          * r7 = tmp
37          */
38
39         /* old longword algo: 6.680 KiB/s @ adapter_khz 2000
40          * this async algo: 19.808 KiB/s @ adapter_khz 2000
41          */
42
43 FTFx_FSTAT =    0
44 FTFx_FCCOB3 =   4
45 FTFx_FCCOB0 =   7
46 FTFx_FCCOB7 =   8
47
48 wait_fifo:
49         ldr     r6, [r2, #0]    /* read wp */
50         cmp     r6, #0          /* abort if wp == 0 */
51         beq     exit
52
53         ldr     r5, [r2, #4]    /* read rp */
54         cmp     r5, r6          /* wait until rp != wp */
55         beq     wait_fifo
56
57         str     r0, [r4, #FTFx_FCCOB3] /* set flash address */
58         mov     r7, #6
59         strb    r7, [r4, #FTFx_FCCOB0] /* flash command */
60
61         ldr     r7, [r5]        /* set longword data = *rp */
62         str     r7, [r4, #FTFx_FCCOB7]
63
64         mov     r7, #128
65         strb    r7, [r4, #FTFx_FSTAT]
66
67         add     r5, #4          /* rp += 4 */
68         cmp     r5, r3          /* Wrap? */
69         bcc     no_wrap
70         mov     r5, r2
71         add     r5, #8
72
73 no_wrap:
74         str     r5, [r2, #4]    /* Store rp */
75
76 wait_ccif:
77         ldr     r6, [r2, #0]    /* read wp */
78         cmp     r6, #0          /* abort if wp == 0 */
79         beq     exit
80
81         ldrb    r6, [r4, #FTFx_FSTAT]
82         tst     r6, r7
83         beq     wait_ccif
84
85         mov     r7, #0x70
86         tst     r6, r7
87         bne     error
88
89         add     r0, #4          /* flash address += 4, do not increment before err check */
90
91         sub     r1, #1          /* word_count-- */
92         cmp     r1, #0
93         bne     wait_fifo
94         b       exit
95
96 error:
97         mov     r5, #0
98         str     r5, [r2, #4]    /* set rp = 0 on error */
99
100 exit:
101         bkpt    #0