execute all tests just once
[Arduino] / c2_ulx3s_test / dac.cpp
1 /* Test connectivity of audio jack DAC
2 ** it will check do all FPGA DAC lines have
3 ** connection to DAC resistors network.
4 ** This check cannot detect does signal
5 ** really appears on audio jack.
6
7 *  audio pins should have pull-up enabled in the bitstream
8 *  pulling down any of the bits on each channel should result in all 4 bits
9 *  reading in this channel be 0x0, otherwise all bits will 0xF 
10 *  any other value indicates bits connection error
11 *  
12 *  Todo: if probe bit is not connected,
13 *  complete checkword will fail. Construct better boolean
14 *  algebra so that using another probe bit reveals one disconnected line
15 */
16 #include <Arduino.h>
17
18 // additional gpio for DAC lines testing (not integrated into arduino yet)
19 // this needs special bitstream with gpio 64-75 (bits 0-11) connected to
20 // 12 DAC resistor network
21 volatile uint32_t *gpio2_out = (uint32_t *) 0xfffff840;
22 volatile uint32_t *gpio2_ctl = (uint32_t *) 0xfffff844;
23 volatile uint32_t *gpio2_in  = (uint32_t *) 0xfffff858;
24 const uint32_t gpio2_bits = 0xFFF; // all bits/pins 0-11
25
26 void dac_init()
27 {
28   *gpio2_ctl &= ~gpio2_bits; // inputs (output disabled)
29   *gpio2_out &= ~gpio2_bits; // output default low when enabled
30 }
31
32 // 4-bit value converted to 4-byte string "3210"
33 void dac_decode(char *a, uint8_t v)
34 {
35   for(uint8_t i = 0; i < 4; i++)
36   {
37     a[3-i] = v & 1 ? '_' : '0'+i;
38     v >>= 1;
39   }
40   a[4] = '\0'; // null-string termination
41 }
42
43
44 int dac_read(char *a)
45 {
46   int ret = 0;
47   uint32_t probeword, checkword, difference;
48   // static uint8_t counter = 0; // moving bit for detection state
49   uint32_t i;
50   // testword 32-cycle
51   uint32_t fail = 0; // reset fail flags
52   difference = 0; // reset difference register
53   // this for-loop should find and indentify
54   // disconnected or faulty bits in DAC resistor network
55   for(i = 0; i < 32; i++)
56   {
57     probeword = (((i & B100)<<6)  | ((i & B10)<<3) | (i & B1)) << ((i >> 3) & 3);
58     checkword = 0xFFF & ~( (0xF*((i & B100)<<6))  | (0xF*((i & B10)<<3)) | (0xF*(i & B1)) );
59     *gpio2_ctl = (*gpio2_ctl & ~gpio2_bits) | probeword;
60     delay(1); // wait for change to take effect
61     // any difference between checkword and read bits will set a bit in difference register 
62     uint32_t error_bits = checkword ^ *gpio2_in;
63     difference |= probeword & error_bits;
64     fail |= error_bits;
65   }
66   difference &= 0xFFF; // final bitmask
67   char dac_l[5], dac_r[5], dac_v[5];
68   dac_decode(dac_l, difference);
69   dac_decode(dac_r, difference >> 4);
70   dac_decode(dac_v, difference >> 8);
71   sprintf(a, "DAC: L%s %s R%s %s V%s %s\n",
72       dac_l,
73       (fail & 0x00F) == 0 ? " OK " : "FAIL",
74       dac_r,
75       (fail & 0x0F0) == 0 ? " OK " : "FAIL",
76       dac_v,
77       (fail & 0xF00) == 0 ? " OK " : "FAIL"
78   );
79   if ((fail & 0xFFF) == 0) ret++;
80   return ret;
81 }