diff options
author | Akshay <[email protected]> | 2022-04-10 12:13:40 +0100 |
---|---|---|
committer | Akshay <[email protected]> | 2022-04-10 12:13:40 +0100 |
commit | dc90387ce7d8ba7b607d9c48540bf6d8b560f14d (patch) | |
tree | 4ccb8fa5886b66fa9d480edef74236c27f035e16 /lib/chibios-contrib/testhal/MSP430X/EXP430FR6989/ADC/main.c |
Diffstat (limited to 'lib/chibios-contrib/testhal/MSP430X/EXP430FR6989/ADC/main.c')
-rw-r--r-- | lib/chibios-contrib/testhal/MSP430X/EXP430FR6989/ADC/main.c | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/lib/chibios-contrib/testhal/MSP430X/EXP430FR6989/ADC/main.c b/lib/chibios-contrib/testhal/MSP430X/EXP430FR6989/ADC/main.c new file mode 100644 index 000000000..7f6429dad --- /dev/null +++ b/lib/chibios-contrib/testhal/MSP430X/EXP430FR6989/ADC/main.c | |||
@@ -0,0 +1,254 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include "ch.h" | ||
18 | #include "hal.h" | ||
19 | #include "string.h" | ||
20 | #include "stdio.h" /* eesh */ | ||
21 | |||
22 | /* Disable watchdog because of lousy startup code in newlib */ | ||
23 | static void __attribute__((naked, section(".crt_0042disable_watchdog"), used)) | ||
24 | disable_watchdog(void) { | ||
25 | WDTCTL = WDTPW | WDTHOLD; | ||
26 | } | ||
27 | |||
28 | const char * start_msg = "\r\n\r\nExecuting ADC test suite...\r\n"; | ||
29 | const char * test_1_msg = "\r\nTEST 1: 1 channel, depth 1, no circular\r\n"; | ||
30 | const char * test_2_msg = "\r\nTEST 2: 1 channel, depth 8, no circular\r\n"; | ||
31 | const char * test_3_msg = "\r\nTEST 3: 4 channels, depth 1, no circular\r\n"; | ||
32 | const char * test_4_msg = "\r\nTEST 4: 4 channels, depth 8, no circular\r\n"; | ||
33 | const char * test_5_msg = "\r\nTEST 5: 1 channel, depth 1, circular\r\n"; | ||
34 | const char * test_6_msg = "\r\nTEST 6: 1 channel, depth 8, circular\r\n"; | ||
35 | const char * test_7_msg = "\r\nTEST 7: 4 channel, depth 1, circular\r\n"; | ||
36 | const char * test_8_msg = "\r\nTEST 8: 4 channel, depth 8, circular\r\n"; | ||
37 | const char * test_9_msg = "\r\nTEST 9: 1 channel, depth 1, synchronous\r\n"; | ||
38 | |||
39 | const char * success_string = "\r\nSUCCESS\r\n"; | ||
40 | const char * fail_string = "\r\nFAILURE\r\n"; | ||
41 | |||
42 | char out_string[128]; | ||
43 | const char * raw_fmt_string = "Raw Value: %d\r\n"; | ||
44 | const char * cooked_fmt_string = "Cooked Value: %d\r\n"; | ||
45 | const char * chn_fmt_string = "\r\nCHANNEL %d\r\n"; | ||
46 | |||
47 | uint16_t buffer_margin[72]; | ||
48 | uint16_t * buffer = buffer_margin + 4; | ||
49 | uint8_t depth; | ||
50 | uint8_t cb_arg = 0; | ||
51 | uint16_t cb_expect; | ||
52 | |||
53 | static const int test = 0; | ||
54 | |||
55 | ADCConfig config = { | ||
56 | }; | ||
57 | |||
58 | ADCConversionGroup group = { | ||
59 | false, /* circular */ | ||
60 | 1, /* num_channels */ | ||
61 | NULL, /* end_cb */ | ||
62 | NULL, /* error_cb */ | ||
63 | { | ||
64 | 30, 31, 30, 31, 0, 0, 0, 0, | ||
65 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
66 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
67 | 0, 0, 0, 0, 0, 0, 0, 0 | ||
68 | }, /* channels */ | ||
69 | MSP430X_ADC_RES_12BIT, /* res */ | ||
70 | MSP430X_ADC_SHT_32, /* rate */ | ||
71 | MSP430X_ADC_VSS_VREF_BUF, /* ref */ | ||
72 | MSP430X_REF_2V5 /* vref_src */ | ||
73 | }; | ||
74 | |||
75 | void print(const char * msg) { | ||
76 | |||
77 | if (!test) { | ||
78 | chnWrite(&SD1, (const uint8_t *)msg, strlen(msg)); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | void adc_callback(ADCDriver * adcp, adcsample_t *buffer, size_t n) { | ||
83 | (void)adcp; | ||
84 | (void)buffer; | ||
85 | (void)n; | ||
86 | |||
87 | cb_arg++; | ||
88 | |||
89 | if (adcp->grpp->circular && cb_arg == cb_expect) { | ||
90 | osalSysLockFromISR(); | ||
91 | adcStopConversionI(adcp); | ||
92 | osalSysUnlockFromISR(); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | void run_test(const char * test_msg, uint8_t num_channels, uint8_t depth, | ||
97 | bool circular) { | ||
98 | print(test_msg); | ||
99 | |||
100 | cb_arg = 0; | ||
101 | |||
102 | group.num_channels = num_channels; | ||
103 | group.circular = circular; | ||
104 | group.end_cb = adc_callback; | ||
105 | |||
106 | if (depth > 1) cb_expect = 2; | ||
107 | else cb_expect = 1; | ||
108 | if (circular) cb_expect *= 3; | ||
109 | |||
110 | adcStartConversion(&ADCD1, &group, buffer, depth); | ||
111 | |||
112 | while (ADCD1.state == ADC_ACTIVE) ; | ||
113 | |||
114 | |||
115 | int index = 0; | ||
116 | for (int j = 0; j < depth; j++) { | ||
117 | for (int i = 0; i < group.num_channels; i++) { | ||
118 | index = i + (j * group.num_channels); | ||
119 | sniprintf(out_string, 128, chn_fmt_string, group.channels[i]); | ||
120 | print(out_string); | ||
121 | |||
122 | sniprintf(out_string, 128, raw_fmt_string, buffer[index]); | ||
123 | print(out_string); | ||
124 | |||
125 | if (group.channels[i] == 30) { /* internal temp sensor */ | ||
126 | buffer[index] = adcMSP430XAdjustTemp(&group, buffer[index]); | ||
127 | } | ||
128 | else { | ||
129 | buffer[index] = adcMSP430XAdjustResult(&group, buffer[index]); | ||
130 | } | ||
131 | |||
132 | sniprintf(out_string, 128, cooked_fmt_string, buffer[index]); | ||
133 | print(out_string); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | if (cb_arg == cb_expect) { | ||
138 | print(success_string); | ||
139 | } | ||
140 | else { | ||
141 | print(fail_string); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Thread 2. | ||
147 | */ | ||
148 | THD_WORKING_AREA(waThread1, 4096); | ||
149 | THD_FUNCTION(Thread1, arg) { | ||
150 | |||
151 | (void)arg; | ||
152 | |||
153 | /* | ||
154 | * Activate the serial driver 0 using the driver default configuration. | ||
155 | */ | ||
156 | sdStart(&SD1, NULL); | ||
157 | |||
158 | /* Activate the ADC driver 1 using its config */ | ||
159 | adcStart(&ADCD1, &config); | ||
160 | |||
161 | while (chnGetTimeout(&SD1, TIME_INFINITE)) { | ||
162 | print(start_msg); | ||
163 | chThdSleepMilliseconds(2000); | ||
164 | |||
165 | /* Test 1 - 1ch1d, no circular */ | ||
166 | run_test(test_1_msg, 1, 1, false); | ||
167 | |||
168 | /* Test 2 - 1ch8d, no circular */ | ||
169 | run_test(test_2_msg, 1, 8, false); | ||
170 | |||
171 | /* Test 3 - 4chd1, no circular */ | ||
172 | run_test(test_3_msg, 4, 1, false); | ||
173 | |||
174 | /* Test 4 - 4ch8d, no circular */ | ||
175 | run_test(test_4_msg, 4, 8, false); | ||
176 | |||
177 | /* Test 5 - 1ch1d, circular */ | ||
178 | run_test(test_5_msg, 1, 1, true); | ||
179 | |||
180 | /* Test 6 - 1ch8d, circular */ | ||
181 | run_test(test_6_msg, 1, 8, true); | ||
182 | |||
183 | /* Test 7 - 4ch1d, circular */ | ||
184 | run_test(test_7_msg, 4, 1, true); | ||
185 | |||
186 | /* Test 8 - 4ch8d, circular */ | ||
187 | run_test(test_8_msg, 4, 8, true); | ||
188 | |||
189 | /* Test 9 - 1ch1d, synchronous */ | ||
190 | print(test_9_msg); | ||
191 | cb_arg = 0; | ||
192 | |||
193 | group.num_channels = 1; | ||
194 | group.circular = false; | ||
195 | group.end_cb = adc_callback; | ||
196 | |||
197 | cb_expect = 1; | ||
198 | |||
199 | adcConvert(&ADCD1, &group, buffer, 1); | ||
200 | |||
201 | while (ADCD1.state == ADC_ACTIVE) ; | ||
202 | |||
203 | sniprintf(out_string, 128, chn_fmt_string, group.channels[0]); | ||
204 | print(out_string); | ||
205 | |||
206 | sniprintf(out_string, 128, raw_fmt_string, buffer[0]); | ||
207 | print(out_string); | ||
208 | |||
209 | buffer[0] = adcMSP430XAdjustTemp(&group, buffer[0]); | ||
210 | |||
211 | sniprintf(out_string, 128, cooked_fmt_string, buffer[0]); | ||
212 | print(out_string); | ||
213 | |||
214 | if (cb_arg == cb_expect) { | ||
215 | print(success_string); | ||
216 | } | ||
217 | else { | ||
218 | print(fail_string); | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Threads static table, one entry per thread. The number of entries must | ||
225 | * match NIL_CFG_NUM_THREADS. | ||
226 | */ | ||
227 | THD_TABLE_BEGIN | ||
228 | THD_TABLE_ENTRY(waThread1, "adc_test", Thread1, NULL) | ||
229 | THD_TABLE_END | ||
230 | |||
231 | /* | ||
232 | * Application entry point. | ||
233 | */ | ||
234 | int main(void) { | ||
235 | |||
236 | /* | ||
237 | * System initializations. | ||
238 | * - HAL initialization, this also initializes the configured device drivers | ||
239 | * and performs the board-specific initializations. | ||
240 | * - Kernel initialization, the main() function becomes a thread and the | ||
241 | * RTOS is active. | ||
242 | */ | ||
243 | WDTCTL = WDTPW | WDTHOLD; | ||
244 | |||
245 | halInit(); | ||
246 | chSysInit(); | ||
247 | |||
248 | /* This is now the idle thread loop, you may perform here a low priority | ||
249 | task but you must never try to sleep or wait in this loop. Note that | ||
250 | this tasks runs at the lowest priority level so any instruction added | ||
251 | here will be executed after all other tasks have been started.*/ | ||
252 | while (true) { | ||
253 | } | ||
254 | } | ||