summaryrefslogtreecommitdiff
path: root/contrib/loaders/flash/pic32mx.s
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/loaders/flash/pic32mx.s')
-rw-r--r--contrib/loaders/flash/pic32mx.s131
1 files changed, 131 insertions, 0 deletions
diff --git a/contrib/loaders/flash/pic32mx.s b/contrib/loaders/flash/pic32mx.s
new file mode 100644
index 00000000..b26ff611
--- /dev/null
+++ b/contrib/loaders/flash/pic32mx.s
@@ -0,0 +1,131 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+ .text
+ .set noreorder
+ .set noat
+
+/* params:
+ * $a0 src adr - ram + result
+ * $a1 dest adr - flash
+ * $a2 count (32bit words)
+ * vars
+ *
+ * temps:
+ * $t0, $t1, $t2, $t3, $t4, $t5
+ * $s0, $s1, $s3, $s4, $s5
+ */
+
+ .type main, @function
+ .global main
+
+.ent main
+main:
+ /* setup constants */
+ lui $t0, 0xaa99
+ ori $t0, 0x6655 /* NVMKEY1 */
+ lui $t1, 0x5566
+ ori $t1, 0x99AA /* NVMKEY2 */
+ lui $t2, 0xBF80
+ ori $t2, 0xF400 /* NVMCON */
+ ori $t3, $zero, 0x4003 /* NVMCON row write cmd */
+ ori $t4, $zero, 0x8000 /* NVMCON start cmd */
+
+write_row:
+ /* can we perform a row write: 128 32bit words */
+ sltiu $s3, $a2, 128
+ bne $s3, $zero, write_word
+ ori $t5, $zero, 0x4000 /* NVMCON clear cmd */
+
+ /* perform row write 512 bytes */
+ sw $a1, 32($t2) /* set NVMADDR with dest addr - real addr */
+ sw $a0, 64($t2) /* set NVMSRCADDR with src addr - real addr */
+
+ bal progflash
+ addiu $a0, $a0, 512
+ addiu $a1, $a1, 512
+ beq $zero, $zero, write_row
+ addiu $a2, $a2, -128
+
+write_word:
+ /* write 32bit words */
+ lui $s5, 0xa000
+ ori $s5, 0x0000
+ or $a0, $a0, $s5 /* convert to virtual addr */
+
+ beq $zero, $zero, next_word
+ ori $t3, $zero, 0x4001 /* NVMCON word write cmd */
+
+prog_word:
+ lw $s4, 0($a0) /* load data - from virtual addr */
+ sw $s4, 48($t2) /* set NVMDATA with data */
+ sw $a1, 32($t2) /* set NVMADDR with dest addr - real addr */
+
+ bal progflash
+ addiu $a0, $a0, 4
+ addiu $a1, $a1, 4
+ addiu $a2, $a2, -1
+next_word:
+ bne $a2, $zero, prog_word
+ nop
+
+done:
+ beq $zero, $zero, exit
+ addiu $a0, $zero, 0
+
+error:
+ /* save result to $a0 */
+ addiu $a0, $s1, 0
+
+exit:
+ sdbbp
+.end main
+
+ .type progflash, @function
+ .global progflash
+
+.ent progflash
+progflash:
+ sw $t3, 0($t2) /* set NVMWREN */
+ sw $t0, 16($t2) /* write NVMKEY1 */
+ sw $t1, 16($t2) /* write NVMKEY2 */
+ sw $t4, 8($t2) /* start operation */
+
+waitflash:
+ lw $s0, 0($t2)
+ and $s0, $s0, $t4
+ bne $s0, $zero, waitflash
+ nop
+
+ /* following is to comply with errata #34
+ * 500ns delay required */
+ nop
+ nop
+ nop
+ nop
+ /* check for errors */
+ lw $s1, 0($t2)
+ andi $s1, $zero, 0x3000
+ bne $s1, $zero, error
+ sw $t5, 4($t2) /* clear NVMWREN */
+ jr $ra
+ nop
+
+.end progflash