summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-10-03 23:08:11 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-10-03 23:08:11 +0000
commitd16fe2d36a0881a1bf4f65b945087a10962ed33a (patch)
treea1b6b5144dcb46b24db59eb952215bf0488fe6f8
parent20e704ba78d82f65084d0b27717c5c748908bd97 (diff)
downloadrockbox-d16fe2d36a0881a1bf4f65b945087a10962ed33a.tar.gz
rockbox-d16fe2d36a0881a1bf4f65b945087a10962ed33a.zip
implement usb_drv_release_endpoint() and usb_drv_request_endpoint() (a.k.a. fix red)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18705 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/isp1583.c1587
1 files changed, 806 insertions, 781 deletions
diff --git a/firmware/drivers/isp1583.c b/firmware/drivers/isp1583.c
index 34c5db1faa..62c16e880c 100644
--- a/firmware/drivers/isp1583.c
+++ b/firmware/drivers/isp1583.c
@@ -1,785 +1,810 @@
1/*************************************************************************** 1/***************************************************************************
2 * __________ __ ___. 2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2006 by Tomasz Malesinski 10 * Copyright (C) 2006 by Tomasz Malesinski
11 * Copyright (C) 2008 by Maurus Cuelenaere 11 * Copyright (C) 2008 by Maurus Cuelenaere
12 * 12 *
13 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License 14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2 15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version. 16 * of the License, or (at your option) any later version.
17 * 17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied. 19 * KIND, either express or implied.
20 * 20 *
21 ****************************************************************************/ 21 ****************************************************************************/
22 22
23#include "config.h" 23#include "config.h"
24#include "usb_ch9.h" 24#include "usb_ch9.h"
25#include "usb_drv.h" 25#include "usb_drv.h"
26#include "usb_core.h" 26#include "usb_core.h"
27#include "isp1583.h" 27#include "isp1583.h"
28#include "thread.h" 28#include "thread.h"
29#include "logf.h" 29#include "logf.h"
30#include <stdio.h> 30#include <stdio.h>
31 31
32#define DIR_RX 0 32#define DIR_RX 0
33#define DIR_TX 1 33#define DIR_TX 1
34 34
35struct usb_endpoint 35struct usb_endpoint
36{ 36{
37 unsigned char *out_buf; 37 unsigned char *out_buf;
38 short out_len; 38 short out_len;
39 short out_ptr; 39 short out_ptr;
40 void (*out_done)(int, unsigned char *, int); 40 void (*out_done)(int, unsigned char *, int);
41 unsigned char out_in_progress; 41 unsigned char out_in_progress;
42 42
43 unsigned char *in_buf; 43 unsigned char *in_buf;
44 short in_min_len; 44 short in_min_len;
45 short in_max_len; 45 short in_max_len;
46 short in_ptr; 46 short in_ptr;
47 void (*in_done)(int, unsigned char *, int); 47 void (*in_done)(int, unsigned char *, int);
48 unsigned char in_ack; 48 unsigned char in_ack;
49 49
50 unsigned char halt[2]; 50 unsigned char halt[2];
51 unsigned char enabled[2]; 51 unsigned char enabled[2];
52 short max_pkt_size[2]; 52 short max_pkt_size[2];
53 short type; 53 short type;
54}; 54 char allocation;
55 55};
56static unsigned char setup_pkt_buf[8]; 56
57static struct usb_endpoint endpoints[NUM_ENDPOINTS]; 57static unsigned char setup_pkt_buf[8];
58 58static struct usb_endpoint endpoints[NUM_ENDPOINTS];
59static bool high_speed_mode = false; 59
60 60static bool high_speed_mode = false;
61static inline void or_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value) 61
62{ 62static inline void or_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value)
63 set_int_value(*a, *b, (r | value)); 63{
64} 64 set_int_value(*a, *b, (r | value));
65static inline void bc_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value) 65}
66{ 66static inline void bc_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value)
67 set_int_value(*a, *b, (r & ~value)); 67{
68} 68 set_int_value(*a, *b, (r & ~value));
69 69}
70static inline void nop_f(void) 70
71{ 71static inline void nop_f(void)
72 yield(); 72{
73} 73 yield();
74 74}
75#define NOP asm volatile("nop\n"); 75
76 76#define NOP asm volatile("nop\n");
77static inline int ep_index(int n, bool dir) 77
78{ 78static inline int ep_index(int n, bool dir)
79 return (n << 1) | dir; 79{
80} 80 return (n << 1) | dir;
81 81}
82static inline bool epidx_dir(int idx) 82
83{ 83static inline bool epidx_dir(int idx)
84 return idx & 1; 84{
85} 85 return idx & 1;
86 86}
87static inline int epidx_n(int idx) 87
88{ 88static inline int epidx_n(int idx)
89 return idx >> 1; 89{
90} 90 return idx >> 1;
91 91}
92static inline void usb_select_endpoint(int idx) 92
93{ 93static inline void usb_select_endpoint(int idx)
94 /* Select the endpoint */ 94{
95 ISP1583_DFLOW_EPINDEX = idx; 95 /* Select the endpoint */
96 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns. 96 ISP1583_DFLOW_EPINDEX = idx;
97 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns. 97 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
98 */ 98 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
99 NOP; 99 */
100} 100 NOP;
101 101}
102static inline void usb_select_setup_endpoint(void) 102
103{ 103static inline void usb_select_setup_endpoint(void)
104 /* Select the endpoint */ 104{
105 ISP1583_DFLOW_EPINDEX = DFLOW_EPINDEX_EP0SETUP; 105 /* Select the endpoint */
106 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns. 106 ISP1583_DFLOW_EPINDEX = DFLOW_EPINDEX_EP0SETUP;
107 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns. 107 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
108 */ 108 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
109 NOP; 109 */
110} 110 NOP;
111 111}
112static void usb_setup_endpoint(int idx, int max_pkt_size, int type) 112
113{ 113static void usb_setup_endpoint(int idx, int max_pkt_size, int type)
114 if(epidx_n(idx)!=0) 114{
115 { 115 if(epidx_n(idx)!=0)
116 usb_select_endpoint(idx); 116 {
117 ISP1583_DFLOW_MAXPKSZ = max_pkt_size & 0x7FF; 117 usb_select_endpoint(idx);
118 ISP1583_DFLOW_EPTYPE = (DFLOW_EPTYPE_NOEMPKT | DFLOW_EPTYPE_DBLBUF | (type & 0x3)); 118 ISP1583_DFLOW_MAXPKSZ = max_pkt_size & 0x7FF;
119 119 ISP1583_DFLOW_EPTYPE = (DFLOW_EPTYPE_NOEMPKT | DFLOW_EPTYPE_DBLBUF | (type & 0x3));
120 /* clear buffer ... */ 120
121 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF; 121 /* clear buffer ... */
122 /* ... twice because of double buffering */ 122 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
123 usb_select_endpoint(idx); 123 /* ... twice because of double buffering */
124 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF; 124 usb_select_endpoint(idx);
125 } 125 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
126 126 }
127 struct usb_endpoint *ep; 127
128 ep = &(endpoints[epidx_n(idx)]); 128 struct usb_endpoint *ep;
129 ep->halt[epidx_dir(idx)] = 0; 129 ep = &(endpoints[epidx_n(idx)]);
130 ep->enabled[epidx_dir(idx)] = 0; 130 ep->halt[epidx_dir(idx)] = 0;
131 ep->out_in_progress = 0; 131 ep->enabled[epidx_dir(idx)] = 0;
132 ep->in_min_len = -1; 132 ep->out_in_progress = 0;
133 ep->in_ack = 0; 133 ep->in_min_len = -1;
134 ep->type = type; 134 ep->in_ack = 0;
135 ep->max_pkt_size[epidx_dir(idx)] = max_pkt_size; 135 ep->type = type;
136} 136 ep->max_pkt_size[epidx_dir(idx)] = max_pkt_size;
137 137}
138static void usb_enable_endpoint(int idx) 138
139{ 139static void usb_enable_endpoint(int idx)
140 if(epidx_n(idx)!=0) 140{
141 { 141 if(epidx_n(idx)!=0)
142 usb_select_endpoint(idx); 142 {
143 /* Enable interrupt */ 143 usb_select_endpoint(idx);
144 or_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx)); 144 /* Enable interrupt */
145 /* Enable endpoint */ 145 or_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
146 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE; 146 /* Enable endpoint */
147 } 147 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE;
148 148 }
149 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 1; 149
150} 150 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 1;
151/* 151}
152static void usb_disable_endpoint(int idx, bool set_struct) 152/*
153{ 153static void usb_disable_endpoint(int idx, bool set_struct)
154 usb_select_endpoint(idx); 154{
155 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE; 155 usb_select_endpoint(idx);
156 bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx)); 156 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
157 157 bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
158 if(set_struct) 158
159 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0; 159 if(set_struct)
160} 160 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0;
161*/ 161}
162static int usb_get_packet(unsigned char *buf, int max_len) 162*/
163{ 163static int usb_get_packet(unsigned char *buf, int max_len)
164 int len, i; 164{
165 len = ISP1583_DFLOW_BUFLEN; 165 int len, i;
166 166 len = ISP1583_DFLOW_BUFLEN;
167 if (max_len < 0 || max_len > len) 167
168 max_len = len; 168 if (max_len < 0 || max_len > len)
169 169 max_len = len;
170 i = 0; 170
171 while (i < len) 171 i = 0;
172 { 172 while (i < len)
173 unsigned short d = ISP1583_DFLOW_DATA; 173 {
174 if (i < max_len) 174 unsigned short d = ISP1583_DFLOW_DATA;
175 buf[i] = d & 0xff; 175 if (i < max_len)
176 i++; 176 buf[i] = d & 0xff;
177 if (i < max_len) 177 i++;
178 buf[i] = (d >> 8) & 0xff; 178 if (i < max_len)
179 i++; 179 buf[i] = (d >> 8) & 0xff;
180 } 180 i++;
181 return max_len; 181 }
182} 182 return max_len;
183 183}
184static int usb_receive(int n) 184
185{ 185static int usb_receive(int n)
186 logf("usb_receive(%d)", n); 186{
187 int len; 187 logf("usb_receive(%d)", n);
188 188 int len;
189 if (endpoints[n].halt[DIR_RX] 189
190 || !endpoints[n].enabled[DIR_RX] 190 if (endpoints[n].halt[DIR_RX]
191 || endpoints[n].in_min_len < 0 191 || !endpoints[n].enabled[DIR_RX]
192 || !endpoints[n].in_ack) 192 || endpoints[n].in_min_len < 0
193 return -1; 193 || !endpoints[n].in_ack)
194 194 return -1;
195 endpoints[n].in_ack = 0; 195
196 196 endpoints[n].in_ack = 0;
197 usb_select_endpoint(ep_index(n, DIR_RX)); 197
198 198 usb_select_endpoint(ep_index(n, DIR_RX));
199 len = usb_get_packet(endpoints[n].in_buf + endpoints[n].in_ptr, 199
200 endpoints[n].in_max_len - endpoints[n].in_ptr); 200 len = usb_get_packet(endpoints[n].in_buf + endpoints[n].in_ptr,
201 endpoints[n].in_ptr += len; 201 endpoints[n].in_max_len - endpoints[n].in_ptr);
202 if (endpoints[n].in_ptr >= endpoints[n].in_min_len) { 202 endpoints[n].in_ptr += len;
203 endpoints[n].in_min_len = -1; 203 if (endpoints[n].in_ptr >= endpoints[n].in_min_len) {
204 if (endpoints[n].in_done) 204 endpoints[n].in_min_len = -1;
205 (*(endpoints[n].in_done))(n, endpoints[n].in_buf, 205 if (endpoints[n].in_done)
206 endpoints[n].in_ptr); 206 (*(endpoints[n].in_done))(n, endpoints[n].in_buf,
207 } 207 endpoints[n].in_ptr);
208 logf("receive_end"); 208 }
209 return 0; 209 logf("receive_end");
210} 210 return 0;
211 211}
212static bool usb_out_buffer_full(int ep) 212
213{ 213static bool usb_out_buffer_full(int ep)
214 usb_select_endpoint(ep_index(ep, DIR_TX)); 214{
215 if (ISP1583_DFLOW_EPTYPE & 4) /* Check if type=bulk and double buffering is set */ 215 usb_select_endpoint(ep_index(ep, DIR_TX));
216 return (ISP1583_DFLOW_BUFSTAT & 3) == 3; /* Return true if both buffers are filled */ 216 if (ISP1583_DFLOW_EPTYPE & 4) /* Check if type=bulk and double buffering is set */
217 else 217 return (ISP1583_DFLOW_BUFSTAT & 3) == 3; /* Return true if both buffers are filled */
218 return (ISP1583_DFLOW_BUFSTAT & 3) != 0; /* Return true if one of the buffers are filled */ 218 else
219} 219 return (ISP1583_DFLOW_BUFSTAT & 3) != 0; /* Return true if one of the buffers are filled */
220 220}
221static int usb_send(int n) 221
222{ 222static int usb_send(int n)
223 logf("usb_send(%d)", n); 223{
224 int max_pkt_size, len; 224 logf("usb_send(%d)", n);
225 int i; 225 int max_pkt_size, len;
226 unsigned char *p; 226 int i;
227 227 unsigned char *p;
228 if (endpoints[n].halt[DIR_TX] 228
229 || !endpoints[n].enabled[DIR_TX] 229 if (endpoints[n].halt[DIR_TX]
230 || !endpoints[n].out_in_progress) 230 || !endpoints[n].enabled[DIR_TX]
231 { 231 || !endpoints[n].out_in_progress)
232 logf("NOT SEND TO EP!"); 232 {
233 return -1; 233 logf("NOT SEND TO EP!");
234 } 234 return -1;
235 235 }
236 if (endpoints[n].out_ptr < 0) 236
237 { 237 if (endpoints[n].out_ptr < 0)
238 endpoints[n].out_in_progress = 0; 238 {
239 if (endpoints[n].out_done) 239 endpoints[n].out_in_progress = 0;
240 (*(endpoints[n].out_done))(n, endpoints[n].out_buf, 240 if (endpoints[n].out_done)
241 endpoints[n].out_len); 241 (*(endpoints[n].out_done))(n, endpoints[n].out_buf,
242 logf("ALREADY SENT TO EP!"); 242 endpoints[n].out_len);
243 return -1; 243 logf("ALREADY SENT TO EP!");
244 } 244 return -1;
245 245 }
246 if (usb_out_buffer_full(n)) 246
247 { 247 if (usb_out_buffer_full(n))
248 logf("BUFFER FULL!"); 248 {
249 return -1; 249 logf("BUFFER FULL!");
250 } 250 return -1;
251 251 }
252 usb_select_endpoint(ep_index(n, DIR_TX)); 252
253 max_pkt_size = endpoints[n].max_pkt_size[DIR_TX]; 253 usb_select_endpoint(ep_index(n, DIR_TX));
254 len = endpoints[n].out_len - endpoints[n].out_ptr; 254 max_pkt_size = endpoints[n].max_pkt_size[DIR_TX];
255 if (len > max_pkt_size) 255 len = endpoints[n].out_len - endpoints[n].out_ptr;
256 len = max_pkt_size; 256 if (len > max_pkt_size)
257 257 len = max_pkt_size;
258 if(len < max_pkt_size) 258
259 ISP1583_DFLOW_BUFLEN = len; 259 if(len < max_pkt_size)
260 260 ISP1583_DFLOW_BUFLEN = len;
261 p = endpoints[n].out_buf + endpoints[n].out_ptr; 261
262 i = 0; 262 p = endpoints[n].out_buf + endpoints[n].out_ptr;
263 while (len - i >= 2) { 263 i = 0;
264 ISP1583_DFLOW_DATA = p[i] | (p[i + 1] << 8); 264 while (len - i >= 2) {
265 i += 2; 265 ISP1583_DFLOW_DATA = p[i] | (p[i + 1] << 8);
266 } 266 i += 2;
267 if (i < len) 267 }
268 ISP1583_DFLOW_DATA = p[i]; 268 if (i < len)
269 269 ISP1583_DFLOW_DATA = p[i];
270 endpoints[n].out_ptr += len; 270
271 271 endpoints[n].out_ptr += len;
272/* 272
273 if (endpoints[n].out_ptr == endpoints[n].out_len 273/*
274 && len < max_pkt_size) 274 if (endpoints[n].out_ptr == endpoints[n].out_len
275*/ 275 && len < max_pkt_size)
276 if (endpoints[n].out_ptr == endpoints[n].out_len) 276*/
277 endpoints[n].out_ptr = -1; 277 if (endpoints[n].out_ptr == endpoints[n].out_len)
278 278 endpoints[n].out_ptr = -1;
279 logf("send_end"); 279
280 return 0; 280 logf("send_end");
281} 281 return 0;
282 282}
283static void usb_stall_endpoint(int idx) 283
284{ 284static void usb_stall_endpoint(int idx)
285 usb_select_endpoint(idx); 285{
286 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STALL; 286 usb_select_endpoint(idx);
287 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 1; 287 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STALL;
288} 288 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 1;
289 289}
290static void usb_unstall_endpoint(int idx) 290
291{ 291static void usb_unstall_endpoint(int idx)
292 usb_select_endpoint(idx); 292{
293 ISP1583_DFLOW_CTRLFUN &= ~DFLOW_CTRLFUN_STALL; 293 usb_select_endpoint(idx);
294 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE; 294 ISP1583_DFLOW_CTRLFUN &= ~DFLOW_CTRLFUN_STALL;
295 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE; 295 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
296 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF; 296 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE;
297 if (epidx_dir(idx) == DIR_TX) 297 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
298 endpoints[epidx_n(idx)].out_in_progress = 0; 298 if (epidx_dir(idx) == DIR_TX)
299 else 299 endpoints[epidx_n(idx)].out_in_progress = 0;
300 { 300 else
301 endpoints[epidx_n(idx)].in_min_len = -1; 301 {
302 endpoints[epidx_n(idx)].in_ack = 0; 302 endpoints[epidx_n(idx)].in_min_len = -1;
303 } 303 endpoints[epidx_n(idx)].in_ack = 0;
304 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 0; 304 }
305} 305 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 0;
306 306}
307static void usb_status_ack(int ep, int dir) 307
308{ 308static void usb_status_ack(int ep, int dir)
309 logf("usb_status_ack(%d)", dir); 309{
310 usb_select_endpoint(ep_index(ep, dir)); 310 logf("usb_status_ack(%d)", dir);
311 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS; 311 usb_select_endpoint(ep_index(ep, dir));
312} 312 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS;
313 313}
314static void usb_data_stage_enable(int ep, int dir) 314
315{ 315static void usb_data_stage_enable(int ep, int dir)
316 logf("usb_data_stage_enable(%d)", dir); 316{
317 usb_select_endpoint(ep_index(ep, dir)); 317 logf("usb_data_stage_enable(%d)", dir);
318 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_DSEN; 318 usb_select_endpoint(ep_index(ep, dir));
319} 319 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_DSEN;
320 320}
321static void usb_handle_setup_rx(void) 321
322{ 322static void usb_handle_setup_rx(void)
323 int len; 323{
324 usb_select_setup_endpoint(); 324 int len;
325 len = usb_get_packet(setup_pkt_buf, 8); 325 usb_select_setup_endpoint();
326 326 len = usb_get_packet(setup_pkt_buf, 8);
327 if (len == 8) 327
328 usb_core_control_request((struct usb_ctrlrequest*)setup_pkt_buf); 328 if (len == 8)
329 else 329 usb_core_control_request((struct usb_ctrlrequest*)setup_pkt_buf);
330 { 330 else
331 usb_drv_stall(0, true, false); 331 {
332 usb_drv_stall(0, true, true); 332 usb_drv_stall(0, true, false);
333 logf("usb_handle_setup_rx() failed"); 333 usb_drv_stall(0, true, true);
334 return; 334 logf("usb_handle_setup_rx() failed");
335 } 335 return;
336 336 }
337 logf("usb_handle_setup_rx(): %02x %02x %02x %02x %02x %02x %02x %02x", setup_pkt_buf[0], setup_pkt_buf[1], setup_pkt_buf[2], setup_pkt_buf[3], setup_pkt_buf[4], setup_pkt_buf[5], setup_pkt_buf[6], setup_pkt_buf[7]); 337
338} 338 logf("usb_handle_setup_rx(): %02x %02x %02x %02x %02x %02x %02x %02x", setup_pkt_buf[0], setup_pkt_buf[1], setup_pkt_buf[2], setup_pkt_buf[3], setup_pkt_buf[4], setup_pkt_buf[5], setup_pkt_buf[6], setup_pkt_buf[7]);
339 339}
340static void usb_handle_data_int(int ep, int dir) 340
341{ 341static void usb_handle_data_int(int ep, int dir)
342 int len; 342{
343 if (dir == DIR_TX) 343 int len;
344 len = usb_send(ep); 344 if (dir == DIR_TX)
345 else 345 len = usb_send(ep);
346 { 346 else
347 len = usb_receive(ep); 347 {
348 endpoints[ep].in_ack = 1; 348 len = usb_receive(ep);
349 } 349 endpoints[ep].in_ack = 1;
350 logf("usb_handle_data_int(%d, %d) finished", ep, dir); 350 }
351} 351 logf("usb_handle_data_int(%d, %d) finished", ep, dir);
352 352}
353bool usb_drv_powered(void) 353
354{ 354bool usb_drv_powered(void)
355#if 0 355{
356 return (ISP1583_INIT_OTG & INIT_OTG_BSESS_VALID) ? true : false; 356#if 0
357#else 357 return (ISP1583_INIT_OTG & INIT_OTG_BSESS_VALID) ? true : false;
358 return (ISP1583_INIT_MODE & INIT_MODE_VBUSSTAT) ? true : false; 358#else
359#endif 359 return (ISP1583_INIT_MODE & INIT_MODE_VBUSSTAT) ? true : false;
360} 360#endif
361 361}
362static void setup_endpoints(void) 362
363{ 363static void setup_endpoints(void)
364 usb_setup_endpoint(ep_index(0, DIR_RX), 64, 0); 364{
365 usb_setup_endpoint(ep_index(0, DIR_TX), 64, 0); 365 usb_setup_endpoint(ep_index(0, DIR_RX), 64, 0);
366 366 usb_setup_endpoint(ep_index(0, DIR_TX), 64, 0);
367 int i; 367
368 for(i = 1; i < NUM_ENDPOINTS-1; i++) 368 int i;
369 { 369 for(i = 1; i < NUM_ENDPOINTS-1; i++)
370 usb_setup_endpoint(ep_index(i, DIR_RX), (high_speed_mode ? 512 : 64), 2); /* 2 = TYPE_BULK */ 370 {
371 usb_setup_endpoint(ep_index(i, DIR_TX), (high_speed_mode ? 512 : 64), 2); 371 usb_setup_endpoint(ep_index(i, DIR_RX), (high_speed_mode ? 512 : 64), 2); /* 2 = TYPE_BULK */
372 } 372 usb_setup_endpoint(ep_index(i, DIR_TX), (high_speed_mode ? 512 : 64), 2);
373 373 }
374 usb_enable_endpoint(ep_index(0, DIR_RX)); 374
375 usb_enable_endpoint(ep_index(0, DIR_TX)); 375 usb_enable_endpoint(ep_index(0, DIR_RX));
376 376 usb_enable_endpoint(ep_index(0, DIR_TX));
377 for (i = 1; i < NUM_ENDPOINTS-1; i++) 377
378 { 378 for (i = 1; i < NUM_ENDPOINTS-1; i++)
379 usb_enable_endpoint(ep_index(i, DIR_RX)); 379 {
380 usb_enable_endpoint(ep_index(i, DIR_TX)); 380 usb_enable_endpoint(ep_index(i, DIR_RX));
381 } 381 usb_enable_endpoint(ep_index(i, DIR_TX));
382 382 }
383 ZVM_SPECIFIC; 383
384} 384 ZVM_SPECIFIC;
385 385}
386void usb_helper(void) 386
387{ 387void usb_helper(void)
388 if(ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ) 388{
389 { 389 if(ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ)
390 #ifdef DEBUG 390 {
391 logf("Helper detected interrupt... [%d]", current_tick); 391 #ifdef DEBUG
392 #endif 392 logf("Helper detected interrupt... [%d]", current_tick);
393 usb_drv_int(); 393 #endif
394 } 394 usb_drv_int();
395 return; 395 }
396} 396 return;
397 397}
398void usb_drv_init(void) 398
399{ 399void usb_drv_init(void)
400 /* Disable interrupt at CPU level */ 400{
401 DIS_INT_CPU_TARGET; 401 /* Disable interrupt at CPU level */
402 402 DIS_INT_CPU_TARGET;
403 /* Unlock the device's registers */ 403
404 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE; 404 /* Unlock the device's registers */
405 405 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
406 /* Soft reset the device */ 406
407 ISP1583_INIT_MODE = INIT_MODE_SFRESET; 407 /* Soft reset the device */
408 sleep(10); 408 ISP1583_INIT_MODE = INIT_MODE_SFRESET;
409 /* Enable CLKAON & GLINTENA */ 409 sleep(10);
410 ISP1583_INIT_MODE = STANDARD_INIT_MODE; 410 /* Enable CLKAON & GLINTENA */
411 411 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
412 /* Disable all OTG functions */ 412
413 ISP1583_INIT_OTG = 0; 413 /* Disable all OTG functions */
414 414 ISP1583_INIT_OTG = 0;
415#if 0 415
416 #ifdef USE_HIGH_SPEED 416#if 0
417 /* Force device to high speed */ 417 #ifdef USE_HIGH_SPEED
418 ISP1583_GEN_TSTMOD = GEN_TSTMOD_FORCEHS; 418 /* Force device to high speed */
419 high_speed_mode = true; 419 ISP1583_GEN_TSTMOD = GEN_TSTMOD_FORCEHS;
420 #endif 420 high_speed_mode = true;
421#endif 421 #endif
422 422#endif
423 #ifdef DEBUG 423
424 logf("BUS_CONF/DA0:%d MODE0/DA1: %d MODE1: %d", (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST0), (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST1), (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST2)); 424 #ifdef DEBUG
425 logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID); 425 logf("BUS_CONF/DA0:%d MODE0/DA1: %d MODE1: %d", (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST0), (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST1), (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST2));
426 //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT); 426 logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID);
427 #endif 427 //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT);
428 428 #endif
429 /*Set interrupt generation to target-specific mode + 429
430 * Set the control pipe to ACK only interrupt + 430 /*Set interrupt generation to target-specific mode +
431 * Set the IN pipe to ACK only interrupt + 431 * Set the control pipe to ACK only interrupt +
432 * Set OUT pipe to ACK and NYET interrupt 432 * Set the IN pipe to ACK only interrupt +
433 */ 433 * Set OUT pipe to ACK and NYET interrupt
434 434 */
435 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET; 435
436 /* Clear all interrupts */ 436 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET;
437 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, 0xFFFFFFFF); 437 /* Clear all interrupts */
438 /* Enable USB interrupts */ 438 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, 0xFFFFFFFF);
439 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN); 439 /* Enable USB interrupts */
440 440 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN);
441 ZVM_SPECIFIC; 441
442 442 ZVM_SPECIFIC;
443 /* Enable interrupt at CPU level */ 443
444 EN_INT_CPU_TARGET; 444 /* Enable interrupt at CPU level */
445 445 EN_INT_CPU_TARGET;
446 setup_endpoints(); 446
447 447 setup_endpoints();
448 /* Clear device address and disable it */ 448
449 ISP1583_INIT_ADDRESS = 0; 449 /* Clear device address and disable it */
450 450 ISP1583_INIT_ADDRESS = 0;
451 /* Turn SoftConnect on */ 451
452 ISP1583_INIT_MODE |= INIT_MODE_SOFTCT; 452 /* Turn SoftConnect on */
453 453 ISP1583_INIT_MODE |= INIT_MODE_SOFTCT;
454 ZVM_SPECIFIC; 454
455 455 ZVM_SPECIFIC;
456 tick_add_task(usb_helper); 456
457 457 tick_add_task(usb_helper);
458 logf("usb_init_device() finished"); 458
459} 459 logf("usb_init_device() finished");
460 460}
461int usb_drv_port_speed(void) 461
462{ 462int usb_drv_port_speed(void)
463 return (int)high_speed_mode; 463{
464} 464 return (int)high_speed_mode;
465 465}
466void usb_drv_exit(void) 466
467{ 467void usb_drv_exit(void)
468 logf("usb_drv_exit()"); 468{
469 469 logf("usb_drv_exit()");
470 /* Disable device */ 470
471 ISP1583_INIT_MODE &= ~INIT_MODE_SOFTCT; 471 /* Disable device */
472 ISP1583_INIT_ADDRESS = 0; 472 ISP1583_INIT_MODE &= ~INIT_MODE_SOFTCT;
473 473 ISP1583_INIT_ADDRESS = 0;
474 /* Disable interrupts */ 474
475 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, 0); 475 /* Disable interrupts */
476 /* and the CPU's one... */ 476 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, 0);
477 DIS_INT_CPU_TARGET; 477 /* and the CPU's one... */
478 478 DIS_INT_CPU_TARGET;
479 479
480 /* Send usb controller to suspend mode */ 480
481 ISP1583_INIT_MODE = INIT_MODE_GOSUSP; 481 /* Send usb controller to suspend mode */
482 ISP1583_INIT_MODE = 0; 482 ISP1583_INIT_MODE = INIT_MODE_GOSUSP;
483 483 ISP1583_INIT_MODE = 0;
484 tick_remove_task(usb_helper); 484
485 485 tick_remove_task(usb_helper);
486 ZVM_SPECIFIC; 486
487} 487 ZVM_SPECIFIC;
488 488}
489void usb_drv_stall(int endpoint, bool stall, bool in) 489
490{ 490void usb_drv_stall(int endpoint, bool stall, bool in)
491 logf("%sstall EP%d %s", (stall ? "" : "un"), endpoint, (in ? "RX" : "TX" )); 491{
492 if (stall) 492 logf("%sstall EP%d %s", (stall ? "" : "un"), endpoint, (in ? "RX" : "TX" ));
493 usb_stall_endpoint(ep_index(endpoint, (int)in)); 493 if (stall)
494 else 494 usb_stall_endpoint(ep_index(endpoint, (int)in));
495 usb_unstall_endpoint(ep_index(endpoint, (int)in)); 495 else
496} 496 usb_unstall_endpoint(ep_index(endpoint, (int)in));
497 497}
498bool usb_drv_stalled(int endpoint, bool in) 498
499{ 499bool usb_drv_stalled(int endpoint, bool in)
500 return (endpoints[endpoint].halt[(int)in] == 1); 500{
501} 501 return (endpoints[endpoint].halt[(int)in] == 1);
502 502}
503static void out_callback(int ep, unsigned char *buf, int len) 503
504{ 504static void out_callback(int ep, unsigned char *buf, int len)
505 (void)buf; 505{
506 logf("out_callback(%d, 0x%x, %d)", ep, &buf, len); 506 (void)buf;
507 usb_status_ack(ep, DIR_RX); 507 logf("out_callback(%d, 0x%x, %d)", ep, &buf, len);
508 usb_core_transfer_complete(ep, true, 0, len); /* 0=>status succeeded, haven't worked out status failed yet... */ 508 usb_status_ack(ep, DIR_RX);
509} 509 usb_core_transfer_complete(ep, true, 0, len); /* 0=>status succeeded, haven't worked out status failed yet... */
510 510}
511static void in_callback(int ep, unsigned char *buf, int len) 511
512{ 512static void in_callback(int ep, unsigned char *buf, int len)
513 (void)buf; 513{
514 logf("in_callback(%d, 0x%x, %d)", ep, &buf, len); 514 (void)buf;
515 usb_status_ack(ep, DIR_TX); 515 logf("in_callback(%d, 0x%x, %d)", ep, &buf, len);
516 usb_core_transfer_complete(ep, false, 0, len); 516 usb_status_ack(ep, DIR_TX);
517} 517 usb_core_transfer_complete(ep, false, 0, len);
518 518}
519int usb_drv_recv(int ep, void* ptr, int length) 519
520{ 520int usb_drv_recv(int ep, void* ptr, int length)
521 logf("usb_drv_recv(%d, 0x%x, %d)", ep, &ptr, length); 521{
522 if(ep == 0 && length == 0 && ptr == NULL) 522 logf("usb_drv_recv(%d, 0x%x, %d)", ep, &ptr, length);
523 { 523 if(ep == 0 && length == 0 && ptr == NULL)
524 usb_status_ack(ep, DIR_TX); 524 {
525 return 0; 525 usb_status_ack(ep, DIR_TX);
526 } 526 return 0;
527 endpoints[ep].in_done = in_callback; 527 }
528 endpoints[ep].in_buf = ptr; 528 endpoints[ep].in_done = in_callback;
529 endpoints[ep].in_max_len = length; 529 endpoints[ep].in_buf = ptr;
530 endpoints[ep].in_min_len = length; 530 endpoints[ep].in_max_len = length;
531 endpoints[ep].in_ptr = 0; 531 endpoints[ep].in_min_len = length;
532 if(ep == 0) 532 endpoints[ep].in_ptr = 0;
533 { 533 if(ep == 0)
534 usb_data_stage_enable(ep, DIR_RX); 534 {
535 return usb_receive(ep); 535 usb_data_stage_enable(ep, DIR_RX);
536 } 536 return usb_receive(ep);
537 else 537 }
538 return usb_receive(ep); 538 else
539} 539 return usb_receive(ep);
540 540}
541int usb_drv_send_nonblocking(int ep, void* ptr, int length) 541
542{ 542int usb_drv_send_nonblocking(int ep, void* ptr, int length)
543 /* First implement DMA... */ 543{
544 return usb_drv_send(ep, ptr, length); 544 /* First implement DMA... */
545} 545 return usb_drv_send(ep, ptr, length);
546 546}
547int usb_drv_send(int ep, void* ptr, int length) 547
548{ 548int usb_drv_send(int ep, void* ptr, int length)
549 logf("usb_drv_send_nb(%d, 0x%x, %d)", ep, &ptr, length); 549{
550 if(ep == 0 && length == 0 && ptr == NULL) 550 logf("usb_drv_send_nb(%d, 0x%x, %d)", ep, &ptr, length);
551 { 551 if(ep == 0 && length == 0 && ptr == NULL)
552 usb_status_ack(ep, DIR_RX); 552 {
553 return 0; 553 usb_status_ack(ep, DIR_RX);
554 } 554 return 0;
555 if(endpoints[ep].out_in_progress == 1) 555 }
556 return -1; 556 if(endpoints[ep].out_in_progress == 1)
557 endpoints[ep].out_done = out_callback; 557 return -1;
558 endpoints[ep].out_buf = ptr; 558 endpoints[ep].out_done = out_callback;
559 endpoints[ep].out_len = length; 559 endpoints[ep].out_buf = ptr;
560 endpoints[ep].out_ptr = 0; 560 endpoints[ep].out_len = length;
561 endpoints[ep].out_in_progress = 1; 561 endpoints[ep].out_ptr = 0;
562 if(ep == 0) 562 endpoints[ep].out_in_progress = 1;
563 { 563 if(ep == 0)
564 int rc = usb_send(ep); 564 {
565 usb_data_stage_enable(ep, DIR_TX); 565 int rc = usb_send(ep);
566 usb_drv_wait(ep, DIR_TX); 566 usb_data_stage_enable(ep, DIR_TX);
567 return rc; 567 usb_drv_wait(ep, DIR_TX);
568 } 568 return rc;
569 else 569 }
570 return usb_send(ep); 570 else
571} 571 return usb_send(ep);
572 572}
573void usb_drv_reset_endpoint(int ep, bool send) 573
574{ 574void usb_drv_reset_endpoint(int ep, bool send)
575 logf("reset endpoint(%d, %d)", ep, send); 575{
576 usb_setup_endpoint(ep_index(ep, (int)send), endpoints[ep].max_pkt_size[(int)send], endpoints[ep].type); 576 logf("reset endpoint(%d, %d)", ep, send);
577 usb_enable_endpoint(ep_index(ep, (int)send)); 577 usb_setup_endpoint(ep_index(ep, (int)send), endpoints[ep].max_pkt_size[(int)send], endpoints[ep].type);
578} 578 usb_enable_endpoint(ep_index(ep, (int)send));
579 579}
580void usb_drv_wait(int ep, bool send) 580
581{ 581void usb_drv_wait(int ep, bool send)
582 logf("usb_drv_wait(%d, %d)", ep, send); 582{
583 if(send) 583 logf("usb_drv_wait(%d, %d)", ep, send);
584 { 584 if(send)
585 while (endpoints[ep].out_in_progress) 585 {
586 nop_f(); 586 while (endpoints[ep].out_in_progress)
587 } 587 nop_f();
588 else 588 }
589 { 589 else
590 while (endpoints[ep].in_ack) 590 {
591 nop_f(); 591 while (endpoints[ep].in_ack)
592 } 592 nop_f();
593} 593 }
594 594}
595void usb_drv_cancel_all_transfers(void) 595
596{ 596void usb_drv_cancel_all_transfers(void)
597 logf("usb_drv_cancel_all_tranfers()"); 597{
598 int i; 598 logf("usb_drv_cancel_all_tranfers()");
599 599 int i;
600 for(i=0;i<NUM_ENDPOINTS-1;i++) 600
601 endpoints[i].halt[0] = endpoints[i].halt[1] = 1; 601 for(i=0;i<NUM_ENDPOINTS-1;i++)
602} 602 endpoints[i].halt[0] = endpoints[i].halt[1] = 1;
603 603}
604static void bus_reset(void) 604
605{ 605int usb_drv_request_endpoint(int dir)
606 /* Enable CLKAON & GLINTENA */ 606{
607 ISP1583_INIT_MODE = STANDARD_INIT_MODE; 607 int i, bit;
608 /* Enable USB interrupts */ 608
609 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET; 609 bit=(dir & USB_DIR_IN)? 2:1;
610 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN); 610
611 611 for (i=1; i < NUM_ENDPOINTS; i++) {
612 /* Disable all OTG functions */ 612 if((endpoints[i].allocation & bit)!=0)
613 ISP1583_INIT_OTG = 0; 613 continue;
614 614 endpoints[i].allocation |= bit;
615 /* Clear device address and enable it */ 615 return i | dir;
616 ISP1583_INIT_ADDRESS = INIT_ADDRESS_DEVEN; 616 }
617 617
618 ZVM_SPECIFIC; 618 return -1;
619 619}
620 /* Reset endpoints to default */ 620
621 setup_endpoints(); 621void usb_drv_release_endpoint(int ep)
622 622{
623 logf("bus reset->done"); 623 int mask = (ep & USB_DIR_IN)? ~2:~1;
624} 624 endpoints[ep & 0x7f].allocation &= mask;
625 625}
626/* Method for handling interrupts, must be called from usb-<target>.c */ 626
627void IRAM_ATTR usb_drv_int(void) 627
628{ 628
629 unsigned long ints; 629static void bus_reset(void)
630 ints = ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ; 630{
631 631 /* Enable CLKAON & GLINTENA */
632 if(!ints) 632 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
633 return; 633 /* Enable USB interrupts */
634 634 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET;
635 /* Unlock the device's registers */ 635 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN);
636 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE; 636
637 637 /* Disable all OTG functions */
638 #if 0 638 ISP1583_INIT_OTG = 0;
639 logf(" handling int [0x%x & 0x%x = 0x%x]", ISP1583_GEN_INT_READ, ISP1583_INIT_INTEN_READ, ints); 639
640 #endif 640 /* Clear device address and enable it */
641 641 ISP1583_INIT_ADDRESS = INIT_ADDRESS_DEVEN;
642 if(ints & INT_IEBRST) /* Bus reset */ 642
643 { 643 ZVM_SPECIFIC;
644 logf("BRESET"); 644
645 high_speed_mode = false; 645 /* Reset endpoints to default */
646 bus_reset(); 646 setup_endpoints();
647 usb_core_bus_reset(); 647
648 /* Mask bus reset interrupt */ 648 logf("bus reset->done");
649 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, INT_IEBRST); 649}
650 return; 650
651 } 651/* Method for handling interrupts, must be called from usb-<target>.c */
652 if(ints & INT_IEP0SETUP) /* EP0SETUP interrupt */ 652void IRAM_ATTR usb_drv_int(void)
653 { 653{
654 logf("EP0SETUP"); 654 unsigned long ints;
655 usb_handle_setup_rx(); 655 ints = ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ;
656 } 656
657 if(ints & INT_IEHS_STA) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */ 657 if(!ints)
658 { 658 return;
659 logf("HS_STA"); 659
660 high_speed_mode = true; 660 /* Unlock the device's registers */
661 setup_endpoints(); 661 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
662 } 662
663 if(ints & INT_EP_MASK) /* Endpoints interrupt */ 663 #if 0
664 { 664 logf(" handling int [0x%x & 0x%x = 0x%x]", ISP1583_GEN_INT_READ, ISP1583_INIT_INTEN_READ, ints);
665 unsigned long ep_event; 665 #endif
666 unsigned short i = 10; 666
667 ep_event = ints & INT_EP_MASK; 667 if(ints & INT_IEBRST) /* Bus reset */
668 while(ep_event) 668 {
669 { 669 logf("BRESET");
670 if(i>25) 670 high_speed_mode = false;
671 break; 671 bus_reset();
672 672 usb_core_bus_reset();
673 if(ep_event & (1 << i)) 673 /* Mask bus reset interrupt */
674 { 674 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, INT_IEBRST);
675 logf("EP%d %s interrupt", (i - 10) / 2, i % 2 ? "RX" : "TX"); 675 return;
676 usb_handle_data_int((i - 10) / 2, i % 2); 676 }
677 ep_event &= ~(1 << i); 677 if(ints & INT_IEP0SETUP) /* EP0SETUP interrupt */
678 } 678 {
679 i++; 679 logf("EP0SETUP");
680 } 680 usb_handle_setup_rx();
681 } 681 }
682 if(ints & INT_IERESM && !(ints & INT_IESUSP)) /* Resume status: status change from suspend to resume (active) */ 682 if(ints & INT_IEHS_STA) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */
683 { 683 {
684 logf("RESM"); 684 logf("HS_STA");
685 } 685 high_speed_mode = true;
686 if(ints & INT_IESUSP && !(ints & INT_IERESM)) /* Suspend status: status change from active to suspend */ 686 setup_endpoints();
687 { 687 }
688 logf("SUSP"); 688 if(ints & INT_EP_MASK) /* Endpoints interrupt */
689 } 689 {
690 if(ints & INT_IEDMA) /* change in the DMA Interrupt Reason register */ 690 unsigned long ep_event;
691 { 691 unsigned short i = 10;
692 logf("DMA"); 692 ep_event = ints & INT_EP_MASK;
693 } 693 while(ep_event)
694 if(ints & INT_IEVBUS) /* transition from LOW to HIGH on VBUS */ 694 {
695 { 695 if(i>25)
696 logf("VBUS"); 696 break;
697 } 697
698 /* Mask all (enabled) interrupts */ 698 if(ep_event & (1 << i))
699 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, ints); 699 {
700 700 logf("EP%d %s interrupt", (i - 10) / 2, i % 2 ? "RX" : "TX");
701 ZVM_SPECIFIC; 701 usb_handle_data_int((i - 10) / 2, i % 2);
702} 702 ep_event &= ~(1 << i);
703 703 }
704void usb_drv_set_address(int address) 704 i++;
705{ 705 }
706 logf("usb_drv_set_address(0x%x)", address); 706 }
707 ISP1583_INIT_ADDRESS = (address & 0x7F) | INIT_ADDRESS_DEVEN; 707 if(ints & INT_IERESM && !(ints & INT_IESUSP)) /* Resume status: status change from suspend to resume (active) */
708 708 {
709 ZVM_SPECIFIC; 709 logf("RESM");
710 710 }
711 usb_status_ack(0, DIR_TX); 711 if(ints & INT_IESUSP && !(ints & INT_IERESM)) /* Suspend status: status change from active to suspend */
712} 712 {
713 713 logf("SUSP");
714int dbg_usb_num_items(void) 714 }
715{ 715 if(ints & INT_IEDMA) /* change in the DMA Interrupt Reason register */
716 return 2+NUM_ENDPOINTS*2; 716 {
717} 717 logf("DMA");
718 718 }
719char* dbg_usb_item(int selected_item, void *data, char *buffer, size_t buffer_len) 719 if(ints & INT_IEVBUS) /* transition from LOW to HIGH on VBUS */
720{ 720 {
721 if(selected_item < 2) 721 logf("VBUS");
722 { 722 }
723 switch(selected_item) 723 /* Mask all (enabled) interrupts */
724 { 724 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, ints);
725 case 0: 725
726 snprintf(buffer, buffer_len, "USB connected: %s", (usb_drv_connected() ? "Yes" : "No")); 726 ZVM_SPECIFIC;
727 return buffer; 727}
728 case 1: 728
729 snprintf(buffer, buffer_len, "HS mode: %s", (high_speed_mode ? "Yes" : "No")); 729void usb_drv_set_address(int address)
730 return buffer; 730{
731 } 731 logf("usb_drv_set_address(0x%x)", address);
732 } 732 ISP1583_INIT_ADDRESS = (address & 0x7F) | INIT_ADDRESS_DEVEN;
733 else 733
734 { 734 ZVM_SPECIFIC;
735 int n = ep_index((selected_item - 2) / 2, (selected_item - 2) % 2); 735
736 if(endpoints[n].enabled == false) 736 usb_status_ack(0, DIR_TX);
737 snprintf(buffer, buffer_len, "EP%d[%s]: DISABLED", epidx_n(n), (epidx_dir(n) ? "TX" : "RX")); 737}
738 else 738
739 { 739int dbg_usb_num_items(void)
740 if(epidx_dir(n)) 740{
741 { 741 return 2+NUM_ENDPOINTS*2;
742 if(endpoints[n].out_in_progress) 742}
743 snprintf(buffer, buffer_len, "EP%d[TX]: TRANSFERRING DATA -> %d bytes/%d bytes", epidx_n(n), (endpoints[n].out_len - endpoints[n].out_ptr), endpoints[n].out_len); 743
744 else 744char* dbg_usb_item(int selected_item, void *data, char *buffer, size_t buffer_len)
745 snprintf(buffer, buffer_len, "EP%d[TX]: STANDBY", epidx_n(n)); 745{
746 } 746 if(selected_item < 2)
747 else 747 {
748 { 748 switch(selected_item)
749 if(endpoints[n].in_buf && !endpoints[n].in_ack) 749 {
750 snprintf(buffer, buffer_len, "EP%d[RX]: RECEIVING DATA -> %d bytes/%d bytes", epidx_n(n), endpoints[n].in_ptr, endpoints[n].in_max_len); 750 case 0:
751 else 751 snprintf(buffer, buffer_len, "USB connected: %s", (usb_drv_connected() ? "Yes" : "No"));
752 snprintf(buffer, buffer_len, "EP%d[RX]: STANDBY", epidx_n(n)); 752 return buffer;
753 } 753 case 1:
754 } 754 snprintf(buffer, buffer_len, "HS mode: %s", (high_speed_mode ? "Yes" : "No"));
755 return buffer; 755 return buffer;
756 } 756 }
757 return NULL; 757 }
758 (void)data; 758 else
759} 759 {
760 760 int n = ep_index((selected_item - 2) / 2, (selected_item - 2) % 2);
761void usb_drv_set_test_mode(int mode) 761 if(endpoints[n].enabled == false)
762{ 762 snprintf(buffer, buffer_len, "EP%d[%s]: DISABLED", epidx_n(n), (epidx_dir(n) ? "TX" : "RX"));
763 logf("usb_drv_set_test_mode(%d)", mode); 763 else
764 switch(mode){ 764 {
765 case 0: 765 if(epidx_dir(n))
766 ISP1583_GEN_TSTMOD = 0; 766 {
767 /* Power cycle... */ 767 if(endpoints[n].out_in_progress)
768 break; 768 snprintf(buffer, buffer_len, "EP%d[TX]: TRANSFERRING DATA -> %d bytes/%d bytes", epidx_n(n), (endpoints[n].out_len - endpoints[n].out_ptr), endpoints[n].out_len);
769 case 1: 769 else
770 ISP1583_GEN_TSTMOD = GEN_TSTMOD_JSTATE; 770 snprintf(buffer, buffer_len, "EP%d[TX]: STANDBY", epidx_n(n));
771 break; 771 }
772 case 2: 772 else
773 ISP1583_GEN_TSTMOD = GEN_TSTMOD_KSTATE; 773 {
774 break; 774 if(endpoints[n].in_buf && !endpoints[n].in_ack)
775 case 3: 775 snprintf(buffer, buffer_len, "EP%d[RX]: RECEIVING DATA -> %d bytes/%d bytes", epidx_n(n), endpoints[n].in_ptr, endpoints[n].in_max_len);
776 ISP1583_GEN_TSTMOD = GEN_TSTMOD_SE0_NAK; 776 else
777 break; 777 snprintf(buffer, buffer_len, "EP%d[RX]: STANDBY", epidx_n(n));
778 case 4: 778 }
779 //REG_PORTSC1 |= PORTSCX_PTC_PACKET; 779 }
780 break; 780 return buffer;
781 case 5: 781 }
782 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN; 782 return NULL;
783 break; 783 (void)data;
784 } 784}
785} 785
786void usb_drv_set_test_mode(int mode)
787{
788 logf("usb_drv_set_test_mode(%d)", mode);
789 switch(mode){
790 case 0:
791 ISP1583_GEN_TSTMOD = 0;
792 /* Power cycle... */
793 break;
794 case 1:
795 ISP1583_GEN_TSTMOD = GEN_TSTMOD_JSTATE;
796 break;
797 case 2:
798 ISP1583_GEN_TSTMOD = GEN_TSTMOD_KSTATE;
799 break;
800 case 3:
801 ISP1583_GEN_TSTMOD = GEN_TSTMOD_SE0_NAK;
802 break;
803 case 4:
804 //REG_PORTSC1 |= PORTSCX_PTC_PACKET;
805 break;
806 case 5:
807 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
808 break;
809 }
810}