-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfuncs.c
155 lines (126 loc) · 3.98 KB
/
funcs.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
#include <stdio.h>
#include <math.h>
#define conversionCycles 22
#define adcAddress 0x12000000
#define adcDataAddress 0x13000000
#define configReg0 0x40
#define configReg1 0x41
#define configReg2 0x42
#define DENDWEaddress 0x14000000
#define EOCaddress 0x15000000
#define sampleAddress 0x16000000
// DO NOT CHANGE ANYTHING ABOVE THIS LINE //
// defines below this line can be changed //
#define reg0Default 0x0003 //0000000000000011
#define reg1Default 0x30F0 //0011000011110000
#define reg2Default 0x0000 //0000000000000000
#define dclkFreq 50 //in MHz
#define acqTime 4 //in cycles. can only be 4 or 10
#define convRate 50 //in KSPS
/* setDENandDWE
* sets the bit located at the DENDWEaddress to high
* Input: none
* Output: none */
void setDENandDWE() {
int* denAndDwe = DENDWEaddress;
*denAndDwe = 0x1;
// Hardware will (should) reset this value to 0.
}
/* writeDclkDivider
* Input: dclkDivider
* reg2 (pointer to change it in main when modified)
* Output: none */
void writeDclkDivider(int dclkDivider, int* reg2) {
int* address = adcAddress;
int* dataAddress = adcDataAddress;
int shiftedDivider = dclkDivider << 8;
*reg2 &= 0x00FF; //clear out the old clock divider
*reg2 |= shiftedDivider; //and set the inputted one
//set the address we are writing to be configReg2
*address = configReg2;
//write the clock divider to that spot, bits shifted by 8 (other 8 unused)
*dataAddress = *reg2;
//set DEN and DWE high so the ADC will actually read what we wrote (done in hardware)
setDENandDWE();
}
/* getDclkDivider
* Inputs: dclkFrequency (MHz)
* acqTime (clock cycles)
* conversionRate (KSPS)
* Output: clock divider value, rounded to nearest whole number */
int getDclkDivider(int dclkFrequency, int acquireTime, int conversionRate) {
// NOTE: multiplied by 1000 to account for dclkFrequency being in MHz.
return round(1000 * ((double)dclkFrequency /
(conversionRate * (acquireTime + conversionCycles))));
}
/* getSamples
* populates the inputted int array with samples from the ADC
* Input: adcSamples
* Output: none */
void getSamples(int* adcSamples) {
int i = 0;
int* EOC = EOCaddress;
int* sampleAddr = sampleAddress;
while(i < 5000) {
// do not collect samples until EOC goes high
while(!(*EOC)) {
;
}
// once EOC goes high, fill up our array.
adcSamples[i++] = *sampleAddr;
}
return;
}
/* getPeakToPeak
* finds the min and max in the adcSamples list, and outputs their difference
* Inputs: adcSamples (int array)
* N (size of adcSamples)
* Output: peak to peak value */
int getPeakToPeak(int* adcSamples, int N) {
int max = adcSamples[0];
int min = adcSamples[0];
int i;
for(i = 0; i < N; i++) {
if (adcSamples[i] < min)
min = adcSamples[i];
if (adcSamples[i] > max)
max = adcSamples[i];
}
return (max - min);
}
/* getPeakToPeak
* finds the average value in the adcSamples list
* Inputs: adcSamples (int array)
* N (size of adcSamples)
* Output: average value */
int getAverage(int* adcSamples, int N) {
int sum = 0;
int i;
for(i = 0; i < N; i++) {
sum += adcSamples[i];
}
return (sum / N);
}
int main()
{
int reg0 = reg0Default;
int reg1 = reg1Default;
int reg2 = reg2Default;
int dclkDivider;
int peakToPeak;
int average;
int adcSamples[5000];
// set the clock rate from user-specified parameters, from the #defines
dclkDivider = getDclkDivider(dclkFreq, acqTime, convRate);
writeDclkDivider(dclkDivider, ®2);
// run indefinitely (until shutdown)
while(1){
// populate the samples array
getSamples(adcSamples);
// get the peak to peak of this sample
peakToPeak = getPeakToPeak(adcSamples, 5000);
// get the average of this sample
average = getAverage(adcSamples, 5000);
}
return 0;
}