Better RNG test.
[goodfet] / client / GoodFETEM260.py
1 #!/usr/bin/env python
2 # GoodFET EM260 Radio Client
3
4 # (C) 2010 Travis Goodspeed <travis at radiantmachines.com>
5 #
6 # This code is being rewritten and refactored.  You've been warned!
7
8 # The EM260 is almost textbook SPI, except that the response cannot be
9 # read until after the nHOST_INT pin of the EM260 drops low and a dummy
10 # byte is read.  That is, the sequence will look like the following:
11
12 # Transmit Host->Slave Data
13 # while(nHOST_INT); //Sleep until ready.
14 # Recv Dummy Byte
15 # Recv Slave->Host Data
16
17 # The delay is mandatory.
18
19 import sys, time, string, cStringIO, struct, glob, serial, os;
20
21 from GoodFETSPI import GoodFETSPI;
22
23 class GoodFETEM260(GoodFETSPI):
24     EM260APP=0x01;
25     seq=0;
26     def EM260trans(self,data,retry=1):
27         """Exchange data by EM260 SPI. (Slightly nonstandard.)"""
28         
29         if retry==0:
30             #Retries exceeded.  Send a trivial command to clear error.
31             data=[0x0A,0xA7];
32         self.writecmd(0x01,0x82,len(data),data);
33         
34         
35         try:
36             reply=ord(self.data[0]);
37             if(reply==0x00):
38                 #print "Warning: EM260 rebooted.";
39                 return self.EM260trans(data,retry-1);
40             if(reply==0x02):
41                 #print "Error: Aborted Transaction.";
42                 return self.EM260trans(data,retry-1);
43             if(reply==0x03):
44                 print "Error: Missing Frame Terminator.";
45                 return self.data;
46             if(reply==0x04):
47                 print "Error: Reserved Error.  (Access denied?)";
48                 return self.data;
49         except:
50             print "Error in EM260trans.";
51         return self.data;
52     
53     def EZSPtrans(self,frame):
54         """Send an EZSP frame."""
55         data=self.EM260trans([0xFE,len(frame)+2,
56                               self.seq&0xFF,0x00,
57                               ]+frame+[
58                               0xA7]);
59         #s="EZSP< ";
60         #for foo in data:
61         #    s=s+"%02x " % ord(foo);
62         #print s;
63         
64         if ord(data[0])!=0xFE:
65             print "EZSP error: 0x%02x" % ord(data[0]);
66         if ord(data[4])==0x58:
67             print "EZSP Invalid Command";
68             return None;
69         if frame[0]!=ord(data[4]):
70             print "EZSP warning: Command 0x%02x returned type 0x%02x." % (
71                 frame[0],ord(data[4]));
72         self.seq=self.seq+1;
73         return data;
74         
75     def peek8(self,adr):
76         """Read a byte from the given address.  Untested."""
77         
78         data=self.EZSPtrans([0x47,adr&0xFF,10]);
79         
80         return ord(data[6]);
81     def poke8(self,adr,val):
82         """Poke a value into RAM.  Untested"""
83         self.EZSPtrans([0x46,adr&0xFF,1,val&0xFF]);
84         return val;
85     def rand16(self):
86         """Read a byte from the given address."""
87         
88         data=self.EZSPtrans([0x49]);
89         if data==None:
90             print "Insufficient random data.";
91             return 0;
92         return ord(data[6])+(ord(data[7])<<8);
93     
94     def info(self):
95         """Read the info bytes."""
96         print "Ember EM26 Z-Stack SPI Module.";
97         version=self.EM260spiversion();
98         status=self.EM260spistatus();
99         print "Version: %i" % (version); 
100         print "Status:  %s" % (["dead","alive"][status]);
101     def EM260spiversion(self):
102         """Read the SPI version number from EM260."""
103         data=self.EM260trans([0x0A,0xA7]);        
104         version=ord(data[0]);
105         
106         if version==0x00:
107             return self.EM260spiversion();
108         if version==0x02:
109             return self.EM260spiversion();
110         if not version&0x80:
111             print "Version misread.";
112             return 0;
113         return version&0x7F;
114     
115     def EM260spistatus(self):
116         """Read the status bit."""
117         data=self.EM260trans([0x0B,0xA7]);
118         status=ord(data[0]);
119         
120         if status==0x00:
121             return self.EM260spistatus();
122         if status==0x02:
123             return self.EM260spistatus();
124         if not status&0x80 and status&0x40:
125             print "Status misread.";
126             return 0;
127         return status&1;