BlinkPIC32

blink.S

2:ce5a30648166
2018-10-17 Paul Boddie Adopted a more explicit program section positioning scheme.
     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 The peripheral clock frequency (FPB) will be 24MHz given the above DEVCFG1    49 settings.    50 */    51     52 .section .devcfg2, "a"    53 .word 0xfff9fffb	/* DEVCFG2<18:16> = FPLLODIV<2:0> = 001;    54 			DEVCFG2<6:4> = FPLLMUL<2:0> = 111;    55 			DEVCFG2<2:0> = FPLLIDIV<2:0> = 011 */    56     57 /* The start routine is placed at the boot location. */    58     59 .section .boot, "a"    60     61 .globl _start    62     63 _start:    64 	/* Set pins for output. */    65     66 	jal init_pins    67 	nop    68     69 	/* Clear output (LED). */    70     71 	la $t0, PORTA    72 	li $t1, (1 << 3)	/* PORTA<3> = RA3 */    73 	sw $t1, CLR($t0)    74     75 	/* Main program. */    76 main:    77 	li $a1, (3 << 24)	/* counter ~= 50000000 */    78     79 	/* Monitoring loop. */    80 loop:    81 	addiu $a1, $a1, -1	/* counter -= 1 */    82 	bnez $a1, loop    83 	nop    84     85 	/* Invert output (LED). */    86     87 	la $t0, PORTA    88 	li $t1, (1 << 3)	/* PORTA<3> = RA3 */    89 	sw $t1, INV($t0)    90     91 	j main    92 	nop    93     94     95     96 init_pins:    97 	/* DEVCFG0<2> needs setting to 0 before the program is run. */    98     99 	la $v0, CFGCON   100 	li $v1, (1 << 3)	/* CFGCON<3> = JTAGEN = 0 */   101 	sw $v1, CLR($v0)   102    103 init_outputs:   104 	/* Remove analogue features from pins. */   105    106 	la $v0, ANSELA   107 	sw $zero, 0($v0)	/* ANSELA = 0 */   108 	la $v0, ANSELB   109 	sw $zero, 0($v0)	/* ANSELB = 0 */   110    111 	/* Set pins as outputs. */   112    113 	la $v0, TRISA   114 	sw $zero, 0($v0)   115 	la $v0, TRISB   116 	sw $zero, 0($v0)   117    118 	/* Clear outputs. */   119    120 	la $v0, PORTA   121 	sw $zero, 0($v0)   122 	la $v0, PORTB   123 	sw $zero, 0($v0)   124    125 	jr $ra   126 	nop