1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/init.c Tue Oct 16 23:26:17 2018 +0200
1.3 @@ -0,0 +1,126 @@
1.4 +#include "cpu.h"
1.5 +#include "pic32_c.h"
1.6 +
1.7 +
1.8 +
1.9 +/* Basic memory and pin initialisation. */
1.10 +
1.11 +void init_memory(void)
1.12 +{
1.13 + /*
1.14 + Configure RAM.
1.15 + See: http://microchipdeveloper.com/32bit:mx-arch-exceptions-processor-initialization
1.16 + */
1.17 +
1.18 + uint32_t config = REG(BMXCON);
1.19 +
1.20 + /* Set zero wait states for address setup. */
1.21 +
1.22 + config &= ~(1 << 6); /* BMXCON<6> = BMXWSDRM = 0 */
1.23 +
1.24 + /* Set bus arbitration mode. */
1.25 +
1.26 + config &= ~0b111;
1.27 + config |= 0b010; /* BMXCON<2:0> = BMXARB<2:0> = 2 */
1.28 +
1.29 + REG(BMXCON) = config;
1.30 +}
1.31 +
1.32 +void init_pins(void)
1.33 +{
1.34 + /* DEVCFG0<2> also needs setting to 0 before the program is run. */
1.35 +
1.36 + CLR_REG(CFGCON, 1 << 3); /* CFGCON<3> = JTAGEN = 0 */
1.37 +}
1.38 +
1.39 +void init_outputs(void)
1.40 +{
1.41 + /* Remove analogue features from pins. */
1.42 +
1.43 + REG(ANSELA) = 0;
1.44 + REG(ANSELB) = 0;
1.45 +
1.46 + REG(TRISA) = 0;
1.47 + REG(TRISB) = 0;
1.48 +
1.49 + REG(PORTA) = 0;
1.50 + REG(PORTB) = 0;
1.51 +}
1.52 +
1.53 +
1.54 +
1.55 +/* Peripheral pin configuration. */
1.56 +
1.57 +void config_uart(void)
1.58 +{
1.59 + /* Map U1RX to RPB13. */
1.60 +
1.61 + REG(U1RXR) = 0b0011; /* U1RXR<3:0> = 0011 (RPB13) */
1.62 +
1.63 + /* Map U1TX to RPB15. */
1.64 +
1.65 + REG(RPB15R) = 0b0001; /* RPB15R<3:0> = 0001 (U1TX) */
1.66 +
1.67 + /* Set RPB13 to input. */
1.68 +
1.69 + SET_REG(TRISB, 1 << 13);
1.70 +}
1.71 +
1.72 +void lock_config(void)
1.73 +{
1.74 + SET_REG(CFGCON, 1 << 13); /* IOLOCK = 1 */
1.75 +
1.76 + /* Lock the configuration again. */
1.77 +
1.78 + REG(SYSKEY) = 0x33333333;
1.79 +}
1.80 +
1.81 +void unlock_config(void)
1.82 +{
1.83 + /* Unlock the configuration register bits. */
1.84 +
1.85 + REG(SYSKEY) = 0;
1.86 + REG(SYSKEY) = 0xAA996655;
1.87 + REG(SYSKEY) = 0x556699AA;
1.88 +
1.89 + CLR_REG(CFGCON, 1 << 13); /* IOLOCK = 0 */
1.90 +}
1.91 +
1.92 +
1.93 +
1.94 +/* Convenience operations. */
1.95 +
1.96 +void interrupts_on(void)
1.97 +{
1.98 + init_interrupts();
1.99 + enable_interrupts();
1.100 + handle_error_level();
1.101 +}
1.102 +
1.103 +
1.104 +
1.105 +/* Peripheral configuration. */
1.106 +
1.107 +void init_uart(uint8_t pri, uint8_t sub)
1.108 +{
1.109 + CLR_REG(U1MODE, 1 << 15); /* U1MODE<15> = ON = 0 */
1.110 + REG(U1BRG) = 12; /* U1BRG<15:0> = BRG = (FPB / (16 * baudrate)) - 1 = (24000000 / (16 * 115200)) - 1 = 12 */
1.111 +
1.112 + /* Disable interrupt and clear flag. */
1.113 +
1.114 + CLR_REG(IEC1, 1 << 8); /* IEC1<8> = U1RIE = 0 */
1.115 + CLR_REG(IFS1, 1 << 8); /* IFS1<8> = U1RIF = 0 */
1.116 +
1.117 + /* Set priorities: U1IP = pri; U1IS = sub */
1.118 +
1.119 + REG(IPC8) = (REG(IPC8) & ~0b11111) | ((pri & 0b111) << 2) | (sub & 0b11);
1.120 +
1.121 + /* Enable interrupt. */
1.122 +
1.123 + SET_REG(IEC1, 1 << 8); /* IEC1<8> = U1RIE = 1 */
1.124 +
1.125 + /* Start UART. */
1.126 +
1.127 + SET_REG(U1STA, (1 << 12) | (1 << 10)); /* U1STA<12> = URXEN = 1; U1STA<10> = UTXEN = 1 */
1.128 + SET_REG(U1MODE, 1 << 15); /* U1MODE<15> = ON = 1 */
1.129 +}