KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
shell_verify.c
1 /*
2  * KM3NeT CLB v2 Firmware
3  * ----------------------
4  *
5  * Copyright 2015 KM3NeT Collaboration
6  *
7  * All Rights Reserved.
8  *
9  *
10  * File : shell_verify.c
11  * Created : 26 mar. 2015
12  * Author : Vincent van Beveren
13  */
14 
15 #include <stdbool.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 
19 #include <util/convert.h>
20 
21 #include "drv/wb/gpio.h"
22 #include "drv/i2c/sht21.h"
23 #include "drv/i2c/ahrs.h"
24 #include "drv/i2c/lsm303.h"
25 #include "drv/i2c/lsm303d.h"
26 #include "drv/i2c/octocpld.h"
27 #include "drv/i2c/pca9548.h"
28 #include "drv/i2c/promis.h"
29 #include "drv/i2c/ltc2631.h"
30 #include "drv/i2c/max123x.h"
31 #include "drv/wb/watchdog.h"
32 #include "kernel/tm.h"
33 #include "kernel/sys.h"
34 #include "cfg_board.h"
35 
36 #include <errorcode.h>
37 #include <kernel/err.h>
38 
39 
40 #define verify_info(MSG, ...) printf(MSG " | ", ## __VA_ARGS__)
41 
42 char fmt_buf[80];
43 
44 typedef const char * (*verify_fn_t)();
45 
46 typedef struct test_entry_s {
47  int label;
48  const char * name;
49  verify_fn_t fn;
50  int dep1;
51  int dep2;
52  bool failed;
53 } test_entry_t;
54 
55 
56 
57 // =======================================================================================================================================
58 // SHT21 temperature / humidity check
59 // =======================================================================================================================================
60 static const char * verify_sht21()
61 {
62  int v;
63  if (!sht21Temp(INS_I2C_DEV, SHT21_I2C_ADDR, &v)) {
64  return "I2C read error";
65  }
66 
67  if ((v < 1500) || (v > 5000)) {
68  sprintf(fmt_buf, "Temperature odd: %d C\n", v / 100);
69  return fmt_buf;
70  }
71  return NULL;
72 }
73 
74 // =======================================================================================================================================
75 // Powerboard ADCs
76 // =======================================================================================================================================
77 
78 // this configures the ADC
79 static const char * verify_max123x(uint8_t addr)
80 {
81  if (!max123xSetup(POWER_I2C_DEV, addr, MAX123X_REF_EXT_RIN, false, false)) {
82  sprintf(fmt_buf, "Powerboard ADC failure @%02x", addr);
83  return fmt_buf;
84  }
85  return NULL;
86 }
87 
88 static const char * verify_max123x_ch(uint8_t addr, int ch, int conv, char * unit, uint32_t mn, uint32_t mx)
89 {
90  uint16_t result;
91  if (!max123xConvert(POWER_I2C_DEV, addr, ch, &result)) {
92  sprintf(fmt_buf, "Powerboard ADC read @%02x, ch=%u", addr, ch);
93  return fmt_buf;
94  }
95 
96  uint32_t val = ((uint32_t)result * conv) / MAX123X_MAX_VALUE;
97  verify_info("%5d %s", val, unit);
98 
99  if (val < mn || val > mx) {
100  sprintf(fmt_buf, "Out of bounds (%d, %d)", mn, mx);
101  return fmt_buf;
102  }
103 
104  return NULL;
105 }
106 
107 
108 static inline const char * verify_max123x_0() { return verify_max123x(POWER_ADC0_I2C_ADDR); }
109 static inline const char * verify_max123x_1() { return verify_max123x(POWER_ADC1_I2C_ADDR); }
110 
111 static inline const char * verify_max123x_0_c12v() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 0, 3300, "mA", 300, 450); }
112 static inline const char * verify_max123x_0_c1v() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 1, 3300, "mA", 600, 1000); }
113 static inline const char * verify_max123x_0_c1v8() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 2, 1320, "mA", 400, 550); }
114 static inline const char * verify_max123x_0_c2v5() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 3, 1320, "mA", 100, 200); }
115 static inline const char * verify_max123x_0_c3v3() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 4, 3300, "mA", 300, 450); }
116 static inline const char * verify_max123x_0_c5v() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 5, 1320, "mA", 0, 10); }
117 static inline const char * verify_max123x_0_cpmt() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 6, 1320, "mA", 0, 1000); }
118 static inline const char * verify_max123x_0_cvled() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 7, 6600, "mA", 10, 40); }
119 static inline const char * verify_max123x_0_lvled() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 8, 33330, "mV", 400, 700); }
120 static inline const char * verify_max123x_0_l12v() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 9, 16500, "mV", 11800, 12200); }
121 static inline const char * verify_max123x_0_temp() { return verify_max123x_ch(POWER_ADC0_I2C_ADDR, 10, 330000, "mC", 20000, 45000); }
122 static inline const char * verify_max123x_1_l1v() { return verify_max123x_ch(POWER_ADC1_I2C_ADDR, 0, 3300, "mV", 950, 1050); }
123 static inline const char * verify_max123x_1_l1v8() { return verify_max123x_ch(POWER_ADC1_I2C_ADDR, 1, 3300, "mV", 1750, 1850); }
124 static inline const char * verify_max123x_1_l2v5() { return verify_max123x_ch(POWER_ADC1_I2C_ADDR, 2, 3300, "mV", 2450, 2550); }
125 static inline const char * verify_max123x_1_l3v3() { return verify_max123x_ch(POWER_ADC1_I2C_ADDR, 3, 6600, "mV", 3250, 3350); }
126 static inline const char * verify_max123x_1_l5v() { return verify_max123x_ch(POWER_ADC1_I2C_ADDR, 4, 6600, "mV", 4950, 5050); }
127 static inline const char * verify_max123x_1_lpmt() { return verify_max123x_ch(POWER_ADC1_I2C_ADDR, 5, 6600, "mV", 3250, 3350); }
128 static inline const char * verify_max123x_1_ldac() { return verify_max123x_ch(POWER_ADC1_I2C_ADDR, 6, 3300, "mV", 0, 1000); }
129 
130 
131 
132 // =======================================================================================================================================
133 // Compass sensor (AHRS/LSM303)
134 // =======================================================================================================================================
135 static const char * verify_compass()
136 {
137  CompassData cmpDta;
140  // give it two seconds.
141  timeDelay(2000);
142  uint8_t ver = 0;
143  uint8_t ahrs_addr = 0;
144  const char * rv = NULL;
145  bool isLSM303 = false;
146  if (!ahrsGetVersion(INS_I2C_DEV, AHRS_I2C_PRIM_ADDR, &ver))
147  {
148  if (!ahrsGetVersion(INS_I2C_DEV, AHRS_I2C_SEC_ADDR, &ver))
149  {
150  if (!lsm303DValid(INS_I2C_DEV, LSM303D_I2C_ADDR, &isLSM303))
151  {
152  rv = "No compass sensor found!";
153  goto failed;
154  }
155  } else ahrs_addr = AHRS_I2C_SEC_ADDR;
156  } else ahrs_addr = AHRS_I2C_PRIM_ADDR;
157 
158  errClear();
159 
160 
161  if (ahrs_addr != 0) {
162  verify_info("Compass = AHRS, version=%d", ahrs_addr, ver);
163  } else {
164  verify_info("Compass = LSM303", isLSM303);
165  }
166 
167  if (ahrs_addr == 0 && !isLSM303)
168  {
169  rv = "LSM303 reports not being LSM303!";
170  goto failed;
171  }
172 
173  if (ahrs_addr != 0) {
174  if (!ahrsRead(INS_I2C_DEV, ahrs_addr, &cmpDta))
175  {
176  rv = "AHRS could not read compass data";
177  goto failed;
178  }
179  } else if (isLSM303) {
180  Lsm303DMagCfg magCfg = {
181  .magScale = LSM303D_MAGSCALE_2GAUSS,
182  .magRate = LSM303D_MAGRATE_12HZ5,
183  .magMode = LSM303D_MAGMODE_CONTINUOUS,
184  .lowPower = false,
185  .hiRes = true
186  };
187 
188  if (!lsm303DMagnetCfg(INS_I2C_DEV, LSM303D_I2C_ADDR, magCfg)) {
189  rv = "LSM303 could not write magnetic cfg";
190  goto failed;
191  }
192 
193  // configure accelerometer at same rate.
194  Lsm303DAccCfg accelCfg = {
195  .accRate = LSM303D_ACCRATE_12HZ5,
196  .accAAF = LSM303D_ACCAAF_773HZ,
197  .accHPF = LSM303D_ACCHPF_NORMAL,
198  .accScale = LSM303D_ACCSCALE_2G,
199  .selfTest = false,
200  .filterAcc = false
201  };
202 
203  if (!lsm303DAccelCfg(INS_I2C_DEV, LSM303D_I2C_ADDR, accelCfg)) {
204  rv = "LSM303 could not write accelerometer cfg";
205  goto failed;
206  }
207 
208 
209  Lsm303DCfg cfg = {
210  .bdu = true,
211  .temp = false,
212  .tempOnly = false
213  };
214 
215  if (!lsm303DCfg(INS_I2C_DEV, LSM303D_I2C_ADDR, cfg)) {
216  rv = "LSM303 could not write temperature cfg";
217  goto failed;
218  }
219 
220  timeDelay(1000);
221  Lsm303Axis axis;
222 
223  // clear data
224  memset(&cmpDta, 0, sizeof(CompassData));
225 
226  if (!lsm303DMagnetRead(INS_I2C_DEV, LSM303D_I2C_ADDR, &axis)) {
227  rv = "LSM303 could not read compass direction";
228  goto failed;
229  }
230 
231  cmpDta.hx = fltFromI16(axis.x, 14);
232  cmpDta.hy = fltFromI16(axis.y, 14);
233  cmpDta.hz = fltFromI16(axis.z, 14);
234 
235 
236  if (!lsm303DAccelRead(INS_I2C_DEV, LSM303D_I2C_ADDR, &axis)) {
237  rv = "LSM303 could not read accelerometer information";
238  goto failed;
239  }
240 
241  cmpDta.ax = fltFromI16(axis.x, 14);
242  cmpDta.ay = fltFromI16(axis.y, 14);
243  cmpDta.az = fltFromI16(axis.z, 14);
244  }
245 
246  int ax = fltToI32(cmpDta.ax, 10);
247  int ay = fltToI32(cmpDta.ay, 10);
248  int az = fltToI32(cmpDta.az, 10);
249 
250  if (az < -11 || az > -9) {
251  rv = "Accelerometer Z value not close to -1";
252  goto failed;
253  }
254 
255  if (ax < -1 || ax > 1) {
256  rv = "Accelerometer X value not close to 0";
257  goto failed;
258  }
259 
260  if (ay < -1 || ay > 1) {
261  rv = "Accelerometer Y value not close to 0";
262  goto failed;
263  }
264 
265 failed:
267  return rv;
268 }
269 
270 // =======================================================================================================================================
271 // Octopus CPLDs, and PMTs
272 // =======================================================================================================================================
273 
274 // ---------------------------------------------------------------------------------------------------------------------------------------
275 // CPLD
276 // ---------------------------------------------------------------------------------------------------------------------------------------
277 
278 static const char * verify_octopus_cpld(I2C_Device * dev, uint8_t addr)
279 {
280  if (!ocWakeUp(dev, addr)) {
281  return "Did not wake up";
282  }
283 
284  return NULL;
285 }
286 
287 static const char * verify_octopus_cpld_small() {
288  return verify_octopus_cpld(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR);
289 }
290 
291 static const char * verify_octopus_cpld_large() {
292  return verify_octopus_cpld(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR);
293 }
294 
295 // ---------------------------------------------------------------------------------------------------------------------------------------
296 // I2C MUX
297 // ---------------------------------------------------------------------------------------------------------------------------------------
298 static const char * verify_octopus_mux(I2C_Device * dev, uint8_t addr)
299 {
300  if (!pca9548_select(dev, addr, -1)) {
301  sprintf(fmt_buf, "I2C mux @ %02xh failed", addr);
302  return fmt_buf;
303  }
304  return NULL;
305 }
306 
307 static inline const char * verify_octopus_mux_small_0() {
308  return verify_octopus_mux(OCTOS_I2C_DEV, OCTOS_MUXB_I2C_ADDR);
309 }
310 
311 static inline const char * verify_octopus_mux_small_1() {
312  return verify_octopus_mux(OCTOS_I2C_DEV, OCTOS_MUXB_I2C_ADDR + 1);
313 }
314 
315 static inline const char * verify_octopus_mux_large_0() {
316  return verify_octopus_mux(OCTOL_I2C_DEV, OCTOL_MUXB_I2C_ADDR);
317 }
318 
319 static inline const char * verify_octopus_mux_large_1() {
320  return verify_octopus_mux(OCTOL_I2C_DEV, OCTOL_MUXB_I2C_ADDR + 1);
321 }
322 
323 static inline const char * verify_octopus_mux_large_2() {
324  return verify_octopus_mux(OCTOL_I2C_DEV, OCTOL_MUXB_I2C_ADDR + 2);
325 }
326 
327 
328 // ---------------------------------------------------------------------------------------------------------------------------------------
329 // I2C PMTS
330 // ---------------------------------------------------------------------------------------------------------------------------------------
331 
332 
333 static const char * verify_pmt(I2C_Device * dev, uint8_t cpld_addr, uint8_t mux_base_addr, uint8_t ch)
334 {
335  const char * rv = NULL;
336 
337  // wake up CPLD
338  if (!ocWakeUp(dev, cpld_addr)) {
339  rv = "Failed to wake up CPLD this time";
340  goto failed;
341  }
342  // Turn PMT on
343  if (!ocWrite(dev, cpld_addr, ocRegOn, 1 << ch)) {
344  rv = "Failed to select CPLD channel";
345  goto failed;
346  }
347 
348  // also enable the clock
349  if (!ocWrite(dev, cpld_addr, ocRegClkEn, 1 << ch)) {
350  // clean up
351  ocWrite(dev, cpld_addr, ocRegOn, 0);
352  rv = "Failed to enable CPLD clock";
353  goto failed;
354  }
355 
356  // and select the correct channel on the mux.
357  if (!pca9548_select(dev, mux_base_addr + (ch / 8), ch % 8)) {
358  rv = "Failed to select PCA channel";
359  }
360 
361  uint8_t buf[3];
362 
363  if (!prmsID(dev, OCTO_PROMIS_I2C_ADDR, buf)) {
364  rv = "Failed to read promis ID";
365  } else {
366  verify_info("ID: %02x%02x%02x", buf[0],buf[1],buf[2]);
367  }
368 
369  // now we're done
370  if (!pca9548_select(dev, mux_base_addr + (ch / 8), 0)) {
371  if (rv == NULL) rv = "Failed to deselect PCA channel";
372  }
373 
374  // disable stuff
375  ocWrite(dev, cpld_addr, ocRegOn, 0);
376  ocWrite(dev, cpld_addr, ocRegClkEn, 0);
377 
378 failed:
379  return rv;
380 }
381 
382 
383 static inline const char * verify_pmt_4_small_0() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 0); }
384 static inline const char * verify_pmt_4_small_1() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 1); }
385 static inline const char * verify_pmt_4_small_2() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 2); }
386 static inline const char * verify_pmt_4_small_3() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 3); }
387 static inline const char * verify_pmt_4_small_4() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 4); }
388 static inline const char * verify_pmt_4_small_5() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 5); }
389 static inline const char * verify_pmt_4_small_6() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 6); }
390 static inline const char * verify_pmt_4_small_7() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 7); }
391 static inline const char * verify_pmt_4_small_8() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 8); }
392 static inline const char * verify_pmt_4_small_9() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 9); }
393 static inline const char * verify_pmt_4_small_10() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 10); }
394 static inline const char * verify_pmt_4_small_11() { return verify_pmt(OCTOS_I2C_DEV, OCTOS_CPLD_I2C_ADDR, OCTOS_MUXB_I2C_ADDR, 11); }
395 
396 static inline const char * verify_pmt_4_large_0() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 0); }
397 static inline const char * verify_pmt_4_large_1() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 1); }
398 static inline const char * verify_pmt_4_large_2() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 2); }
399 static inline const char * verify_pmt_4_large_3() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 3); }
400 static inline const char * verify_pmt_4_large_4() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 4); }
401 static inline const char * verify_pmt_4_large_5() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 5); }
402 static inline const char * verify_pmt_4_large_6() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 6); }
403 static inline const char * verify_pmt_4_large_7() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 7); }
404 static inline const char * verify_pmt_4_large_8() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 8); }
405 static inline const char * verify_pmt_4_large_9() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 9); }
406 static inline const char * verify_pmt_4_large_10() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 10); }
407 static inline const char * verify_pmt_4_large_11() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 11); }
408 static inline const char * verify_pmt_4_large_12() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 12); }
409 static inline const char * verify_pmt_4_large_13() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 13); }
410 static inline const char * verify_pmt_4_large_14() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 14); }
411 static inline const char * verify_pmt_4_large_15() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 15); }
412 static inline const char * verify_pmt_4_large_16() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 16); }
413 static inline const char * verify_pmt_4_large_17() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 17); }
414 static inline const char * verify_pmt_4_large_18() { return verify_pmt(OCTOL_I2C_DEV, OCTOL_CPLD_I2C_ADDR, OCTOL_MUXB_I2C_ADDR, 18); }
415 /*
416 static const char * verify_pmt_4_large() {
417  return verify_pmt(OCTOL_I2C_DEV, OCTOL_MUXB_I2C_ADDR, 3);
418 }
419 */
420 
421 // =======================================================================================================================================
422 // Nano beacon DAC
423 // =======================================================================================================================================
424 static const char * verify_nanobeacon_dac()
425 {
427  return "Failed to write DAC value";
428  }
429  return NULL;
430 }
431 
432 
433 
434 // =======================================================================================================================================
435 // Test configuration list
436 // =======================================================================================================================================
437 static test_entry_t _tests[] = {
438  { -1, "SHT21", verify_sht21, -1, -1, false },
439  { -1, "Compass", verify_compass, -1, -1, false},
440  { 7, "Powerb ADC 0 exist", verify_max123x_0, -1, -1, false},
441  { 8, "Powerb ADC 1 exist", verify_max123x_1, -1, -1, false},
442  { -1, "Powerb 12V current", verify_max123x_0_c12v, 7, -1, false},
443  { -1, "Powerb 1V current", verify_max123x_0_c1v, 7, -1, false},
444  { -1, "Powerb 1.8V current", verify_max123x_0_c1v8, 7, -1, false},
445  { -1, "Powerb 2.5V current", verify_max123x_0_c2v5, 7, -1, false},
446  { -1, "Powerb 3.3V current", verify_max123x_0_c3v3, 7, -1, false},
447  { -1, "Powerb 5V current", verify_max123x_0_c5v, 7, -1, false},
448  { -1, "Powerb PMT current", verify_max123x_0_cpmt, 7, -1, false},
449  { -1, "Powerb LED current", verify_max123x_0_cvled, 7, -1, false},
450  { -1, "Powerb LED level", verify_max123x_0_lvled, 7, -1, false},
451  { -1, "Powerb 12V level", verify_max123x_0_l12v, 7, -1, false},
452  { -1, "Powerb temperature", verify_max123x_0_temp, 7, -1, false},
453  { -1, "Powerb 1V level", verify_max123x_1_l1v, 8, -1, false},
454  { -1, "Powerb 1.8V level", verify_max123x_1_l1v8, 8, -1, false},
455  { -1, "Powerb 2.5V level", verify_max123x_1_l2v5, 8, -1, false},
456  { -1, "Powerb 3.3V level", verify_max123x_1_l3v3, 8, -1, false},
457  { -1, "Powerb 5V level", verify_max123x_1_l5v, 8, -1, false},
458  { -1, "Powerb PMT level", verify_max123x_1_lpmt, 8, -1, false},
459  { -1, "Powerb DAC level", verify_max123x_1_ldac, 8, -1, false},
460  { -1, "Nano beacon DAC", verify_nanobeacon_dac, -1, -1, false},
461  { 0, "Octopus CPLD small", verify_octopus_cpld_small, -1, -1, false},
462  { 1, "Octopus CPLD large", verify_octopus_cpld_large, -1, -1, false},
463  { 2, "Octopus MUX 0 small", verify_octopus_mux_small_0, -1, -1, false},
464  { 3, "Octopus MUX 1 small", verify_octopus_mux_small_1, -1, -1, false},
465  { 4, "Octopus MUX 0 large", verify_octopus_mux_large_0, -1, -1, false},
466  { 5, "Octopus MUX 1 large", verify_octopus_mux_large_1, -1, -1, false},
467  { 6, "Octopus MUX 2 large", verify_octopus_mux_large_2, -1, -1, false},
468  { -1, "1 PMT 0 for small", verify_pmt_4_small_0, 0, 2, false},
469  { -1, "2 PMT 1 for small", verify_pmt_4_small_1, 0, 2, false},
470  { -1, "3 PMT 2 for small", verify_pmt_4_small_2, 0, 2, false},
471  { -1, "4 PMT 3 for small", verify_pmt_4_small_3, 0, 2, false},
472  { -1, "5 PMT 4 for small", verify_pmt_4_small_4, 0, 2, false},
473  { -1, "6 PMT 5 for small", verify_pmt_4_small_5, 0, 2, false},
474  { -1, "7 PMT 6 for small", verify_pmt_4_small_6, 0, 2, false},
475  { -1, "8 PMT 7 for small", verify_pmt_4_small_7, 0, 2, false},
476  { -1, "9 PMT 8 for small", verify_pmt_4_small_8, 0, 3, false},
477  { -1, "10 PMT 9 for small", verify_pmt_4_small_9, 0, 3, false},
478  { -1, "11 PMT 10 for small", verify_pmt_4_small_10, 0, 3, false},
479  { -1, "12 PMT 11 for small", verify_pmt_4_small_11, 0, 3, false},
480  { -1, "13 PMT 0 for large", verify_pmt_4_large_0, 1, 4, false},
481  { -1, "14 PMT 1 for large", verify_pmt_4_large_1, 1, 4, false},
482  { -1, "15 PMT 2 for large", verify_pmt_4_large_2, 1, 4, false},
483  { -1, "16 PMT 3 for large", verify_pmt_4_large_3, 1, 4, false},
484  { -1, "17 PMT 4 for large", verify_pmt_4_large_4, 1, 4, false},
485  { -1, "18 PMT 5 for large", verify_pmt_4_large_5, 1, 4, false},
486  { -1, "19 PMT 6 for large", verify_pmt_4_large_6, 1, 4, false},
487  { -1, "20 PMT 7 for large", verify_pmt_4_large_7, 1, 4, false},
488  { -1, "21 PMT 8 for large", verify_pmt_4_large_8, 1, 5, false},
489  { -1, "22 PMT 9 for large", verify_pmt_4_large_9, 1, 5, false},
490  { -1, "23 PMT 10 for large", verify_pmt_4_large_10, 1, 5, false},
491  { -1, "24 PMT 11 for large", verify_pmt_4_large_11, 1, 5, false},
492  { -1, "25 PMT 12 for large", verify_pmt_4_large_12, 1, 5, false},
493  { -1, "26 PMT 13 for large", verify_pmt_4_large_13, 1, 5, false},
494  { -1, "27 PMT 14 for large", verify_pmt_4_large_14, 1, 5, false},
495  { -1, "28 PMT 15 for large", verify_pmt_4_large_15, 1, 5, false},
496  { -1, "29 PMT 16 for large", verify_pmt_4_large_16, 1, 6, false},
497  { -1, "30 PMT 17 for large", verify_pmt_4_large_17, 1, 6, false},
498  { -1, "31 PMT 18 for large", verify_pmt_4_large_18, 1, 6, false},
499 };
500 
501 const char cmd_verify_help[] = "Verify hardware";
502 
503 bool cmd_verify_exec(int argc, const char *args[])
504 {
505  unsigned int executed = 0;
506  unsigned int skipped = 0;
507  unsigned int failed = 0;
508 
509  int labels[16];
510 
511  const int no_of_tests = sizeof(_tests)/sizeof(_tests[0]);
512 
513  printf("Starting %d CLB tests\n", no_of_tests);
514 
515  for (int i = 0; i < no_of_tests; i++)
516  {
517  // feed WD, otherwise it will crash during the test
519  wdogFeed();
520 
521  test_entry_t * test = &_tests[i];
522 
523  if (test->label != -1) {
524  labels[test->label] = i;
525  }
526 
527  // reset failed state
528  test->failed = false;
529  printf(" %03d %-24s | ", i, test->name);
530  if (test->dep1 >= 0) {
531  if (_tests[labels[test->dep1]].failed) {
532  skipped++;
533  printf("Skipped because %s failed\n", _tests[labels[test->dep1]].name);
534  continue;
535  }
536  }
537  if (test->dep2 >= 0) {
538  if (_tests[labels[test->dep2]].failed) {
539  skipped++;
540  printf("Skipped because %s failed\n", _tests[labels[test->dep2]].name);
541  continue;
542  }
543  }
544 
545  const char * result = test->fn();
546  executed++;
547 
548  if (result == NULL) {
549  if (errGet() != 0) {
550  printf("Unexpected error (%s)\n", errGetDescr());
551  } else {
552  puts("OK");
553  }
554  } else {
555  if (errGet() != 0) {
556  printf("%s (%s)\n", result, errGetDescr());
557  } else {
558  printf("%s\n", result);
559  }
560  failed++;
561  test->failed = true;
562  }
563  errClear();
564  }
565  printf("Completed, executed=%d, failed=%d, skipped=%d\n", executed, failed, skipped);
566 
567  return true;
568 }
569 
570 
f32_t az
Az in g (Float)
Definition: types.h:28
Axis structure for 3D information.
Definition: lsm303.h:31
This driver is to read and configure the AHRS I2C sensor.
#define POWER_I2C_DEV
Power board I2C device.
Definition: cfg_board.h:68
#define OCTOS_MUXB_I2C_ADDR
Octopus small I2C MUX base address.
Definition: cfg_board.h:106
bool ltc2631Write(I2C_Device *dev, uint8_t addr, uint16_t value, bool update)
Sets the DAC value on the input register.
Definition: ltc2631.c:26
#define OCTOS_CPLD_I2C_ADDR
Octopus small CLPD address.
Definition: cfg_board.h:102
Driver of the LTC2631 DAC as found on the power board.
#define OCTOL_CPLD_I2C_ADDR
Octopus large CLPD base address.
Definition: cfg_board.h:91
bool lsm303DMagnetCfg(I2C_Device *dev, uint8_t addr, Lsm303DMagCfg config)
Set the Magnet configuration.
Definition: lsm303d.c:130
#define POWER_DAC_I2C_ADDR
The address of the Power Board DAC (LTC2631)
Definition: cfg_board.h:81
bool ahrsGetVersion(I2C_Device *dev, uint8_t addr, uint8_t *version)
Reads the AHRS version.
Definition: ahrs.c:86
Generic LSM303D configuration.
Definition: lsm303d.h:82
GPIO Driver.
uint16_t accRate
Accelerometer rate , one of LSM303D_ACCRATE_*.
Definition: lsm303d.h:118
void gpioPinConf(int pin, GpioPinDir dir)
Configure PIN directionality.
Definition: gpio.c:26
#define OCTOS_I2C_DEV
Octopus small I2C device.
Definition: cfg_board.h:100
Accelerator configuration structure.
Definition: lsm303d.h:117
System start up and management.
bool lsm303DAccelRead(I2C_Device *dev, uint8_t addr, Lsm303Axis *result)
Read the accelerometer information.
Definition: lsm303d.c:118
f32_t hx
Hx in gauss (Float)
Definition: types.h:32
#define POWER_ADC0_I2C_ADDR
The address of the Power Board ADC (LTC2499) - deprecated, no longer used.
Definition: cfg_board.h:75
Structure defines OpenCores I2C Device.
Definition: dev_i2c.h:55
Watchdog driver.
#define OCTOL_I2C_DEV
Octopus large I2C device.
Definition: cfg_board.h:89
const char * errGetDescr()
Returns the last error description, if any, else null.
Definition: err.c:57
bool max123xConvert(I2C_Device *dev, i2cAddr addr, int ch, uint16_t *result)
Performs a single conversion of a specific channel.
Definition: max123x.c:56
bool prmsID(I2C_Device *dev, uint8_t addr, uint8_t *id)
Returns the burned ID of the PROMiS device.
Definition: promis.c:41
bool sht21Temp(I2C_Device *dev, uint8_t addr, int *answer)
Starts and reads the temperatures from SHT21 at I2C address &#39;addr&#39; (hold master mode); puts the resul...
Definition: sht21.c:76
void timeDelay(uint32_t msec)
Simple busy-wait delay.
Definition: tm.c:18
f32_t hz
Hz in gauss (Float)
Definition: types.h:34
Magnet configuration.
Definition: lsm303d.h:98
Clock enable.
Definition: octocpld.h:40
#define OCTOL_MUXB_I2C_ADDR
Octopus large I2C MUX base address.
Definition: cfg_board.h:95
bool max123xSetup(I2C_Device *dev, i2cAddr addr, int ref, bool extclk, bool bipolar)
Writes the setup register of the MAX123x.
Definition: max123x.c:38
void gpioPinSet(int pin, bool high)
Sets the pin state.
Definition: gpio.c:35
GPIO is output.
Definition: gpio.h:36
Structure defines data from a compass/tilt/gyro sensor.
Definition: types.h:22
PCA9548 I2C mux driver.
Definition: shell_verify.c:46
PMT On register.
Definition: octocpld.h:38
#define LSM303D_I2C_ADDR
LSM303D Address.
Definition: cfg_board.h:57
Manages the global system error.
MAX123x multichannel ADC driver.
bool lsm303DValid(I2C_Device *dev, uint8_t addr, bool *isLSM303)
Checks whether or not the LSM303D is valid.
Definition: lsm303d.c:92
Simple timer functions.
bool ahrsRead(I2C_Device *dev, uint8_t addr, CompassData *data)
Reads all data from the AHRS.
Definition: ahrs.c:99
bool ocWrite(I2C_Device *dev, uint8_t addr, OCReg reg, uint32_t value)
Writes one of the CPLD registers.
Definition: octocpld.c:31
void errClear()
Clears the current error.
Definition: err.c:46
#define GPIO_AHRS_ENABLE
Defines GPIO pins.
Definition: gpio.h:42
f32_t ax
Ax in g (Float)
Definition: types.h:26
void sysClearCrashDetect()
Clear crash detect.
Definition: sys.c:322
f32_t fltFromI16(int16_t val, int fBits)
Takes an integer value and converts it to a float.
Definition: float.c:122
uint32_t errGet()
Returns the last error code, or null.
Definition: err.c:74
This module is responsible for distributing error codes.
#define SHT21_I2C_ADDR
SHT21 I2C Address.
Definition: cfg_board.h:43
bool lsm303DMagnetRead(I2C_Device *dev, uint8_t addr, Lsm303Axis *result)
Read the magnet information.
Definition: lsm303d.c:106
This driver is to read the SHT21 I2C temperature and humidity sensor.
#define AHRS_I2C_SEC_ADDR
AHRS I2C Address.
Definition: cfg_board.h:46
#define OCTO_PROMIS_I2C_ADDR
Generic PROMiS I2C address.
Definition: cfg_board.h:109
bool lsm303DAccelCfg(I2C_Device *dev, uint8_t addr, Lsm303DAccCfg config)
Set the accelerometer configuration.
Definition: lsm303d.c:154
bool lsm303DCfg(I2C_Device *dev, uint8_t addr, Lsm303DCfg config)
Sets the generic device configuration parameters.
Definition: lsm303d.c:179
static bool pca9548_select(I2C_Device *dev, int addr, int ch)
Select a specific channel on the PCA9548.
Definition: pca9548.h:40
This driver interfaces with the PROMiS PMT ASIC.
This driver encapsulates the functionality of the CPLD on the octopus board.
Driver for the ST LSM303Dx Compass sensor.
f32_t hy
Hy in gauss (Float)
Definition: types.h:33
static void wdogFeed()
Feed the watchdog.
Definition: watchdog.h:32
static bool ocWakeUp(I2C_Device *dev, uint8_t addr)
Wakes up the octopus board, apparently it needs it.
Definition: octocpld.h:76
This module implements parsing and formating of strings and integers.
f32_t ay
Ay in g (Float)
Definition: types.h:27
Configures the board-specific peripherals, like I2C, SPI etc...
uint8_t magScale
Magnet scale, use one of LSM303D_MAGSCALEE_*.
Definition: lsm303d.h:99
int32_t fltToI32(f32_t value, uint32_t multiplier)
This takes a f32_t IEEE 754 single precision floating point, and converts it to a multiplied integer...
Definition: float.c:90