Added SPIFI flash driver, algorithms, and docs
[fw/openocd] / contrib / loaders / flash / lpcspifi_init.S
1 /***************************************************************************
2  *   Copyright (C) 2012 by George Harris                                           *
3  *   george@luminairecoffee.com                                            *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 /***************************************************************************
22 *       This is an algorithm for the LPC43xx family (and probably the LPC18xx  *
23 *       family as well, though they have not been tested) that will initialize *
24 *       memory-mapped SPI flash accesses. Unfortunately NXP has published      *
25 *       neither the ROM source code that performs this initialization nor the  *
26 *       register descriptions necessary to do so, so this code is necessary to *
27 *       call into the ROM SPIFI API.                                           *
28 ***************************************************************************/
29
30         .text
31         .syntax unified
32         .arch armv7-m
33         .thumb
34         .thumb_func
35
36         .align 2
37
38 /*
39  * Params :
40  * r0 = spifi clock speed
41  */
42
43 #define IOCONFIG_BASE_HIGH          0x4008
44 #define IOCONFIG_BASE_LOW           0x6000
45 #define IOCONFIG_SCK_OFFSET         0x18c
46 #define IOCONFIG_HOLD_OFFSET        0x190
47 #define IOCONFIG_WP_OFFSET          0x194
48 #define IOCONFIG_MISO_OFFSET        0x198
49 #define IOCONFIG_MOSI_OFFSET        0x19c
50 #define IOCONFIG_CS_OFFSET          0x1a0
51
52 #define SPIFI_ROM_TABLE_BASE_HIGH   0x1040
53 #define SPIFI_ROM_TABLE_BASE_LOW    0x0118
54
55 code:
56         mov.w   r8, r0
57         sub             sp, #0x84
58         add             r7, sp, #0x0
59         /* Initialize SPIFI pins */
60         mov.w   r3, #IOCONFIG_BASE_LOW
61         movt    r3, #IOCONFIG_BASE_HIGH
62         mov.w   r2, #0xf3
63         str.w   r2, [r3, #IOCONFIG_SCK_OFFSET]
64         mov.w   r3, #IOCONFIG_BASE_LOW
65         movt    r3, #IOCONFIG_BASE_HIGH
66         mov.w   r2, #IOCONFIG_BASE_LOW
67         movt    r2, #IOCONFIG_BASE_HIGH
68         mov.w   r1, #IOCONFIG_BASE_LOW
69         movt    r1, #IOCONFIG_BASE_HIGH
70         mov.w   r0, #IOCONFIG_BASE_LOW
71         movt    r0, #IOCONFIG_BASE_HIGH
72         mov.w   r4, #0xd3
73         str.w   r4, [r0, #IOCONFIG_MOSI_OFFSET]
74         mov     r0, r4
75         str.w   r0, [r1, #IOCONFIG_MISO_OFFSET]
76         mov     r1, r0
77         str.w   r1, [r2, #IOCONFIG_WP_OFFSET]
78         str.w   r1, [r3, #IOCONFIG_HOLD_OFFSET]
79         mov.w   r3, #IOCONFIG_BASE_LOW
80         movt    r3, #IOCONFIG_BASE_HIGH
81         mov.w   r2, #0x13
82         str.w   r2, [r3, #IOCONFIG_CS_OFFSET]
83
84         /* Perform SPIFI init. See spifi_rom_api.h (in NXP lpc43xx driver package) for details */
85         /* on initialization arguments. */
86         movw    r3, #SPIFI_ROM_TABLE_BASE_LOW      /* The ROM API table is located @ 0x10400118, and                    */
87         movt    r3, #SPIFI_ROM_TABLE_BASE_HIGH     /* the first pointer in the struct is to the init function. */
88         ldr     r3, [r3, #0x0]
89         ldr     r4, [r3, #0x0]                           /* Grab the init function pointer from the table */
90         /* Set up function arguments */
91         movw    r0, #0x3b4
92         movt    r0, #0x1000                                   /* Pointer to a SPIFI data struct that we don't care about */
93         mov.w   r1, #0x3                        /* "csHigh". Not 100% sure what this does. */
94         mov.w   r2, #0xc0                                     /* The configuration word: S_RCVCLOCK | S_FULLCLK */
95         mov.w   r3, r8                                        /* SPIFI clock speed (12MHz) */
96         blx     r4                                                          /* Call the init function */
97         b               done
98
99 done:
100         bkpt    #0
101
102         .end