This repository has been archived by the owner on Oct 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit.c
197 lines (178 loc) · 6.12 KB
/
init.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <xc.h>
#include <pic18f26k83.h>
#include "init.h"
/*
* Set up all Analog select (ANSEL), Latch/Port (LAT), and Tristate (TRIS)
* registers for all pins on the device. comments appear beside each assignment
* to show what is connected to that pin.
*/
void init_pins(void)
{
//starting with port A
ANSELA = ( 0 << 7 | //OSC1 pin
0 << 6 | //OSC2 pin
0 << 5 | //Debug led 3
0 << 4 | //Debug led 2
1 << 3 | //Battery VSense
0 << 2 | //BUS_enable line
1 << 1 | //curr_battery line
1 << 0); //curr_bus line
LATA = ( 0 << 7 | //OSC1 pin
0 << 6 | //OSC2 pin
0 << 5 | //Debug led 3. Off at startup
1 << 4 | //Debug led 2. Off at startup
0 << 3 | //Battery VSense
0 << 2 | //BUS_enable line. Off at startup
0 << 1 | //curr_battery line
0 << 0); //curr_bus line
TRISA = ( 1 << 7 | //OSC1 pin
1 << 6 | //OSC2 pin
0 << 5 | //Debug led 3
0 << 4 | //Debug led 2
1 << 3 | //Battery VSense
0 << 2 | //BUS_enable line
1 << 1 | //curr_battery line
1 << 0); //curr_bus line
//now port B
ANSELB = ( 1 << 7 | //ICSPDAT (otherwise unused)
1 << 6 | //ICSPCLK (otherwise unused)
1 << 5 | //NC pin
0 << 4 | //UART_TX
0 << 3 | //UART_RX
0 << 2 | //~UART_RTS
0 << 1 | //~UART_CTS
1 << 0); //NC pin
LATB = ( 0 << 7 | //ICSPDAT (otherwise unused)
0 << 6 | //ICSPCLK (otherwise unused)
0 << 5 | //NC pin
0 << 4 | //UART_TX
0 << 3 | //UART_RX
0 << 2 | //~UART_RTS
0 << 1 | //~UART_CTS
0 << 0); //NC pin
TRISB = ( 1 << 7 | //ICSPDAT (otherwise unused)
1 << 6 | //ICSPCLK (otherwise unused)
1 << 5 | //NC pin
0 << 4 | //UART_TX
1 << 3 | //UART_RX
0 << 2 | //~UART_RTS
1 << 1 | //~UART_CTS
1 << 0); //NC pin
//now port C
ANSELC = ( 0 << 7 | //XBEE_RESET
0 << 6 | //XBEE_SLEEP
0 << 5 | //NC
0 << 4 | //BUS_EN_GND
0 << 3 | //CANTX
0 << 2 | //CANRX
0 << 1 | //Debug LED 1
0 << 0); //BUS_EN_5V
LATC = ( 0 << 7 | //XBEE_RESET
0 << 6 | //XBEE_SLEEP
0 << 5 | //NC
0 << 4 | //BUS_EN_GND
0 << 3 | //CANTX
0 << 2 | //CANRX
0 << 1 | //Debug LED 1
0 << 0); //BUS_EN_5V
TRISC = ( 1 << 7 | //XBEE_RESET
1 << 6 | //XBEE_SLEEP
1 << 5 | //NC
0 << 4 | //BUS_EN_GND
0 << 3 | //CANTX
1 << 2 | //CANRX
0 << 1 | //Debug LED 1
0 << 0); //BUS_EN_5V
//setup CAN output pins
//CANRX on RC2
CANRXPPS = 0b010010;
//CANTX on RC3
RC3PPS = 0b110011;
}
/*
* Initialize the oscillator
* Blocks while it tries to run off of the external oscillator.
*/
void init_oscillator(void)
{
//Select external oscillator with PLL of 1:1
OSCCON1 = 0b01110000;
//wait until the clock switch has happened
while (OSCCON3bits.ORDY == 0) {}
//if the currently active clock (CON2) isn't the selected clock (CON1)
if (OSCCON2 != 0b01110000) {
//infinite loop, something is broken, what even is an assert()?
while (1) {}
}
}
/*
* Initializes all necessary registers for the adc module
* Currently only sets up for reading the battery voltage from pin ANA3
*/
void init_adc(void)
{
//enable fixed voltage reference
FVRCONbits.EN = 1;
//set the voltage reference to be 4.096V on both outputs
FVRCONbits.CDAFVR = 0b11;
FVRCONbits.ADFVR = 0b11;
//disable the temperature indicator.... for now....
FVRCONbits.TSEN = 0;
//wait for the FVR to stabilize
while (FVRCONbits.RDY == 0) {}
//turn on the ADC
ADCON0bits.ON = 1;
//disable repeating operations
// if this is set to 1, as soon as ADC finished a reading it starts another
ADCON0bits.CONT = 0;
//use system clock as ADC timer. Divider set by ADCLK
ADCON0bits.CS = 0;
//this assumes FOSC is 12MHz this value sets ADC clock period to
// 1.5uS (Fosc/16). Before you change this number, please check
// datasheet table 37-1
ADCLK = 0b000111;
//right justify the 12 bit output of the ADC. if this value is 0,
// the top 8 bits of read value are put in ADRESH, and the bottom
// 4 bits are put in the top 4 bits of ADRESL. In this mode,
// bottom 8 bits are in ADRESL, top 4 are in bottom 4 bits of
// ADRESH.
ADCON0bits.FM = 1;
//set the references
// negative reference is ground
ADREFbits.NREF = 0; //1 would set to external Vref-
// positive reference to internal FVR module
ADREFbits.PREF = 0b11;
}
void init_timer0(void)
{
//disable the module so we can screw with it
T0CON0bits.EN = 0;
//set timer up to be an 8 bit timer
T0CON0bits.MD16 = 0;
//set the pre and postscalars to 0. Because I don't know what they do
T0CON0bits.OUTPS = 0;
T0CON1bits.CKPS = 0;
//drive the timer from 500 kHz internal oscillator
T0CON1bits.CS = 0x5;
T0CON1bits.ASYNC = 0;
//enable the module
T0CON0bits.EN = 1;
}
/*
* Turn on all the interrupts that we want
* If you want a new interrupt, please turn it on here.
*/
void init_interrupts(void)
{
//enable global interrupts
INTCON0bits.GIE = 1;
//disable interrupt priorities. Another thing we could be fancy about
INTCON0bits.IPEN = 0;
//enable ADC interrupt
PIE1bits.ADIE = 1;
//enable timer 0 interrupt
PIE3bits.TMR0IE = 1;
//at present we are not using vectored interrupts. If we were being fancy,
//we would be using vectored interrupts. If you feel like being fancy and
//adding that functionality, the register you want to screw with is IVTBASE
}