b7e966b791c46c40bb4ec0eceaccc1206c57a717
[goodfet] / client / USBFtdi.py
1 # USBFtdi.py
2 #
3 # Contains class definitions to implement a USB FTDI chip.
4
5 from USB import *
6 from USBDevice import *
7 from USBConfiguration import *
8 from USBInterface import *
9 from USBEndpoint import *
10 from USBVendor import *
11
12 from util import *
13
14 class USBFtdiVendor(USBVendor):
15     name = "USB FTDI vendor"
16
17     def setup_request_handlers(self):
18         self.request_handlers = {
19              0 : self.handle_reset_request,
20              1 : self.handle_modem_ctrl_request,
21              2 : self.handle_set_flow_ctrl_request,
22              3 : self.handle_set_baud_rate_request,
23              4 : self.handle_set_data_request,
24              5 : self.handle_get_status_request,
25              6 : self.handle_set_event_char_request,
26              7 : self.handle_set_error_char_request,
27              9 : self.handle_set_latency_timer_request,
28             10 : self.handle_get_latency_timer_request
29         }
30
31     def handle_reset_request(self, req):
32         if self.verbose > 0:
33             print(self.name, "received reset request")
34
35         self.device.maxusb_app.send_on_endpoint(0, b'')
36
37     def handle_modem_ctrl_request(self, req):
38         if self.verbose > 0:
39             print(self.name, "received modem_ctrl request")
40
41         dtr = req.value[1] & 0x01
42         rts = (req.value[1] & 0x02) >> 1
43         dtren = req.value[0] & 0x01
44         rtsen = (req.value[0] & 0x02) >> 1
45
46         if dtren:
47             print("DTR is enabled, value", dtr)
48         if rtsen:
49             print("RTS is enabled, value", rts)
50
51         self.device.maxusb_app.send_on_endpoint(0, b'')
52
53     def handle_set_flow_ctrl_request(self, req):
54         if self.verbose > 0:
55             print(self.name, "received set_flow_ctrl request")
56
57         dtr = req.value[1] & 0x01
58         if req.value[1] == 0:
59             print("SET_FLOW_CTRL to no handshaking")
60         if req.value[1] & 0x01:
61             print("SET_FLOW_CTRL for RTS/CTS handshaking")
62         if req.value[1] & 0x02:
63             print("SET_FLOW_CTRL for DTR/DSR handshaking")
64         if req.value[1] & 0x04:
65             print("SET_FLOW_CTRL for XON/XOFF handshaking")
66
67         self.device.maxusb_app.send_on_endpoint(0, b'')
68
69     def handle_set_baud_rate_request(self, req):
70         if self.verbose > 0:
71             print(self.name, "received set_baud_rate request")
72
73         dtr = req.value[1] & 0x01
74         print("baud rate set to", req.value[1])
75
76         self.device.maxusb_app.send_on_endpoint(0, b'')
77
78     def handle_set_data_request(self, req):
79         if self.verbose > 0:
80             print(self.name, "received set_data request")
81
82         self.device.maxusb_app.send_on_endpoint(0, b'')
83
84     def handle_get_status_request(self, req):
85         if self.verbose > 0:
86             print(self.name, "received get_status request")
87
88         self.device.maxusb_app.send_on_endpoint(0, b'')
89
90     def handle_set_event_char_request(self, req):
91         if self.verbose > 0:
92             print(self.name, "received set_event_char request")
93
94         self.device.maxusb_app.send_on_endpoint(0, b'')
95
96     def handle_set_error_char_request(self, req):
97         if self.verbose > 0:
98             print(self.name, "received set_error_char request")
99
100         self.device.maxusb_app.send_on_endpoint(0, b'')
101
102     def handle_set_latency_timer_request(self, req):
103         if self.verbose > 0:
104             print(self.name, "received set_latency_timer request")
105
106         self.device.maxusb_app.send_on_endpoint(0, b'')
107
108     def handle_get_latency_timer_request(self, req):
109         if self.verbose > 0:
110             print(self.name, "received get_latency_timer request")
111
112         # bullshit value
113         self.device.maxusb_app.send_on_endpoint(0, b'\x01')
114
115
116 class USBFtdiInterface(USBInterface):
117     name = "USB FTDI interface"
118
119     def __init__(self, verbose=0):
120         descriptors = { }
121
122         endpoints = [
123             USBEndpoint(
124                 1,          # endpoint number
125                 USBEndpoint.direction_out,
126                 USBEndpoint.transfer_type_bulk,
127                 USBEndpoint.sync_type_none,
128                 USBEndpoint.usage_type_data,
129                 16384,      # max packet size
130                 0,          # polling interval, see USB 2.0 spec Table 9-13
131                 self.handle_data_available      # handler function
132             ),
133             USBEndpoint(
134                 3,          # endpoint number
135                 USBEndpoint.direction_in,
136                 USBEndpoint.transfer_type_bulk,
137                 USBEndpoint.sync_type_none,
138                 USBEndpoint.usage_type_data,
139                 16384,      # max packet size
140                 0,          # polling interval, see USB 2.0 spec Table 9-13
141                 self.handle_buffer_available    # handler function
142             )
143         ]
144
145         # TODO: un-hardcode string index (last arg before "verbose")
146         USBInterface.__init__(
147                 self,
148                 0,          # interface number
149                 0,          # alternate setting
150                 0xff,       # interface class: vendor-specific
151                 0xff,       # subclass: vendor-specific
152                 0xff,       # protocol: vendor-specific
153                 0,          # string index
154                 verbose,
155                 endpoints,
156                 descriptors
157         )
158
159     def handle_buffer_available(self):
160         pass
161
162     def handle_data_available(self, data):
163         pass
164
165
166 class USBFtdiDevice(USBDevice):
167     name = "USB FTDI device"
168
169     def __init__(self, maxusb_app, verbose=0):
170         interface = USBFtdiInterface(verbose=verbose)
171
172         config = USBConfiguration(
173                 1,                                          # index
174                 "FTDI config",                              # string desc
175                 [ interface ]                               # interfaces
176         )
177
178         USBDevice.__init__(
179                 self,
180                 maxusb_app,
181                 0,                      # device class
182                 0,                      # device subclass
183                 0,                      # protocol release number
184                 64,                     # max packet size for endpoint 0
185                 0x0304,                 # vendor id: FTDI
186                 0x0160,                 # product id: FT232 USB-Serial (UART) IC
187                 0x0001,                 # device revision
188                 "GoodFET",              # manufacturer string
189                 "FTDI Emulator",        # product string
190                 "S/N3420E",             # serial number string
191                 [ config ],
192                 verbose=verbose
193         )
194
195         self.device_vendor = USBFtdiVendor()
196         self.device_vendor.set_device(self)
197