d011103a2f31b874c389a44816e37222b6e35977
[fw/openocd] / contrib / loaders / flash / stmqspi / stmqspi_erase_check.S
1 /***************************************************************************
2  *   Copyright (C) 2019 by Andreas Bolsch                                  *
3  *   andreas.bolsch@mni.thm.de                                             *
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, see <http://www.gnu.org/licenses/>. *
17  ***************************************************************************/
18
19         .text
20         .syntax unified
21         .cpu cortex-m0
22         .thumb
23         .thumb_func
24
25 /* Params:
26  * r0 - sector count
27  * r1 - QSPI io_base
28
29  * Clobbered:
30  * r2 - r7 tmp */
31
32 #include "../../../../src/flash/nor/stmqspi.h"
33
34         .macro  qspi_abort
35         movs    r4, #(1<<SPI_ABORT)                     /* abort bit mask */
36         ldr             r7, [r1, #QSPI_CR]                      /* get QSPI_CR register */
37         orrs    r7, r7, r4                                      /* set abort bit */
38         str             r7, [r1, #QSPI_CR]                      /* store new CR register */
39         .endm
40
41         .macro  wait_busy
42 0:
43         ldr             r7, [r1, #QSPI_SR]                      /* load status */
44         lsrs    r7, r7, #(SPI_BUSY+1)           /* shift BUSY into C */
45         bcs             0b                                                      /* loop until BUSY cleared */
46         movs    r7, #(1<<SPI_TCF)                       /* TCF bitmask */
47         str             r7, [r1, #QSPI_FCR]                     /* clear TCF flag */
48         .endm
49
50 start:
51         adr             r2, buffer                                      /* pointer to start of buffer */
52         movs    r3, #QSPI_DR                            /* load QSPI_DR address offset */
53         add             r3, r3, r1                                      /* address of QSPI_DR */
54 sector_start:
55         qspi_abort                                                      /* start in clean state */
56         ldmia   r2!, {r4, r5, r6}                       /* load address offset, length, initial value */
57         subs    r2, r2, #8                                      /* point to length */
58         subs    r5, r5, #1                                      /* decrement sector length for DLR */
59         wait_busy
60         str             r5, [r1, #QSPI_DLR]                     /* size-1 in DLR register */
61         ldr             r7, ccr_page_read                       /* CCR for page read */
62         str             r7, [r1, #QSPI_CCR]                     /* initiate transfer */
63         str             r4, [r1, #QSPI_AR]                      /* store SPI start address */
64         ldr             r7, [r1, #QSPI_SR]                      /* wait for command startup */
65 read_loop:
66         ldrb    r4, [r3]                                        /* read next byte from DR */
67         movs    r7, #0xFF                                       /* fill bits 8-15 */
68         lsls    r7, r7, #8                                      /* with ones */
69         orrs    r4, r4, r7                                      /* copy ones to left of read byte */
70         ands    r6, r6, r4                                      /* and read byte to result */
71         lsls    r4, r4, #8                                      /* shift result into higher byte */
72         orrs    r6, r6, r4                                      /* or read byte to result */
73         subs    r5, r5, #1                                      /* decrement byte (count-1) */
74         bpl             read_loop                                       /* again if sector not completed */
75         adds    r5, r5, #1                                      /* increment count due to the -1 */
76         stmia   r2!, {r5, r6}                           /* save final count and result for sector */
77         subs    r0, r0, #1                                      /* decrement sector count */
78         bne             sector_start                            /* next sector? */
79         qspi_abort                                                      /* to idle state */
80         .align  2                                                       /* align to word, bkpt is 4 words */
81         bkpt    #0                                                      /* before code end for exit_point */
82         .align  2                                                       /* align to word */
83
84         .space  4                                                       /* not used */
85 ccr_page_read:
86         .space  4                                                       /* QSPI_CCR value for read command */
87         .space  4                                                       /* not used */
88         .space  4                                                       /* not used */
89
90         .equ buffer, .
91