BlinkPIC32

blink.S

0:47e3885a4c3a
2018-10-15 Paul Boddie A simple LED-blinking demonstration for MIPS-based PIC32 microcontrollers.
     1 /*     2  * Blink LEDs using a PIC32 microcontroller.     3  *     4  * Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>     5  *     6  * This program is free software: you can redistribute it and/or modify     7  * it under the terms of the GNU General Public License as published by     8  * the Free Software Foundation, either version 3 of the License, or     9  * (at your option) any later version.    10  *    11  * This program is distributed in the hope that it will be useful,    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    14  * GNU General Public License for more details.    15  *    16  * You should have received a copy of the GNU General Public License    17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.    18  */    19     20 #include "mips.h"    21 #include "pic32.h"    22     23 /* Disable JTAG functionality on pins. */    24     25 .section .devcfg0, "a"    26 .word 0xfffffffb	/* DEVCFG0<2> = JTAGEN = 0 */    27     28 /*    29 Set the oscillator to be the FRC oscillator with PLL, with peripheral clock    30 divided by 2, and FRCDIV+PLL selected.    31     32 The watchdog timer (FWDTEN) is also disabled.    33     34 The secondary oscillator pin (FSOSCEN) is disabled to avoid pin conflicts with    35 RPB4.    36 */    37     38 .section .devcfg1, "a"    39 .word 0xff7fdfd9	/* DEVCFG1<23> = FWDTEN = 0; DEVCFG1<13:12> = FPBDIV<1:0> = 1;    40 			DEVCFG1<5> = FSOSCEN = 0; DEVCFG1<2:0> = FNOSC<2:0> = 001 */    41     42 /*    43 Set the FRC oscillator PLL function with an input division of 4, an output    44 division of 2, a multiplication of 24, yielding a multiplication of 3.    45     46 The FRC is apparently at 16MHz and this produces a system clock of 48MHz.    47 */    48     49 .section .devcfg2, "a"    50 .word 0xfff9fffb	/* DEVCFG2<18:16> = FPLLODIV<2:0> = 001;    51 			DEVCFG2<6:4> = FPLLMUL<2:0> = 111;    52 			DEVCFG2<2:0> = FPLLIDIV<2:0> = 011 */    53     54 .text    55 .globl _start    56     57 _start:    58 	/* Set pins for output. */    59     60 	jal init_pins    61 	nop    62     63 	/* Clear output (LED). */    64     65 	la $t0, PORTA    66 	li $t1, (1 << 3)	/* PORTA<3> = RA3 */    67 	sw $t1, CLR($t0)    68     69 	/* Main program. */    70 main:    71 	li $a1, (3 << 24)	/* counter ~= 50000000 */    72     73 	/* Monitoring loop. */    74 loop:    75 	addiu $a1, $a1, -1	/* counter -= 1 */    76 	bnez $a1, loop    77 	nop    78     79 	/* Invert output (LED). */    80     81 	la $t0, PORTA    82 	li $t1, (1 << 3)	/* PORTA<3> = RA3 */    83 	sw $t1, INV($t0)    84     85 	j main    86 	nop    87     88     89     90 init_pins:    91 	/* DEVCFG0<2> needs setting to 0 before the program is run. */    92     93 	la $v0, CFGCON    94 	li $v1, (1 << 3)	/* CFGCON<3> = JTAGEN = 0 */    95 	sw $v1, CLR($v0)    96     97 init_outputs:    98 	/* Remove analogue features from pins. */    99    100 	la $v0, ANSELA   101 	sw $zero, 0($v0)	/* ANSELA = 0 */   102 	la $v0, ANSELB   103 	sw $zero, 0($v0)	/* ANSELB = 0 */   104    105 	la $v0, TRISA   106 	sw $zero, 0($v0)   107 	la $v0, TRISB   108 	sw $zero, 0($v0)   109    110 	la $v0, PORTA   111 	sw $zero, 0($v0)   112 	la $v0, PORTB   113 	sw $zero, 0($v0)   114    115 	jr $ra   116 	nop