turn ftdi driver into echo server
[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 & 0x0001
42         rts = (req.value & 0x0002) >> 1
43         dtren = (req.value & 0x0100) >> 8
44         rtsen = (req.value & 0x0200) >> 9
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         if req.value == 0x000:
58             print("SET_FLOW_CTRL to no handshaking")
59         if req.value & 0x0001:
60             print("SET_FLOW_CTRL for RTS/CTS handshaking")
61         if req.value & 0x0002:
62             print("SET_FLOW_CTRL for DTR/DSR handshaking")
63         if req.value & 0x0004:
64             print("SET_FLOW_CTRL for XON/XOFF handshaking")
65
66         self.device.maxusb_app.send_on_endpoint(0, b'')
67
68     def handle_set_baud_rate_request(self, req):
69         if self.verbose > 0:
70             print(self.name, "received set_baud_rate request")
71
72         dtr = req.value & 0x0001
73         print("baud rate set to", dtr)
74
75         self.device.maxusb_app.send_on_endpoint(0, b'')
76
77     def handle_set_data_request(self, req):
78         if self.verbose > 0:
79             print(self.name, "received set_data request")
80
81         self.device.maxusb_app.send_on_endpoint(0, b'')
82
83     def handle_get_status_request(self, req):
84         if self.verbose > 0:
85             print(self.name, "received get_status request")
86
87         self.device.maxusb_app.send_on_endpoint(0, b'')
88
89     def handle_set_event_char_request(self, req):
90         if self.verbose > 0:
91             print(self.name, "received set_event_char request")
92
93         self.device.maxusb_app.send_on_endpoint(0, b'')
94
95     def handle_set_error_char_request(self, req):
96         if self.verbose > 0:
97             print(self.name, "received set_error_char request")
98
99         self.device.maxusb_app.send_on_endpoint(0, b'')
100
101     def handle_set_latency_timer_request(self, req):
102         if self.verbose > 0:
103             print(self.name, "received set_latency_timer request")
104
105         self.device.maxusb_app.send_on_endpoint(0, b'')
106
107     def handle_get_latency_timer_request(self, req):
108         if self.verbose > 0:
109             print(self.name, "received get_latency_timer request")
110
111         # bullshit value
112         self.device.maxusb_app.send_on_endpoint(0, b'\x01')
113
114
115 class USBFtdiInterface(USBInterface):
116     name = "USB FTDI interface"
117
118     def __init__(self, verbose=0):
119         descriptors = { }
120
121         endpoints = [
122             USBEndpoint(
123                 1,          # endpoint number
124                 USBEndpoint.direction_out,
125                 USBEndpoint.transfer_type_bulk,
126                 USBEndpoint.sync_type_none,
127                 USBEndpoint.usage_type_data,
128                 16384,      # max packet size
129                 0,          # polling interval, see USB 2.0 spec Table 9-13
130                 self.handle_data_available      # handler function
131             ),
132             USBEndpoint(
133                 3,          # endpoint number
134                 USBEndpoint.direction_in,
135                 USBEndpoint.transfer_type_bulk,
136                 USBEndpoint.sync_type_none,
137                 USBEndpoint.usage_type_data,
138                 16384,      # max packet size
139                 0,          # polling interval, see USB 2.0 spec Table 9-13
140                 None        # handler function
141             )
142         ]
143
144         # TODO: un-hardcode string index (last arg before "verbose")
145         USBInterface.__init__(
146                 self,
147                 0,          # interface number
148                 0,          # alternate setting
149                 0xff,       # interface class: vendor-specific
150                 0xff,       # subclass: vendor-specific
151                 0xff,       # protocol: vendor-specific
152                 0,          # string index
153                 verbose,
154                 endpoints,
155                 descriptors
156         )
157
158     def handle_data_available(self, data):
159         s = data[1:]
160         if self.verbose > 0:
161             print(self.name, "received string", s)
162
163         s = s.replace(b'\r', b'\r\n')
164
165         reply = b'\x01\x00' + s
166
167         self.configuration.device.maxusb_app.send_on_endpoint(3, reply)
168
169
170 class USBFtdiDevice(USBDevice):
171     name = "USB FTDI device"
172
173     def __init__(self, maxusb_app, verbose=0):
174         interface = USBFtdiInterface(verbose=verbose)
175
176         config = USBConfiguration(
177                 1,                                          # index
178                 "FTDI config",                              # string desc
179                 [ interface ]                               # interfaces
180         )
181
182         USBDevice.__init__(
183                 self,
184                 maxusb_app,
185                 0,                      # device class
186                 0,                      # device subclass
187                 0,                      # protocol release number
188                 64,                     # max packet size for endpoint 0
189                 0x0403,                 # vendor id: FTDI
190                 0x6001,                 # product id: FT232 USB-Serial (UART) IC
191                 0x0001,                 # device revision
192                 "GoodFET",              # manufacturer string
193                 "FTDI Emulator",        # product string
194                 "S/N3420E",             # serial number string
195                 [ config ],
196                 verbose=verbose
197         )
198
199         self.device_vendor = USBFtdiVendor()
200         self.device_vendor.set_device(self)
201