More muck raking.
[goodfet] / client / goodfet.adc
1 #!/usr/bin/env python
2 """
3 ADC10 client (currently only supports x2274 chip, on the GoodFET31
4 board, where pin 5 of JTAG header is sampled.)
5
6 Scott Livingston  <slivingston@caltech.edu>
7 Sep 2010.
8 """
9
10 import matplotlib as mpl
11 import matplotlib.pyplot as plt
12 import time
13
14 import sys
15 from GoodFET import GoodFET
16
17 #############
18 # Some constants (not really immutable...)
19 #############
20 ADC10APP = 0x74
21 ADC10_INIT = 0x81
22 ADC10_UNINIT = 0x82
23 MONITORAPP = 0x00
24 NOK = 0x7E
25
26
27 def man_sample(count=1):
28     """Obtain a single, instantaneous ADC10 sample
29 of channel A5 (pin 5 of JTAG header on the GoodFET31 board).
30
31 This may be repeated count times (default is 1).
32 Result is returned as a list.
33 Failed samples are indicated by -1.
34 """
35     if count < 1:
36         return [-1,]
37     result = []
38     client.writecmd( ADC10APP, ADC10_INIT, 0 ) # Initialize ADC10 module
39     while count > 0:
40         data = client.writecmd( ADC10APP, 0x83, 0 ) # Get a sample
41         if len(data) > 0:
42             samp = ord(data[0]) + (ord(data[1]) << 8)
43         else:
44             samp = -1
45         result.append(samp)
46         count -= 1
47     return result
48
49 def nsample(count=10, t_sample=3, clock_div=8):
50     """Obtain a sequence of count samples, at constant rate.
51
52 (Copied from firmware/include/adc.h)
53
54 t_sample is ``sample-and-hold time''; this is written directly to
55 ADC10SHTx field of ADC10CTL0 register; possible values in binary are
56 00  =>  4 ADC10CLK ticks,
57 01  =>  8 ADC10CLK ticks,
58 10  => 16 ADC10CLK ticks,
59 11  => 64 ADC10CLK ticks.
60
61 clock_div is the value by which to divide SMCLK (which is assumed to
62 be 16 MHz), then giving ADC10CLK.  Possible values are 1..8
63 Cf. Fig. 20-1 (on page 585?) of the msp430x2xxx family manual.
64
65 To estimate the sampling rate, use
66 (SMCLK/clock_div)/(13+t_sample_ticks), where ``t_sample_ticks'' is the
67 number of ticks corresponding to t_sample (see above).  E.g., 16 MHz
68 SMCLK (as on the GoodFET31, and others?), t_sample := 11 (binary) and
69 clock_div := 8 gives a sampling rate of approx. 25.97 kSps.
70 Similarly, e.g., 16 MHz, t_sample=00, clock_div=5 yields approx. 188 kSps.
71
72 Returns a list.
73 Failure is indicated by -1 (within the list).
74 """
75     if count < 0:
76         return [-1,]
77     client.writecmd( ADC10APP, ADC10_INIT, 0 ) # Initialize ADC10 module
78     data = client.writecmd( ADC10APP, 0x84, 3, # ADC10_NSAMPLE
79                             [count & 0xff,
80                              t_sample & 0x03,
81                              clock_div & 0x0f] )
82     result = []
83     for k in range(client.count/2):
84         result.append( ord(data[k*2]) + (ord(data[k*2+1]) << 8) )
85     return result
86
87 #############
88 # Main entry: 
89 #############
90 #if __name__ == "__main__":
91 if len(sys.argv) == 1:
92     print "Usage: %s verb [objects]\n" % sys.argv[0]
93     print "%s sample [N]" % sys.argv[0]
94     print "%s sequence [N]" % sys.argv[0]
95     print """
96 Warning: only known to work for x2274 chip, on GoodFET31 board.
97 """
98     sys.exit()
99
100 # Initialize and open connection to GoodFET
101 client = GoodFET()
102 client.verbose = False # Dump activity to terminal
103 client.serInit( timeout=10 ) # UART comm timeout (in seconds)
104
105
106 # Handle each possible ADC10 verb in turn
107
108 if sys.argv[1] == "sample": #0x83
109     if len(sys.argv) == 2:
110         count = 1
111         print "Requesting a single sample..."
112     else:
113         count = int(sys.argv[2])
114         if count < 1:
115             print "Error: number of requested samples must be at least 1."
116             exit(-1)
117         print "Requesting %d samples..." % count
118     result = man_sample(count)
119     print result
120
121 elif sys.argv[1] == "sequence":
122     if len(sys.argv) == 2:
123         count = 0
124         print "Requesting max sampling sequence length..."
125     else:
126         count = int(sys.argv[2])
127         if count < 1:
128             print "Error: number of requested samples must be at least 1."
129             exit(-1)
130             print "Requesting sampling sequence of length %d..." % count
131     #result = nsample(count, 0, 5)
132     #print result
133     while True:
134         result = nsample(count, 0, 5)
135         plt.clf()
136         plt.plot(result,'.-')
137         plt.ylim([0, 1023])
138         plt.draw()
139         time.sleep(.3)
140         
141     #plt.savefig('figs/test-' + str(int(time.time())) + '.png')
142