1 #include "cpu.h" 2 #include "pic32_c.h" 3 4 5 6 /* Basic memory and pin initialisation. */ 7 8 void init_memory(void) 9 { 10 /* 11 Configure RAM. 12 See: http://microchipdeveloper.com/32bit:mx-arch-exceptions-processor-initialization 13 */ 14 15 uint32_t config = REG(BMXCON); 16 17 /* Set zero wait states for address setup. */ 18 19 config &= ~(1 << 6); /* BMXCON<6> = BMXWSDRM = 0 */ 20 21 /* Set bus arbitration mode. */ 22 23 config &= ~0b111; 24 config |= 0b010; /* BMXCON<2:0> = BMXARB<2:0> = 2 */ 25 26 REG(BMXCON) = config; 27 } 28 29 void init_pins(void) 30 { 31 /* DEVCFG0<2> also needs setting to 0 before the program is run. */ 32 33 CLR_REG(CFGCON, 1 << 3); /* CFGCON<3> = JTAGEN = 0 */ 34 } 35 36 void init_outputs(void) 37 { 38 /* Remove analogue features from pins. */ 39 40 REG(ANSELA) = 0; 41 REG(ANSELB) = 0; 42 43 REG(TRISA) = 0; 44 REG(TRISB) = 0; 45 46 REG(PORTA) = 0; 47 REG(PORTB) = 0; 48 } 49 50 51 52 /* Peripheral pin configuration. */ 53 54 void config_uart(void) 55 { 56 /* Map U1RX to RPB13. */ 57 58 REG(U1RXR) = 0b0011; /* U1RXR<3:0> = 0011 (RPB13) */ 59 60 /* Map U1TX to RPB15. */ 61 62 REG(RPB15R) = 0b0001; /* RPB15R<3:0> = 0001 (U1TX) */ 63 64 /* Set RPB13 to input. */ 65 66 SET_REG(TRISB, 1 << 13); 67 } 68 69 void lock_config(void) 70 { 71 SET_REG(CFGCON, 1 << 13); /* IOLOCK = 1 */ 72 73 /* Lock the configuration again. */ 74 75 REG(SYSKEY) = 0x33333333; 76 } 77 78 void unlock_config(void) 79 { 80 /* Unlock the configuration register bits. */ 81 82 REG(SYSKEY) = 0; 83 REG(SYSKEY) = 0xAA996655; 84 REG(SYSKEY) = 0x556699AA; 85 86 CLR_REG(CFGCON, 1 << 13); /* IOLOCK = 0 */ 87 } 88 89 90 91 /* Convenience operations. */ 92 93 void interrupts_on(void) 94 { 95 init_interrupts(); 96 enable_interrupts(); 97 handle_error_level(); 98 } 99 100 101 102 /* Peripheral configuration. */ 103 104 void init_uart(uint8_t pri, uint8_t sub) 105 { 106 CLR_REG(U1MODE, 1 << 15); /* U1MODE<15> = ON = 0 */ 107 REG(U1BRG) = 12; /* U1BRG<15:0> = BRG = (FPB / (16 * baudrate)) - 1 = (24000000 / (16 * 115200)) - 1 = 12 */ 108 109 /* Disable interrupt and clear flag. */ 110 111 CLR_REG(IEC1, 1 << 8); /* IEC1<8> = U1RIE = 0 */ 112 CLR_REG(IFS1, 1 << 8); /* IFS1<8> = U1RIF = 0 */ 113 114 /* Set priorities: U1IP = pri; U1IS = sub */ 115 116 REG(IPC8) = (REG(IPC8) & ~0b11111) | ((pri & 0b111) << 2) | (sub & 0b11); 117 118 /* Enable interrupt. */ 119 120 SET_REG(IEC1, 1 << 8); /* IEC1<8> = U1RIE = 1 */ 121 122 /* Start UART. */ 123 124 SET_REG(U1STA, (1 << 12) | (1 << 10)); /* U1STA<12> = URXEN = 1; U1STA<10> = UTXEN = 1 */ 125 SET_REG(U1MODE, 1 << 15); /* U1MODE<15> = ON = 1 */ 126 }