contrib: replace the GPLv2-or-later license tag
[openocd.git] / contrib / loaders / flash / stmqspi / stmoctospi_read.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4 * Copyright (C) 2019 by Andreas Bolsch *
5 * andreas.bolsch@mni.thm.de *
6 ***************************************************************************/
7
8 .text
9 .syntax unified
10 .cpu cortex-m0
11 .thumb
12 .thumb_func
13
14 /* Params:
15 * r0 - total count (bytes), remaining bytes (out, 0 means successful)
16 * r1 - flash page size
17 * r2 - address offset into flash
18 * r3 - OCTOSPI io_base
19 * r8 - fifo start
20 * r9 - fifo end + 1
21
22 * Clobbered:
23 * r4 - wp
24 * r5 - address of OCTOSPI_DR
25 * r6 - address of OCTOSPI_CCR
26 * r7 - tmp
27 */
28
29 #include "../../../../src/flash/nor/stmqspi.h"
30
31 #define OCTOSPI_CCR_CCR (OCTOSPI_CCR - OCTOSPI_CCR)
32 #define OCTOSPI_TCR_CCR (OCTOSPI_TCR - OCTOSPI_CCR)
33 #define OCTOSPI_IR_CCR (OCTOSPI_IR - OCTOSPI_CCR)
34
35 .macro octospi_abort
36 movs r5, #(1<<SPI_ABORT) /* abort bit mask */
37 ldr r7, [r3, #OCTOSPI_CR] /* get OCTOSPI CR register */
38 orrs r7, r7, r5 /* set abort bit */
39 str r7, [r3, #OCTOSPI_CR] /* store new CR register */
40 .endm
41
42 .macro wait_busy
43 0:
44 ldr r7, [r3, #OCTOSPI_SR] /* load status */
45 lsrs r7, r7, #(SPI_BUSY+1) /* shift BUSY into C */
46 bcs 0b /* loop until BUSY cleared */
47 movs r7, #(1<<SPI_TCF) /* TCF bitmask */
48 str r7, [r3, #OCTOSPI_FCR] /* clear TCF flag */
49 .endm
50
51 start:
52 subs r0, r0, #1 /* decrement count for DLR */
53 subs r1, r1, #1 /* page size mask and for DLR */
54 ldr r4, wp /* load wp */
55 start_read:
56 octospi_abort /* start in clean state */
57 movs r5, #OCTOSPI_DR /* load OCTOSPI_DR address offset */
58 adds r5, r5, r3 /* address of OCTOSPI_DR */
59 movs r6, #OCTOSPI_CCR-OCTOSPI_DR /* load OCTOSPI_CCR address offset */
60 adds r6, r6, r5 /* address of OCTOSPI_CCR */
61 wait_busy
62 ldr r7, cr_page_read /* indirect read mode */
63 str r7, [r3, #OCTOSPI_CR] /* set mode */
64 mov r7, r2 /* get current start address */
65 orrs r7, r7, r1 /* end of current page */
66 subs r7, r7, r2 /* count-1 to end of page */
67 cmp r7, r0 /* if this count <= remaining */
68 bls write_dlr /* then write to end of page */
69 mov r7, r0 /* else write all remaining */
70 write_dlr:
71 str r7, [r3, #OCTOSPI_DLR] /* size-1 in DLR register */
72 ldr r7, ccr_page_read /* CCR for read */
73 str r7, [r6, #OCTOSPI_CCR_CCR] /* initiate transfer */
74 ldr r7, tcr_page_read /* TCR for read */
75 str r7, [r6, #OCTOSPI_TCR_CCR] /* instruction */
76 ldr r7, ir_page_read /* IR for read */
77 str r7, [r6, #OCTOSPI_IR_CCR] /* instruction */
78 str r2, [r3, #OCTOSPI_AR] /* store SPI start address */
79 read_loop:
80 ldrb r7, [r5] /* read next byte from DR */
81 strb r7, [r4, #0] /* write next byte */
82 adds r4, r4, #1 /* increment internal wp */
83 cmp r4, r9 /* internal wp beyond end? */
84 blo wait_fifo /* if no, then ok */
85 mov r4, r8 /* else wrap around */
86 wait_fifo:
87 ldr r7, rp /* get rp */
88 cmp r7, #0 /* if rp equals 0 */
89 beq exit /* then abort */
90 cmp r4, r7 /* check if fifo full */
91 beq wait_fifo /* wait until not full */
92 adr r7, wp /* get address of wp */
93 str r4, [r7] /* store updated wp */
94 adds r2, r2, #1 /* increment address */
95 subs r0, r0, #1 /* decrement (count-1) */
96 bmi exit /* stop if no data left */
97 tst r2, r1 /* page end ? */
98 bne read_loop /* if not, then next byte */
99 page_end:
100 bal start_read /* then next page */
101
102 exit:
103 adds r0, r0, #1 /* increment count due to the -1 */
104 octospi_abort /* to idle state */
105
106 .align 2 /* align to word, bkpt is 4 words */
107 bkpt #0 /* before code end for exit_point */
108 .align 2 /* align to word */
109
110 .space 4 /* not used */
111 .space 4 /* not used */
112 .space 4 /* not used */
113 .space 4 /* not used */
114
115 .space 4 /* not used */
116 .space 4 /* not used */
117 .space 4 /* not used */
118 .space 4 /* not used */
119
120 cr_page_read:
121 .space 4 /* OCTOSPI_CR value for read command */
122 ccr_page_read:
123 .space 4 /* OCTOSPI_CCR value for read command */
124 tcr_page_read:
125 .space 4 /* OCTOSPI_TCR value for read command */
126 ir_page_read:
127 .space 4 /* OCTOSPI_IR value for read command */
128
129 .equ wp, . /* wp, uint32_t */
130 .equ rp, wp + 4 /* rp, uint32_t */
131 .equ buffer, rp + 4 /* buffer follows right away */

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)