70cdcfa28bfd6d6684de0d331e1dab9706aec3b4
[openocd.git] / contrib / loaders / flash / lpcspifi_erase.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4 * Copyright (C) 2012 by George Harris *
5 * george@luminairecoffee.com *
6 ***************************************************************************/
7
8 .text
9 .syntax unified
10 .cpu cortex-m3
11 .thumb
12 .thumb_func
13
14 /*
15 * Params :
16 * r0 = start address, status (out)
17 * r1 = count
18 * r2 = erase command
19 * r3 = block size
20 */
21
22 #define SSP_BASE_HIGH 0x4008
23 #define SSP_BASE_LOW 0x3000
24 #define SSP_CR0_OFFSET 0x00
25 #define SSP_CR1_OFFSET 0x04
26 #define SSP_DATA_OFFSET 0x08
27 #define SSP_CPSR_OFFSET 0x10
28 #define SSP_SR_OFFSET 0x0c
29
30 #define SSP_CLOCK_BASE_HIGH 0x4005
31 #define SSP_CLOCK_BASE_LOW 0x0000
32 #define SSP_BRANCH_CLOCK_BASE_HIGH 0x4005
33 #define SSP_BRANCH_CLOCK_BASE_LOW 0x2000
34 #define SSP_BASE_CLOCK_OFFSET 0x94
35 #define SSP_BRANCH_CLOCK_OFFSET 0x700
36
37 #define IOCONFIG_BASE_HIGH 0x4008
38 #define IOCONFIG_BASE_LOW 0x6000
39 #define IOCONFIG_SCK_OFFSET 0x18c
40 #define IOCONFIG_HOLD_OFFSET 0x190
41 #define IOCONFIG_WP_OFFSET 0x194
42 #define IOCONFIG_MISO_OFFSET 0x198
43 #define IOCONFIG_MOSI_OFFSET 0x19c
44 #define IOCONFIG_CS_OFFSET 0x1a0
45
46 #define IO_BASE_HIGH 0x400f
47 #define IO_BASE_LOW 0x4000
48 #define IO_CS_OFFSET 0xab
49 #define IODIR_BASE_HIGH 0x400f
50 #define IODIR_BASE_LOW 0x6000
51 #define IO_CS_DIR_OFFSET 0x14
52
53
54 setup: /* Initialize SSP pins and module */
55 mov.w r10, #IOCONFIG_BASE_LOW
56 movt r10, #IOCONFIG_BASE_HIGH
57 mov.w r8, #0xea
58 str.w r8, [r10, #IOCONFIG_SCK_OFFSET] /* Configure SCK pin function */
59 mov.w r8, #0x40
60 str.w r8, [r10, #IOCONFIG_HOLD_OFFSET] /* Configure /HOLD pin function */
61 mov.w r8, #0x40
62 str.w r8, [r10, #IOCONFIG_WP_OFFSET] /* Configure /WP pin function */
63 mov.w r8, #0xed
64 str.w r8, [r10, #IOCONFIG_MISO_OFFSET] /* Configure MISO pin function */
65 mov.w r8, #0xed
66 str.w r8, [r10, #IOCONFIG_MOSI_OFFSET] /* Configure MOSI pin function */
67 mov.w r8, #0x44
68 str.w r8, [r10, #IOCONFIG_CS_OFFSET] /* Configure CS pin function */
69
70 mov.w r10, #IODIR_BASE_LOW
71 movt r10, #IODIR_BASE_HIGH
72 mov.w r8, #0x800
73 str r8, [r10, #IO_CS_DIR_OFFSET] /* Set CS as output */
74 mov.w r10, #IO_BASE_LOW
75 movt r10, #IO_BASE_HIGH
76 mov.w r8, #0xff
77 str.w r8, [r10, #IO_CS_OFFSET] /* Set CS high */
78
79 mov.w r10, #SSP_CLOCK_BASE_LOW
80 movt r10, #SSP_CLOCK_BASE_HIGH
81 mov.w r8, #0x0000
82 movt r8, #0x0100
83 str.w r8, [r10, #SSP_BASE_CLOCK_OFFSET] /* Configure SSP0 base clock (use 12 MHz IRC) */
84
85 mov.w r10, #SSP_BRANCH_CLOCK_BASE_LOW
86 movt r10, #SSP_BRANCH_CLOCK_BASE_HIGH
87 mov.w r8, #0x01
88 str.w r8, [r10, #SSP_BRANCH_CLOCK_OFFSET] /* Configure (enable) SSP0 branch clock */
89
90 mov.w r10, #SSP_BASE_LOW
91 movt r10, #SSP_BASE_HIGH
92 mov.w r8, #0x07
93 str.w r8, [r10, #SSP_CR0_OFFSET] /* Set clock postscale */
94 mov.w r8, #0x02
95 str.w r8, [r10, #SSP_CPSR_OFFSET] /* Set clock prescale */
96 str.w r8, [r10, #SSP_CR1_OFFSET] /* Enable SSP in SPI mode */
97 write_enable:
98 bl cs_down
99 mov.w r9, #0x06 /* Send the write enable command */
100 bl write_data
101 bl cs_up
102
103 bl cs_down
104 mov.w r9, #0x05 /* Get status register */
105 bl write_data
106 mov.w r9, #0x00 /* Dummy data to clock in status */
107 bl write_data
108 bl cs_up
109
110 tst r9, #0x02 /* If the WE bit isn't set, we have a problem. */
111 beq error
112 erase:
113 bl cs_down
114 mov.w r9, r2 /* Send the erase command */
115 bl write_data
116 write_address:
117 lsr r9, r0, #16 /* Send the current 24-bit write address, MSB first */
118 bl write_data
119 lsr r9, r0, #8
120 bl write_data
121 mov.w r9, r0
122 bl write_data
123 bl cs_up
124 wait_flash_busy: /* Wait for the flash to finish the previous erase */
125 bl cs_down
126 mov.w r9, #0x05 /* Get status register */
127 bl write_data
128 mov.w r9, #0x00 /* Dummy data to clock in status */
129 bl write_data
130 bl cs_up
131 tst r9, #0x01 /* If it isn't done, keep waiting */
132 bne wait_flash_busy
133
134 subs r1, r1, #1 /* decrement count */
135 cbz r1, exit /* Exit if we have written everything */
136 add r0, r3 /* Move the address up by the block size */
137 b write_enable /* Start a new block erase */
138 write_data: /* Send/receive 1 byte of data over SSP */
139 mov.w r10, #SSP_BASE_LOW
140 movt r10, #SSP_BASE_HIGH
141 str.w r9, [r10, #SSP_DATA_OFFSET] /* Write supplied data to the SSP data reg */
142 wait_transmit:
143 ldr r9, [r10, #SSP_SR_OFFSET] /* Check SSP status */
144 tst r9, #0x0010 /* Check if BSY bit is set */
145 bne wait_transmit /* If still transmitting, keep waiting */
146 ldr r9, [r10, #SSP_DATA_OFFSET] /* Load received data */
147 bx lr /* Exit subroutine */
148 cs_up:
149 mov.w r8, #0xff
150 b cs_write
151 cs_down:
152 mov.w r8, #0x0000
153 cs_write:
154 mov.w r10, #IO_BASE_LOW
155 movt r10, #IO_BASE_HIGH
156 str.w r8, [r10, #IO_CS_OFFSET]
157 bx lr
158 error:
159 movs r0, #0
160 exit:
161 bkpt #0x00
162
163 .end

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)