1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Makefile Tue Oct 16 23:26:17 2018 +0200
1.3 @@ -0,0 +1,75 @@
1.4 +# Makefile - Build the IntCondTest payload
1.5 +#
1.6 +# Copyright (C) 2015, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
1.7 +# Copyright (C) Xiangfu Liu <xiangfu@sharism.cc>
1.8 +#
1.9 +# This program is free software: you can redistribute it and/or modify
1.10 +# it under the terms of the GNU General Public License as published by
1.11 +# the Free Software Foundation, either version 3 of the License, or
1.12 +# (at your option) any later version.
1.13 +#
1.14 +# This program is distributed in the hope that it will be useful,
1.15 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 +# GNU General Public License for more details.
1.18 +#
1.19 +# You should have received a copy of the GNU General Public License
1.20 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
1.21 +
1.22 +ARCH = mipsel-linux-gnu
1.23 +CC = $(ARCH)-gcc
1.24 +LD = $(ARCH)-ld
1.25 +NM = $(ARCH)-nm
1.26 +OBJCOPY=$(ARCH)-objcopy
1.27 +OBJDUMP=$(ARCH)-objdump
1.28 +
1.29 +# NOTE: -O2 is actually needed to prevent memcpy references, whereas probably
1.30 +# NOTE: one of the -f{freestanding, no-hosted, no-builtin} options should work.
1.31 +# NOTE: See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56888
1.32 +
1.33 +CFLAGS = -O2 -Wall \
1.34 + -fno-unit-at-a-time -fno-zero-initialized-in-bss \
1.35 + -ffreestanding -fno-hosted -fno-builtin \
1.36 + -march=mips32
1.37 +LDFLAGS = -nostdlib -EL
1.38 +
1.39 +TARGET = intcond.elf
1.40 +DUMP = $(TARGET:.elf=.dump)
1.41 +MAP = $(TARGET:.elf=.map)
1.42 +SCRIPT = $(TARGET:.elf=.ld)
1.43 +
1.44 +HEX = $(TARGET:.elf=.hex)
1.45 +SREC = $(TARGET:.elf=.srec)
1.46 +
1.47 +# Ordering of objects is important and cannot be left to replacement rules.
1.48 +
1.49 +SRC = intcond.S main.c init.c cpu.S
1.50 +OBJ = intcond.o main.o init.o cpu.o
1.51 +
1.52 +.PHONY: all clean distclean
1.53 +
1.54 +all: $(HEX) $(SREC)
1.55 +
1.56 +clean:
1.57 + rm -f $(OBJ) $(TARGET) $(HEX) $(SREC) $(DUMP) *.map
1.58 +
1.59 +distclean: clean
1.60 + echo "Nothing else to clean."
1.61 +
1.62 +$(HEX): $(TARGET)
1.63 + $(OBJCOPY) -O ihex $(TARGET) $(HEX)
1.64 +
1.65 +$(SREC): $(TARGET)
1.66 + $(OBJCOPY) -O srec $(TARGET) $(SREC)
1.67 +
1.68 +$(TARGET): $(OBJ)
1.69 + $(LD) $(LDFLAGS) -T $(SCRIPT) $(OBJ) -o $@
1.70 + $(OBJDUMP) -D $(TARGET) > $(DUMP)
1.71 + $(OBJDUMP) -h $(TARGET) > $(MAP)
1.72 + $(NM) -n $(TARGET) > System.map
1.73 +
1.74 +.c.o:
1.75 + $(CC) -c $(CFLAGS) $< -o $@
1.76 +
1.77 +.S.o:
1.78 + $(CC) -c $(CFLAGS) $< -o $@
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/cpu.S Tue Oct 16 23:26:17 2018 +0200
2.3 @@ -0,0 +1,172 @@
2.4 +/*
2.5 + * PIC32 microcontroller interrupt handling code.
2.6 + *
2.7 + * Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
2.8 + *
2.9 + * This program is free software: you can redistribute it and/or modify
2.10 + * it under the terms of the GNU General Public License as published by
2.11 + * the Free Software Foundation, either version 3 of the License, or
2.12 + * (at your option) any later version.
2.13 + *
2.14 + * This program is distributed in the hope that it will be useful,
2.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.17 + * GNU General Public License for more details.
2.18 + *
2.19 + * You should have received a copy of the GNU General Public License
2.20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
2.21 + */
2.22 +
2.23 +#include "mips.h"
2.24 +#include "pic32.h"
2.25 +#include "cpu.h"
2.26 +
2.27 +.globl enable_interrupts
2.28 +.globl handle_error_level
2.29 +.globl init_interrupts
2.30 +.extern exception_handler
2.31 +.extern interrupt_handler
2.32 +
2.33 +/* Put general routines in the text section. */
2.34 +
2.35 +.text
2.36 +
2.37 +/*
2.38 +Clear the error and exception status flags, making interrupts and exceptions
2.39 +possible.
2.40 +*/
2.41 +
2.42 +handle_error_level:
2.43 + mfc0 $t3, CP0_STATUS
2.44 +
2.45 + /* Clear error level and exception level. */
2.46 +
2.47 + li $t4, ~(STATUS_ERL | STATUS_EXL)
2.48 + and $t3, $t3, $t4
2.49 + mtc0 $t3, CP0_STATUS
2.50 +
2.51 + jr $ra
2.52 + nop
2.53 +
2.54 +/* Enable interrupts and direct interrupt requests to non-bootloader vectors. */
2.55 +
2.56 +enable_interrupts:
2.57 + mfc0 $t3, CP0_STATUS
2.58 +
2.59 + /* Clear interrupt priority bits. */
2.60 +
2.61 + li $t4, ~STATUS_IRQ
2.62 + and $t3, $t3, $t4
2.63 +
2.64 + /* Set interrupt priority. */
2.65 +
2.66 + ori $t3, $t3, (CPU_INT_PRIORITY << STATUS_IRQ_SHIFT)
2.67 +
2.68 + /* CP0_STATUS &= ~STATUS_BEV (use non-bootloader vectors) */
2.69 +
2.70 + li $t4, ~STATUS_BEV
2.71 + and $t3, $t3, $t4
2.72 +
2.73 + /* Enable interrupts. */
2.74 +
2.75 + ori $t3, $t3, STATUS_IE
2.76 + mtc0 $t3, CP0_STATUS
2.77 +
2.78 + jr $ra
2.79 + nop
2.80 +
2.81 +/* Initialise the interrupt system parameters. */
2.82 +
2.83 +init_interrupts:
2.84 + /* Clear debug mode. */
2.85 +
2.86 + mfc0 $t3, CP0_DEBUG
2.87 + li $t4, ~DEBUG_DM
2.88 + and $t3, $t3, $t4
2.89 + mtc0 $t3, CP0_DEBUG
2.90 +
2.91 + /* Update the exception base. */
2.92 +
2.93 + mfc0 $t3, CP0_STATUS
2.94 + li $t4, STATUS_BEV /* BEV = 1 or EBASE cannot be set */
2.95 + or $t3, $t3, $t4
2.96 + mtc0 $t3, CP0_STATUS
2.97 +
2.98 + la $t3, ebase
2.99 + mtc0 $t3, CP0_EBASE
2.100 +
2.101 + /* Set vector spacing. */
2.102 +
2.103 + li $t3, 0x20 /* Must be non-zero or the CPU gets upset */
2.104 + mtc0 $t3, CP0_INTCTL
2.105 +
2.106 + li $t3, CAUSE_IV /* IV = 1 (use EBASE+0x200 for interrupts) */
2.107 + mtc0 $t3, CP0_CAUSE
2.108 +
2.109 + jr $ra
2.110 + nop
2.111 +
2.112 +
2.113 +
2.114 +/* Exception servicing, positioned at EBASE at the start of program memory. */
2.115 +
2.116 +.section .vectors, "a"
2.117 +
2.118 +/* TLB error servicing. */
2.119 +
2.120 +ebase:
2.121 +tlb_handler:
2.122 + j exception_handler
2.123 + nop
2.124 +
2.125 +
2.126 +
2.127 +/* General exception servicing. */
2.128 +
2.129 +.org 0x180
2.130 +
2.131 +exc_handler:
2.132 + j exception_handler
2.133 + nop
2.134 +
2.135 +
2.136 +
2.137 +/* Interrupt servicing. */
2.138 +
2.139 +.org 0x200
2.140 +.set noat
2.141 +
2.142 +#define IRQ_STACK_LIMIT (KSEG0_BASE + 256)
2.143 +#define IRQ_STACK_TOP (IRQ_STACK_LIMIT - 32 * 4)
2.144 +
2.145 +int_handler:
2.146 +
2.147 + /* Store affected registers from IRQ_STACK_LIMIT - 4 downwards. */
2.148 +
2.149 + li $k0, IRQ_STACK_LIMIT
2.150 +
2.151 + .irp reg, \
2.152 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 \
2.153 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, \
2.154 + 28, 29, 30, 31
2.155 + sw $\reg, -(\reg * 4)($k0)
2.156 + .endr
2.157 +
2.158 + /* Switch to the IRQ stack. */
2.159 +
2.160 + li $sp, IRQ_STACK_TOP
2.161 +
2.162 + jal interrupt_handler
2.163 + nop
2.164 +
2.165 + /* Restore affected registers. */
2.166 +
2.167 + .irp reg, \
2.168 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 \
2.169 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, \
2.170 + 28, 29, 30, 31
2.171 + lw $\reg, -(\reg * 4)($k0)
2.172 + .endr
2.173 +
2.174 + eret
2.175 + nop
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/cpu.h Tue Oct 16 23:26:17 2018 +0200
3.3 @@ -0,0 +1,16 @@
3.4 +#ifndef __CPU_H__
3.5 +#define __CPU_H__
3.6 +
3.7 +#define CPU_INT_PRIORITY 3
3.8 +
3.9 +#ifndef __ASSEMBLER__
3.10 +
3.11 +/* Specific operations. */
3.12 +
3.13 +void enable_interrupts(void);
3.14 +void handle_error_level(void);
3.15 +void init_interrupts(void);
3.16 +
3.17 +#endif /* __ASSEMBLER__ */
3.18 +
3.19 +#endif /* __CPU_H__ */
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/init.c Tue Oct 16 23:26:17 2018 +0200
4.3 @@ -0,0 +1,126 @@
4.4 +#include "cpu.h"
4.5 +#include "pic32_c.h"
4.6 +
4.7 +
4.8 +
4.9 +/* Basic memory and pin initialisation. */
4.10 +
4.11 +void init_memory(void)
4.12 +{
4.13 + /*
4.14 + Configure RAM.
4.15 + See: http://microchipdeveloper.com/32bit:mx-arch-exceptions-processor-initialization
4.16 + */
4.17 +
4.18 + uint32_t config = REG(BMXCON);
4.19 +
4.20 + /* Set zero wait states for address setup. */
4.21 +
4.22 + config &= ~(1 << 6); /* BMXCON<6> = BMXWSDRM = 0 */
4.23 +
4.24 + /* Set bus arbitration mode. */
4.25 +
4.26 + config &= ~0b111;
4.27 + config |= 0b010; /* BMXCON<2:0> = BMXARB<2:0> = 2 */
4.28 +
4.29 + REG(BMXCON) = config;
4.30 +}
4.31 +
4.32 +void init_pins(void)
4.33 +{
4.34 + /* DEVCFG0<2> also needs setting to 0 before the program is run. */
4.35 +
4.36 + CLR_REG(CFGCON, 1 << 3); /* CFGCON<3> = JTAGEN = 0 */
4.37 +}
4.38 +
4.39 +void init_outputs(void)
4.40 +{
4.41 + /* Remove analogue features from pins. */
4.42 +
4.43 + REG(ANSELA) = 0;
4.44 + REG(ANSELB) = 0;
4.45 +
4.46 + REG(TRISA) = 0;
4.47 + REG(TRISB) = 0;
4.48 +
4.49 + REG(PORTA) = 0;
4.50 + REG(PORTB) = 0;
4.51 +}
4.52 +
4.53 +
4.54 +
4.55 +/* Peripheral pin configuration. */
4.56 +
4.57 +void config_uart(void)
4.58 +{
4.59 + /* Map U1RX to RPB13. */
4.60 +
4.61 + REG(U1RXR) = 0b0011; /* U1RXR<3:0> = 0011 (RPB13) */
4.62 +
4.63 + /* Map U1TX to RPB15. */
4.64 +
4.65 + REG(RPB15R) = 0b0001; /* RPB15R<3:0> = 0001 (U1TX) */
4.66 +
4.67 + /* Set RPB13 to input. */
4.68 +
4.69 + SET_REG(TRISB, 1 << 13);
4.70 +}
4.71 +
4.72 +void lock_config(void)
4.73 +{
4.74 + SET_REG(CFGCON, 1 << 13); /* IOLOCK = 1 */
4.75 +
4.76 + /* Lock the configuration again. */
4.77 +
4.78 + REG(SYSKEY) = 0x33333333;
4.79 +}
4.80 +
4.81 +void unlock_config(void)
4.82 +{
4.83 + /* Unlock the configuration register bits. */
4.84 +
4.85 + REG(SYSKEY) = 0;
4.86 + REG(SYSKEY) = 0xAA996655;
4.87 + REG(SYSKEY) = 0x556699AA;
4.88 +
4.89 + CLR_REG(CFGCON, 1 << 13); /* IOLOCK = 0 */
4.90 +}
4.91 +
4.92 +
4.93 +
4.94 +/* Convenience operations. */
4.95 +
4.96 +void interrupts_on(void)
4.97 +{
4.98 + init_interrupts();
4.99 + enable_interrupts();
4.100 + handle_error_level();
4.101 +}
4.102 +
4.103 +
4.104 +
4.105 +/* Peripheral configuration. */
4.106 +
4.107 +void init_uart(uint8_t pri, uint8_t sub)
4.108 +{
4.109 + CLR_REG(U1MODE, 1 << 15); /* U1MODE<15> = ON = 0 */
4.110 + REG(U1BRG) = 12; /* U1BRG<15:0> = BRG = (FPB / (16 * baudrate)) - 1 = (24000000 / (16 * 115200)) - 1 = 12 */
4.111 +
4.112 + /* Disable interrupt and clear flag. */
4.113 +
4.114 + CLR_REG(IEC1, 1 << 8); /* IEC1<8> = U1RIE = 0 */
4.115 + CLR_REG(IFS1, 1 << 8); /* IFS1<8> = U1RIF = 0 */
4.116 +
4.117 + /* Set priorities: U1IP = pri; U1IS = sub */
4.118 +
4.119 + REG(IPC8) = (REG(IPC8) & ~0b11111) | ((pri & 0b111) << 2) | (sub & 0b11);
4.120 +
4.121 + /* Enable interrupt. */
4.122 +
4.123 + SET_REG(IEC1, 1 << 8); /* IEC1<8> = U1RIE = 1 */
4.124 +
4.125 + /* Start UART. */
4.126 +
4.127 + SET_REG(U1STA, (1 << 12) | (1 << 10)); /* U1STA<12> = URXEN = 1; U1STA<10> = UTXEN = 1 */
4.128 + SET_REG(U1MODE, 1 << 15); /* U1MODE<15> = ON = 1 */
4.129 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/init.h Tue Oct 16 23:26:17 2018 +0200
5.3 @@ -0,0 +1,24 @@
5.4 +#ifndef __INIT_H__
5.5 +#define __INIT_H__
5.6 +
5.7 +/* Basic initialisation. */
5.8 +
5.9 +void init_memory(void);
5.10 +void init_pins(void);
5.11 +void init_outputs(void);
5.12 +
5.13 +/* Peripheral pin configuration. */
5.14 +
5.15 +void config_uart(void);
5.16 +void lock_config(void);
5.17 +void unlock_config(void);
5.18 +
5.19 +/* Convenience operations. */
5.20 +
5.21 +void interrupts_on(void);
5.22 +
5.23 +/* Peripheral configuration. */
5.24 +
5.25 +void init_uart(uint8_t pri, uint8_t sub);
5.26 +
5.27 +#endif /* __INIT_H__ */
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/intcond.S Tue Oct 16 23:26:17 2018 +0200
6.3 @@ -0,0 +1,95 @@
6.4 +/*
6.5 + * PIC32 microcontroller initialisation code.
6.6 + *
6.7 + * Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
6.8 + *
6.9 + * This program is free software: you can redistribute it and/or modify
6.10 + * it under the terms of the GNU General Public License as published by
6.11 + * the Free Software Foundation, either version 3 of the License, or
6.12 + * (at your option) any later version.
6.13 + *
6.14 + * This program is distributed in the hope that it will be useful,
6.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.17 + * GNU General Public License for more details.
6.18 + *
6.19 + * You should have received a copy of the GNU General Public License
6.20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6.21 + */
6.22 +
6.23 +#include "mips.h"
6.24 +#include "pic32.h"
6.25 +
6.26 +/* Disable JTAG functionality on pins. */
6.27 +
6.28 +.section .devcfg0, "a"
6.29 +.word 0xfffffffb /* DEVCFG0<2> = JTAGEN = 0 */
6.30 +
6.31 +/*
6.32 +Set the oscillator to be the FRC oscillator with PLL, with peripheral clock
6.33 +divided by 2, and FRCDIV+PLL selected.
6.34 +
6.35 +The watchdog timer (FWDTEN) is also disabled.
6.36 +
6.37 +The secondary oscillator pin (FSOSCEN) is disabled to avoid pin conflicts with
6.38 +RPB4.
6.39 +*/
6.40 +
6.41 +.section .devcfg1, "a"
6.42 +.word 0xff7fdfd9 /* DEVCFG1<23> = FWDTEN = 0; DEVCFG1<13:12> = FPBDIV<1:0> = 1;
6.43 + DEVCFG1<5> = FSOSCEN = 0; DEVCFG1<2:0> = FNOSC<2:0> = 001 */
6.44 +
6.45 +/*
6.46 +Set the FRC oscillator PLL function with an input division of 4, an output
6.47 +division of 2, a multiplication of 24, yielding a multiplication of 3.
6.48 +
6.49 +The FRC is apparently at 16MHz and this produces a system clock of 48MHz.
6.50 +*/
6.51 +
6.52 +.section .devcfg2, "a"
6.53 +.word 0xfff9fffb /* DEVCFG2<18:16> = FPLLODIV<2:0> = 001;
6.54 + DEVCFG2<6:4> = FPLLMUL<2:0> = 111;
6.55 + DEVCFG2<2:0> = FPLLIDIV<2:0> = 011 */
6.56 +
6.57 +/* The start routine is placed at the boot location. */
6.58 +
6.59 +.section .boot, "a"
6.60 +
6.61 +.globl _start
6.62 +.extern main
6.63 +
6.64 +_start:
6.65 + /* Enable caching. */
6.66 +
6.67 + mfc0 $v1, CP0_CONFIG
6.68 + li $t8, ~CONFIG_K0
6.69 + and $v1, $v1, $t8
6.70 + ori $v1, $v1, CONFIG_K0_CACHABLE_NONCOHERENT
6.71 + mtc0 $v1, CP0_CONFIG
6.72 + nop
6.73 +
6.74 + /* Get the RAM size. */
6.75 +
6.76 + la $v1, BMXDRMSZ
6.77 + lw $t0, 0($v1)
6.78 +
6.79 + /* Initialise the stack pointer. */
6.80 +
6.81 + li $v1, KSEG0_BASE
6.82 + addu $sp, $t0, $v1 /* sp = KSEG0_BASE + RAM size */
6.83 +
6.84 + /* Initialise the globals pointer. */
6.85 +
6.86 + lui $gp, %hi(_GLOBAL_OFFSET_TABLE_)
6.87 + ori $gp, $gp, %lo(_GLOBAL_OFFSET_TABLE_)
6.88 +
6.89 + /*
6.90 + Jump to the main program. Since the boot code is separate from the
6.91 + other code, the address cannot be obtained via the GOT.
6.92 + ("relocation truncated to fit: R_MIPS_PC16 against `main'")
6.93 + */
6.94 +
6.95 + lui $t9, %hi(main)
6.96 + ori $t9, $t9, %lo(main)
6.97 + jr $t9
6.98 + nop
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/intcond.ld Tue Oct 16 23:26:17 2018 +0200
7.3 @@ -0,0 +1,42 @@
7.4 +OUTPUT_ARCH(mips)
7.5 +ENTRY(_start)
7.6 +
7.7 +/* See...
7.8 + * FIGURE 4-5: MEMORY MAP ON RESET FOR PIC32MX170/270 DEVICES (64 KB RAM, 256 KB FLASH)
7.9 + * PIC32MX1XX/2XX 28/36/44-pin Family Data Sheet
7.10 + */
7.11 +
7.12 +MEMORY
7.13 +{
7.14 + kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x10000
7.15 + kseg0_boot_mem (rx) : ORIGIN = 0x9FC00000, LENGTH = 0xBF0
7.16 + kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x40000
7.17 + physical_boot_mem (rx) : ORIGIN = 0x1FC00000, LENGTH = 0xBF0
7.18 + physical_program_mem (rx) : ORIGIN = 0x1D000000, LENGTH = 0x40000
7.19 + sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000
7.20 + configsfrs : ORIGIN = 0xBFC00BF0, LENGTH = 0x10
7.21 + config3 : ORIGIN = 0xBFC00BF0, LENGTH = 0x4
7.22 + config2 : ORIGIN = 0xBFC00BF4, LENGTH = 0x4
7.23 + config1 : ORIGIN = 0xBFC00BF8, LENGTH = 0x4
7.24 + config0 : ORIGIN = 0xBFC00BFC, LENGTH = 0x4
7.25 + physical_config3 : ORIGIN = 0x3FC00BF0, LENGTH = 0x4
7.26 + physical_config2 : ORIGIN = 0x3FC00BF4, LENGTH = 0x4
7.27 + physical_config1 : ORIGIN = 0x3FC00BF8, LENGTH = 0x4
7.28 + physical_config0 : ORIGIN = 0x3FC00BFC, LENGTH = 0x4
7.29 +}
7.30 +
7.31 +SECTIONS
7.32 +{
7.33 + .boot : { *(.boot*) } > kseg0_boot_mem AT > physical_boot_mem
7.34 + .vectors : { *(.vectors*) } > kseg0_program_mem AT > physical_program_mem
7.35 + .text : { *(.text*) } > kseg0_program_mem AT > physical_program_mem
7.36 + .bss : { *(.bss*) } > kseg1_data_mem
7.37 + .got : {
7.38 + _gp = ALIGN(16);
7.39 + *(.got*)
7.40 + } > kseg0_program_mem AT > physical_program_mem
7.41 + .devcfg0 : { *(.devcfg0) } > config0 AT > physical_config0
7.42 + .devcfg1 : { *(.devcfg1) } > config1 AT > physical_config1
7.43 + .devcfg2 : { *(.devcfg2) } > config2 AT > physical_config2
7.44 + /DISCARD/ : { *(.reginfo) *(.MIPS.abiflags) }
7.45 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/main.c Tue Oct 16 23:26:17 2018 +0200
8.3 @@ -0,0 +1,85 @@
8.4 +#include "pic32_c.h"
8.5 +#include "init.h"
8.6 +
8.7 +static void uart_write(char c)
8.8 +{
8.9 + while (REG(U1STA) & (1 << 9)); /* UTXBF (buffer full) */
8.10 +
8.11 + REG(U1TXREG) = c;
8.12 +}
8.13 +
8.14 +static void bits(uint32_t reg)
8.15 +{
8.16 + uint32_t mask;
8.17 +
8.18 + for (mask = (1 << 31); mask; mask >>= 1)
8.19 + if (REG(reg) & mask)
8.20 + uart_write('1');
8.21 + else
8.22 + uart_write('0');
8.23 +
8.24 + uart_write('\r');
8.25 + uart_write('\n');
8.26 +}
8.27 +
8.28 +static void blink(uint32_t delay, uint32_t port, uint32_t pins)
8.29 +{
8.30 + uint32_t counter;
8.31 +
8.32 + /* Clear outputs (LED). */
8.33 +
8.34 + CLR_REG(port, pins);
8.35 +
8.36 + while (1)
8.37 + {
8.38 + counter = delay;
8.39 +
8.40 + while (counter--) __asm__(""); /* retain loop */
8.41 +
8.42 + /* Invert outputs (LED). */
8.43 +
8.44 + INV_REG(port, pins);
8.45 + bits(IFS1);
8.46 + }
8.47 +}
8.48 +
8.49 +void main(void)
8.50 +{
8.51 + init_memory();
8.52 + init_pins();
8.53 + init_outputs();
8.54 +
8.55 + unlock_config();
8.56 + config_uart();
8.57 + lock_config();
8.58 +
8.59 + init_uart(7, 3);
8.60 +
8.61 + interrupts_on();
8.62 +
8.63 + blink(3 << 24, PORTA, 1 << 3);
8.64 +}
8.65 +
8.66 +void exception_handler(void)
8.67 +{
8.68 + blink(3 << 12, PORTA, 1 << 3);
8.69 +}
8.70 +
8.71 +void interrupt_handler(void)
8.72 +{
8.73 + /* Check for a UART receive interrupt condition (U1RIF). */
8.74 +
8.75 + if (!(REG(IFS1) & (1 << 8)))
8.76 + return;
8.77 +
8.78 + /* Write the received data back. */
8.79 +
8.80 + INV_REG(PORTA, 1 << 2);
8.81 +
8.82 + while (REG(U1STA) & 1)
8.83 + uart_write((char) REG(U1RXREG));
8.84 +
8.85 + /* Clear the UART interrupt condition. */
8.86 +
8.87 + CLR_REG(IFS1, 1 << 8);
8.88 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/mips.h Tue Oct 16 23:26:17 2018 +0200
9.3 @@ -0,0 +1,63 @@
9.4 +#ifndef __MIPS_H__
9.5 +#define __MIPS_H__
9.6 +
9.7 +#define KSEG0_BASE 0x80000000
9.8 +#define KSEG1_BASE 0xA0000000
9.9 +
9.10 +#define CP0_INDEX $0
9.11 +#define CP0_ENTRYLO0 $2
9.12 +#define CP0_ENTRYLO1 $3
9.13 +#define CP0_CONTEXT $4
9.14 +#define CP0_PAGEMASK $5
9.15 +#define CP0_WIRED $6
9.16 +#define CP0_BADVADDR $8
9.17 +#define CP0_COUNT $9
9.18 +#define CP0_ENTRYHI $10
9.19 +#define CP0_COMPARE $11
9.20 +#define CP0_STATUS $12
9.21 +#define CP0_INTCTL $12, 1
9.22 +#define CP0_CAUSE $13
9.23 +#define CP0_EPC $14
9.24 +#define CP0_EBASE $15, 1
9.25 +#define CP0_CONFIG $16
9.26 +#define CP0_WATCHLO $18
9.27 +#define CP0_DEBUG $23
9.28 +#define CP0_TAGLO $28
9.29 +#define CP0_TAGHI $29
9.30 +#define CP0_ERROREPC $30, 0
9.31 +
9.32 +#define STATUS_CP0 0x10000000
9.33 +#define STATUS_BEV 0x00400000
9.34 +
9.35 +#define STATUS_IRQ 0x0000fc00
9.36 +#define STATUS_IRQ_SHIFT 10
9.37 +
9.38 +#define STATUS_UM 0x00000010
9.39 +#define STATUS_ERL 0x00000004
9.40 +#define STATUS_EXL 0x00000002
9.41 +#define STATUS_IE 0x00000001
9.42 +
9.43 +#define CAUSE_IV 0x00800000
9.44 +
9.45 +#define EBASE_MASK 0x3ffff000
9.46 +
9.47 +#define INTCTL_MASK 0x000003e0
9.48 +
9.49 +#define DEBUG_DM 0x40000000
9.50 +
9.51 +#define TLB_CACHED 0x00000018
9.52 +#define TLB_UNCACHED 0x00000010
9.53 +#define TLB_DIRTY 0x00000004
9.54 +#define TLB_VALID 0x00000002
9.55 +#define TLB_GLOBAL 0x00000001
9.56 +
9.57 +#define TLB_READ (TLB_CACHED | TLB_VALID)
9.58 +#define TLB_WRITE (TLB_CACHED | TLB_DIRTY | TLB_VALID)
9.59 +#define TLB_ALL_READ (TLB_CACHED | TLB_VALID | TLB_GLOBAL)
9.60 +#define TLB_ALL_WRITE (TLB_CACHED | TLB_DIRTY | TLB_VALID | TLB_GLOBAL)
9.61 +
9.62 +#define CONFIG_K0 0x00000007
9.63 +#define CONFIG_K0_UNCACHED 2
9.64 +#define CONFIG_K0_CACHABLE_NONCOHERENT 3
9.65 +
9.66 +#endif /* __MIPS_H__ */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/pic32.h Tue Oct 16 23:26:17 2018 +0200
10.3 @@ -0,0 +1,125 @@
10.4 +#ifndef __PIC32_H__
10.5 +#define __PIC32_H__
10.6 +
10.7 +/* See...
10.8 + * TABLE 4-1: SFR MEMORYMAP
10.9 + * TABLE 11-3: PORTA REGISTER MAP
10.10 + * 11.2 CLR, SET and INV Registers
10.11 + * PIC32MX1XX/2XX 28/36/44-pin Family Data Sheet
10.12 + */
10.13 +
10.14 +#define OC1CON 0xBF803000
10.15 +#define OC1R 0xBF803010
10.16 +#define OC1RS 0xBF803020
10.17 +#define OC2CON 0xBF803200
10.18 +#define OC2R 0xBF803210
10.19 +#define OC2RS 0xBF803220
10.20 +#define OC3CON 0xBF803400
10.21 +#define OC3R 0xBF803410
10.22 +#define OC3RS 0xBF803420
10.23 +
10.24 +#define T1CON 0xBF800600
10.25 +#define TMR1 0xBF800610
10.26 +#define PR1 0xBF800620
10.27 +#define T2CON 0xBF800800
10.28 +#define TMR2 0xBF800810
10.29 +#define PR2 0xBF800820
10.30 +#define T3CON 0xBF800A00
10.31 +#define TMR3 0xBF800A10
10.32 +#define PR3 0xBF800A20
10.33 +
10.34 +#define U1MODE 0xBF806000
10.35 +#define U1STA 0xBF806010
10.36 +#define U1TXREG 0xBF806020
10.37 +#define U1RXREG 0xBF806030
10.38 +#define U1BRG 0xBF806040
10.39 +
10.40 +#define PMCON 0xBF807000
10.41 +#define PMMODE 0xBF807010
10.42 +#define PMADDR 0xBF807020
10.43 +#define PMDOUT 0xBF807030
10.44 +#define PMDIN 0xBF807040
10.45 +#define PMAEN 0xBF807050
10.46 +#define PMSTAT 0xBF807060
10.47 +
10.48 +#define OSCCON 0xBF80F000
10.49 +#define REFOCON 0xBF80F020
10.50 +#define REFOTRIM 0xBF80F030
10.51 +#define CFGCON 0xBF80F200
10.52 +#define SYSKEY 0xBF80F230
10.53 +
10.54 +#define U1RXR 0xBF80FA50
10.55 +
10.56 +#define RPA0R 0xBF80FB00
10.57 +#define RPA1R 0xBF80FB04
10.58 +#define RPA2R 0xBF80FB08
10.59 +#define RPA3R 0xBF80FB0C
10.60 +#define RPA4R 0xBF80FB10
10.61 +#define RPB0R 0xBF80FB2C
10.62 +#define RPB1R 0xBF80FB30
10.63 +#define RPB2R 0xBF80FB34
10.64 +#define RPB3R 0xBF80FB38
10.65 +#define RPB4R 0xBF80FB3C
10.66 +#define RPB5R 0xBF80FB40
10.67 +#define RPB10R 0xBF80FB54
10.68 +#define RPB15R 0xBF80FB68
10.69 +
10.70 +#define INTCON 0xBF881000
10.71 +#define IFS0 0xBF881030
10.72 +#define IFS1 0xBF881040
10.73 +#define IEC0 0xBF881060
10.74 +#define IEC1 0xBF881070
10.75 +#define IPC1 0xBF8810A0
10.76 +#define IPC2 0xBF8810B0
10.77 +#define IPC7 0xBF881100
10.78 +#define IPC8 0xBF881110
10.79 +#define IPC10 0xBF881130
10.80 +
10.81 +#define BMXCON 0xBF882000
10.82 +#define BMXDKPBA 0xBF882010
10.83 +#define BMXDUDBA 0xBF882020
10.84 +#define BMXDUPBA 0xBF882030
10.85 +#define BMXDRMSZ 0xBF882040
10.86 +
10.87 +#define DMACON 0xBF883000
10.88 +#define DCH0CON 0xBF883060
10.89 +#define DCH0ECON 0xBF883070
10.90 +#define DCH0INT 0xBF883080
10.91 +#define DCH0SSA 0xBF883090
10.92 +#define DCH0DSA 0xBF8830A0
10.93 +#define DCH0SSIZ 0xBF8830B0
10.94 +#define DCH0DSIZ 0xBF8830C0
10.95 +#define DCH0CSIZ 0xBF8830F0
10.96 +#define DCH1CON 0xBF883120
10.97 +#define DCH1ECON 0xBF883130
10.98 +#define DCH1INT 0xBF883140
10.99 +#define DCH1SSA 0xBF883150
10.100 +#define DCH1DSA 0xBF883160
10.101 +#define DCH1SSIZ 0xBF883170
10.102 +#define DCH1DSIZ 0xBF883180
10.103 +#define DCH1CSIZ 0xBF8831B0
10.104 +#define DCH2CON 0xBF8831E0
10.105 +#define DCH2ECON 0xBF8831F0
10.106 +#define DCH2INT 0xBF883200
10.107 +#define DCH2SSA 0xBF883210
10.108 +#define DCH2DSA 0xBF883220
10.109 +#define DCH2SSIZ 0xBF883230
10.110 +#define DCH2DSIZ 0xBF883240
10.111 +#define DCH2CSIZ 0xBF883270
10.112 +
10.113 +#define ANSELA 0xBF886000
10.114 +#define TRISA 0xBF886010
10.115 +#define PORTA 0xBF886020
10.116 +#define LATA 0xBF886030
10.117 +#define ODCA 0xBF886040
10.118 +#define ANSELB 0xBF886100
10.119 +#define TRISB 0xBF886110
10.120 +#define PORTB 0xBF886120
10.121 +#define LATB 0xBF886130
10.122 +#define ODCB 0xBF886140
10.123 +
10.124 +#define CLR 0x4
10.125 +#define SET 0x8
10.126 +#define INV 0xC
10.127 +
10.128 +#endif /* __PIC32_H__ */
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/pic32_c.h Tue Oct 16 23:26:17 2018 +0200
11.3 @@ -0,0 +1,21 @@
11.4 +#ifndef __ASSEMBLER__
11.5 +
11.6 +#ifndef __PIC32_C_H__
11.7 +#define __PIC32_C_H__
11.8 +
11.9 +#include <stdint.h>
11.10 +#include "pic32.h"
11.11 +
11.12 +/* Access. */
11.13 +
11.14 +#define REG(mem) *((volatile uint32_t *) (mem))
11.15 +
11.16 +/* Bit clearing, setting and inverting. */
11.17 +
11.18 +#define CLR_REG(mem, val) (REG(mem + CLR) = val)
11.19 +#define SET_REG(mem, val) (REG(mem + SET) = val)
11.20 +#define INV_REG(mem, val) (REG(mem + INV) = val)
11.21 +
11.22 +#endif /* __PIC32_C_H__ */
11.23 +
11.24 +#endif /* __ASSEMBLER__ */