flash/nor/stm32lx: fixed writes at high adapter speeds
[fw/openocd] / contrib / loaders / flash / stm32 / stm32lx.S
index bcae7a46cc4b5920dbddc39180d8bb75f1658754..7cfe48545215f4e6728faf43e1999c5c3eb48394 100644 (file)
  *   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, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
  ***************************************************************************/
 
-
        .text
        .syntax unified
        .cpu cortex-m0
        .thumb
 
 /*
+Parameters
        r0 - destination address
        r1 - source address
-       r2 - count
+       r2 - half pages
+       r3 - bytes per half page
+       r4 - flash base
+Variables
+       r0 - destination write pointer
+       r1 - source read pointer
+       r2 - source limit address
+       r3 - bytes per half page
+       r4 - flash base
+       r5 - pages left in current half page
+       r6 - temporary r/w
 */
 
+/* offsets of registers from flash reg base */
+#define STM32_FLASH_SR_OFFSET 0x18
+
        .thumb_func
        .global _start
 _start:
-       // r2 = source + count * 4
-       lsls    r2, r2, #2
-       adds    r2, r1, r2
+       // r2 = source + half pages * bytes per half page
+       muls r2, r2, r3
+       add r2, r1, r2
        // Go to compare
-       b       test_done
+       b test_done
+write_half_page:
+       // initialize pages left in current half page
+       mov r5, r3
 write_word:
        // load word from address in r1 and increase r1 by 4
-       ldmia r1!, {r3}
+       ldmia r1!, {r6}
        // store word to address in r0 and increase r0 by 4
-       stmia r0!, {r3}
+       stmia r0!, {r6}
+       // check for end of half page
+       subs r5, r5, #4
+       bne write_word
+wait_busy:
+       // read status register into r6, loop while bottom bit is set
+       ldr r6, [r4, #STM32_FLASH_SR_OFFSET]
+       lsls r6, r6, #31
+       bne wait_busy
 test_done:
-       // compare r1 and r2
+       // compare r1 and r2, loop if not equal
        cmp     r1, r2
-       // loop if not equal
-       bne     write_word
+       bne     write_half_page
 
        // Set breakpoint to exit
-       bkpt    #0x00
-
+       bkpt #0x00