]> git.sur5r.net Git - openocd/blobdiff - contrib/loaders/flash/cc3220sf/cc3220sf.s
flash/nor: Add support for TI CC3220SF internal flash
[openocd] / contrib / loaders / flash / cc3220sf / cc3220sf.s
diff --git a/contrib/loaders/flash/cc3220sf/cc3220sf.s b/contrib/loaders/flash/cc3220sf/cc3220sf.s
new file mode 100644 (file)
index 0000000..cffcfa0
--- /dev/null
@@ -0,0 +1,93 @@
+/***************************************************************************
+ *   Copyright (C) 2017 by Texas Instruments, Inc.                         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+       /* Params:
+        * r0 = buffer start address (in)
+        * r1 = flash destination address (in)
+        * r2 = number of words to write (in/out)
+        */
+
+       .text
+       .cpu cortex-m4
+       .code 16
+       .thumb
+       .syntax unified
+
+       .align 2
+
+       /* r3 = scratchpad
+        * r4 = buffer word counter
+        * r10 = flash programming key
+        * r11 = base FWB address
+        * r12 = base flash regs address
+        */
+
+start:
+       ldr     r10, =0xa4420001        /* flash programming key */
+       ldr     r11, =0x400fd100        /* base of FWB */
+       ldr     r12, =0x400fd000        /* base of flash regs */
+       and     r3, r1, #0x7f           /* is the dest address 32 word aligned? */
+       cmp     r3, #0
+       bne     program_word            /* if not aligned do one word at a time */
+
+       /* program using the write buffers */
+program_buffer:
+       mov     r4, #0                          /* start the buffer word counter at 0 */
+       str     r1, [r12]                       /* store the dest addr in FMA */
+fill_buffer:
+       ldr     r3, [r0]                        /* get the word to write to FWB */
+       str     r3, [r11]                       /* store the word in the FWB */
+       add     r11, r11, #4            /* increment the FWB pointer */
+       add     r0, r0, #4                      /* increment the source pointer */
+       sub     r2, r2, #1                      /* decrement the total word counter */
+       add     r4, r4, #1                      /* increment the buffer word counter */
+       add     r1, r1, #4                      /* increment the dest pointer */
+       cmp     r2, #0                          /* is the total word counter now 0? */
+       beq     buffer_ready            /* go to end if total word counter is 0 */
+       cmp     r4, #32                         /* is the buffer word counter now 32? */
+       bne     fill_buffer                     /* go to continue to fill buffer */
+buffer_ready:
+       str     r10, [r12, #0x20]       /* store the key and write bit to FMC2 */
+wait_buffer_done:
+       ldr     r3, [r12, #0x20]        /* read FMC2 */
+       tst     r3, #1                          /* see if the write bit is cleared */
+       bne     wait_buffer_done        /* go to read FMC2 if bit not cleared */
+       cmp     r2, #0                          /* is the total word counter now 0? */
+       bne     start                           /* go if there is more to program */
+       b       exit
+
+       /* program just one word */
+program_word:
+       str     r1, [r12]                       /* store the dest addr in FMA */
+       ldr     r3, [r0]                        /* get the word to write to FMD */
+       str     r3, [r12, #0x4]         /* store the word in FMD */
+       str     r10, [r12, #0x8]        /* store the key and write bit to FMC */
+wait_word_done:
+       ldr     r3, [r12, #0x8]         /* read FMC */
+       tst     r3, #1                          /* see if the write bit is cleared */
+       bne     wait_word_done          /* go to read FMC if bit not cleared */
+       sub     r2, r2, #1                      /* decrement the total word counter */
+       add     r0, r0, #4                      /* increment the source pointer */
+       add     r1, r1, #4                      /* increment the dest pointer */
+       cmp     r2, #0                          /* is the total word counter now 0 */
+       bne     start                           /* go if there is more to program */
+
+       /* end */
+exit:
+       bkpt    #0
+       bkpt    #1
+       b       exit