1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Tomasz Malesinski
11 * Copyright (C) 2008 by Maurus Cuelenaere
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
34 unsigned char *out_buf
;
37 void (*out_done
)(int, unsigned char *, int);
38 unsigned char out_in_progress
;
40 unsigned char *in_buf
;
44 void (*in_done
)(int, unsigned char *, int);
47 unsigned char halt
[2];
48 unsigned char enabled
[2];
49 short max_pkt_size
[2];
54 static unsigned char setup_pkt_buf
[8];
55 static struct usb_endpoint endpoints
[USB_NUM_ENDPOINTS
];
57 static bool high_speed_mode
= false;
59 static inline void or_int_value(volatile unsigned short *a
, volatile unsigned short *b
, unsigned long r
, unsigned long value
)
61 set_int_value(*a
, *b
, (r
| value
));
63 static inline void bc_int_value(volatile unsigned short *a
, volatile unsigned short *b
, unsigned long r
, unsigned long value
)
65 set_int_value(*a
, *b
, (r
& ~value
));
68 static inline void nop_f(void)
73 #define NOP asm volatile("nop\n");
75 static inline int ep_index(int n
, bool dir
)
77 return (n
<< 1) | dir
;
80 static inline bool epidx_dir(int idx
)
85 static inline int epidx_n(int idx
)
90 static inline void usb_select_endpoint(int idx
)
92 /* Select the endpoint */
93 ISP1583_DFLOW_EPINDEX
= idx
;
94 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
95 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
100 static inline void usb_select_setup_endpoint(void)
102 /* Select the endpoint */
103 ISP1583_DFLOW_EPINDEX
= DFLOW_EPINDEX_EP0SETUP
;
104 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
105 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
110 static void usb_setup_endpoint(int idx
, int max_pkt_size
, int type
)
112 if(epidx_n(idx
)!=EP_CONTROL
)
114 usb_select_endpoint(idx
);
115 ISP1583_DFLOW_MAXPKSZ
= max_pkt_size
& 0x7FF;
116 ISP1583_DFLOW_EPTYPE
= (DFLOW_EPTYPE_NOEMPKT
| DFLOW_EPTYPE_DBLBUF
| (type
& 0x3));
118 /* clear buffer ... */
119 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
120 /* ... twice because of double buffering */
121 usb_select_endpoint(idx
);
122 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
125 struct usb_endpoint
*ep
;
126 ep
= &(endpoints
[epidx_n(idx
)]);
127 ep
->halt
[epidx_dir(idx
)] = 0;
128 ep
->enabled
[epidx_dir(idx
)] = 0;
129 ep
->out_in_progress
= 0;
133 ep
->max_pkt_size
[epidx_dir(idx
)] = max_pkt_size
;
136 static void usb_enable_endpoint(int idx
)
138 if(epidx_n(idx
)!=EP_CONTROL
)
140 usb_select_endpoint(idx
);
141 /* Enable interrupt */
142 or_int_value(&ISP1583_INIT_INTEN_A
, &ISP1583_INIT_INTEN_B
, ISP1583_INIT_INTEN_READ
, 1 << (10 + idx
));
143 /* Enable endpoint */
144 ISP1583_DFLOW_EPTYPE
|= DFLOW_EPTYPE_ENABLE
;
147 endpoints
[epidx_n(idx
)].enabled
[epidx_dir(idx
)] = 1;
150 static void usb_disable_endpoint(int idx, bool set_struct)
152 usb_select_endpoint(idx);
153 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
154 bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
157 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0;
160 static int usb_get_packet(unsigned char *buf
, int max_len
)
163 len
= ISP1583_DFLOW_BUFLEN
;
165 if (max_len
< 0 || max_len
> len
)
171 unsigned short d
= ISP1583_DFLOW_DATA
;
176 buf
[i
] = (d
>> 8) & 0xff;
182 static int usb_receive(int n
)
184 logf("usb_receive(%d)", n
);
187 if (endpoints
[n
].halt
[DIR_RX
]
188 || !endpoints
[n
].enabled
[DIR_RX
]
189 || endpoints
[n
].in_min_len
< 0
190 || !endpoints
[n
].in_ack
)
193 endpoints
[n
].in_ack
= 0;
195 usb_select_endpoint(ep_index(n
, DIR_RX
));
197 len
= usb_get_packet(endpoints
[n
].in_buf
+ endpoints
[n
].in_ptr
,
198 endpoints
[n
].in_max_len
- endpoints
[n
].in_ptr
);
199 endpoints
[n
].in_ptr
+= len
;
201 if (endpoints
[n
].in_ptr
>= endpoints
[n
].in_min_len
)
203 endpoints
[n
].in_min_len
= -1;
204 if (endpoints
[n
].in_done
)
205 (*(endpoints
[n
].in_done
))(n
, endpoints
[n
].in_buf
,
206 endpoints
[n
].in_ptr
);
212 static bool usb_out_buffer_full(int ep
)
214 usb_select_endpoint(ep_index(ep
, DIR_TX
));
215 if (ISP1583_DFLOW_EPTYPE
& 4) /* Check if type=bulk and double buffering is set */
216 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 */
221 static int usb_send(int n
)
223 logf("usb_send(%d)", n
);
224 int max_pkt_size
, len
;
228 if (endpoints
[n
].halt
[DIR_TX
]
229 || !endpoints
[n
].enabled
[DIR_TX
]
230 || !endpoints
[n
].out_in_progress
)
232 logf("NOT SEND TO EP!");
236 if (endpoints
[n
].out_ptr
< 0)
238 endpoints
[n
].out_in_progress
= 0;
239 if (endpoints
[n
].out_done
)
240 (*(endpoints
[n
].out_done
))(n
, endpoints
[n
].out_buf
,
241 endpoints
[n
].out_len
);
242 logf("ALREADY SENT TO EP!");
246 if (usb_out_buffer_full(n
))
248 logf("BUFFER FULL!");
252 usb_select_endpoint(ep_index(n
, DIR_TX
));
253 max_pkt_size
= endpoints
[n
].max_pkt_size
[DIR_TX
];
254 len
= endpoints
[n
].out_len
- endpoints
[n
].out_ptr
;
255 if (len
> max_pkt_size
)
258 if(len
< max_pkt_size
)
259 ISP1583_DFLOW_BUFLEN
= len
;
261 p
= endpoints
[n
].out_buf
+ endpoints
[n
].out_ptr
;
265 ISP1583_DFLOW_DATA
= p
[i
] | (p
[i
+ 1] << 8);
269 ISP1583_DFLOW_DATA
= p
[i
];
271 endpoints
[n
].out_ptr
+= len
;
274 if (endpoints[n].out_ptr == endpoints[n].out_len
275 && len < max_pkt_size)
277 if (endpoints
[n
].out_ptr
== endpoints
[n
].out_len
)
278 endpoints
[n
].out_ptr
= -1;
284 static void usb_stall_endpoint(int idx
)
286 usb_select_endpoint(idx
);
287 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_STALL
;
288 endpoints
[epidx_n(idx
)].halt
[epidx_dir(idx
)] = 1;
291 static void usb_unstall_endpoint(int idx
)
293 usb_select_endpoint(idx
);
294 ISP1583_DFLOW_CTRLFUN
&= ~DFLOW_CTRLFUN_STALL
;
295 ISP1583_DFLOW_EPTYPE
&= ~DFLOW_EPTYPE_ENABLE
;
296 ISP1583_DFLOW_EPTYPE
|= DFLOW_EPTYPE_ENABLE
;
297 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
298 if (epidx_dir(idx
) == DIR_TX
)
299 endpoints
[epidx_n(idx
)].out_in_progress
= 0;
302 endpoints
[epidx_n(idx
)].in_min_len
= -1;
303 endpoints
[epidx_n(idx
)].in_ack
= 0;
305 endpoints
[epidx_n(idx
)].halt
[epidx_dir(idx
)] = 0;
308 static void usb_status_ack(int ep
, int dir
)
310 logf("usb_status_ack(%d)", dir
);
312 usb_select_setup_endpoint();
314 usb_select_endpoint(ep_index(ep
, dir
));
316 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_STATUS
;
319 static void usb_data_stage_enable(int ep
, int dir
)
321 logf("usb_data_stage_enable(%d)", dir
);
322 usb_select_endpoint(ep_index(ep
, dir
));
323 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_DSEN
;
326 static void usb_handle_setup_rx(void)
329 usb_select_setup_endpoint();
330 len
= usb_get_packet(setup_pkt_buf
, 8);
334 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_STATUS
; /* Acknowledge packet */
335 usb_core_control_request((struct usb_ctrlrequest
*)setup_pkt_buf
);
339 usb_drv_stall(EP_CONTROL
, true, false);
340 usb_drv_stall(EP_CONTROL
, true, true);
341 logf("usb_handle_setup_rx() failed");
345 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]);
348 static void usb_handle_data_int(int ep
, int dir
)
355 len
= usb_receive(ep
);
356 endpoints
[ep
].in_ack
= 1;
358 logf("usb_handle_data_int(%d, %d) finished", ep
, dir
);
361 bool usb_drv_powered(void)
364 return (ISP1583_INIT_OTG
& INIT_OTG_BSESS_VALID
) ? true : false;
366 return (ISP1583_INIT_MODE
& INIT_MODE_VBUSSTAT
) ? true : false;
370 static void setup_endpoints(void)
373 int max_pkt_size
= (high_speed_mode
? 512 : 64);
375 usb_setup_endpoint(ep_index(EP_CONTROL
, DIR_RX
), 64,
376 USB_ENDPOINT_XFER_CONTROL
);
377 usb_setup_endpoint(ep_index(EP_CONTROL
, DIR_TX
), 64,
378 USB_ENDPOINT_XFER_CONTROL
);
380 for(i
= 1; i
< USB_NUM_ENDPOINTS
-1; i
++)
382 usb_setup_endpoint(ep_index(i
, DIR_RX
), max_pkt_size
,
383 USB_ENDPOINT_XFER_BULK
);
384 usb_setup_endpoint(ep_index(i
, DIR_TX
), max_pkt_size
,
385 USB_ENDPOINT_XFER_BULK
);
388 usb_enable_endpoint(ep_index(EP_CONTROL
, DIR_RX
));
389 usb_enable_endpoint(ep_index(EP_CONTROL
, DIR_TX
));
391 for (i
= 1; i
< USB_NUM_ENDPOINTS
-1; i
++)
393 usb_enable_endpoint(ep_index(i
, DIR_RX
));
394 usb_enable_endpoint(ep_index(i
, DIR_TX
));
400 void usb_helper(void)
402 if(ISP1583_GEN_INT_READ
& ISP1583_INIT_INTEN_READ
)
404 logf("Helper detected interrupt... [%d]", (int)current_tick
);
410 void usb_drv_init(void)
412 /* Disable interrupt at CPU level */
415 /* Unlock the device's registers */
416 ISP1583_GEN_UNLCKDEV
= ISP1583_UNLOCK_CODE
;
418 /* Soft reset the device */
419 ISP1583_INIT_MODE
= INIT_MODE_SFRESET
;
421 /* Enable CLKAON & GLINTENA */
422 ISP1583_INIT_MODE
= STANDARD_INIT_MODE
;
424 /* Disable all OTG functions */
425 ISP1583_INIT_OTG
= 0;
428 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
));
429 logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID
);
430 //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT);
433 /*Set interrupt generation to target-specific mode +
434 * Set the control pipe to ACK only interrupt +
435 * Set the IN pipe to ACK only interrupt +
436 * Set OUT pipe to ACK and NYET interrupt
439 ISP1583_INIT_INTCONF
= 0x54 | INT_CONF_TARGET
;
440 /* Clear all interrupts */
441 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, 0xFFFFFFFF);
442 /* Enable USB interrupts */
443 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, STANDARD_INTEN
);
447 /* Enable interrupt at CPU level */
452 /* Clear device address and disable it */
453 ISP1583_INIT_ADDRESS
= 0;
455 /* Turn SoftConnect on */
456 ISP1583_INIT_MODE
|= INIT_MODE_SOFTCT
;
460 //tick_add_task(usb_helper);
462 logf("usb_init_device() finished");
465 int usb_drv_port_speed(void)
467 return (int)high_speed_mode
;
470 void usb_drv_exit(void)
472 logf("usb_drv_exit()");
475 ISP1583_INIT_MODE
&= ~INIT_MODE_SOFTCT
;
476 ISP1583_INIT_ADDRESS
= 0;
478 /* Disable interrupts */
479 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, 0);
480 /* and the CPU's one... */
484 /* Send usb controller to suspend mode */
485 ISP1583_INIT_MODE
= INIT_MODE_GOSUSP
;
486 ISP1583_INIT_MODE
= 0;
488 //tick_remove_task(usb_helper);
493 void usb_drv_stall(int endpoint
, bool stall
, bool in
)
495 logf("%sstall EP%d %s", (stall
? "" : "un"), endpoint
, (in
? "RX" : "TX" ));
497 usb_stall_endpoint(ep_index(endpoint
, (int)in
));
499 usb_unstall_endpoint(ep_index(endpoint
, (int)in
));
502 bool usb_drv_stalled(int endpoint
, bool in
)
504 return (endpoints
[endpoint
].halt
[(int)in
] == 1);
507 static void out_callback(int ep
, unsigned char *buf
, int len
)
510 logf("out_callback(%d, 0x%x, %d)", ep
, (int)buf
, len
);
511 usb_status_ack(ep
, DIR_RX
);
512 usb_core_transfer_complete(ep
, true, 0, len
); /* 0=>status succeeded, haven't worked out status failed yet... */
515 static void in_callback(int ep
, unsigned char *buf
, int len
)
518 logf("in_callback(%d, 0x%x, %d)", ep
, (int)buf
, len
);
519 usb_status_ack(ep
, DIR_TX
);
520 usb_core_transfer_complete(ep
, false, 0, len
);
523 int usb_drv_recv(int ep
, void* ptr
, int length
)
525 logf("usb_drv_recv(%d, 0x%x, %d)", ep
, (int)ptr
, length
);
526 if(ep
== EP_CONTROL
&& length
== 0 && ptr
== NULL
)
528 usb_status_ack(ep
, DIR_TX
);
531 endpoints
[ep
].in_done
= in_callback
;
532 endpoints
[ep
].in_buf
= ptr
;
533 endpoints
[ep
].in_max_len
= length
;
534 endpoints
[ep
].in_min_len
= length
;
535 endpoints
[ep
].in_ptr
= 0;
538 usb_data_stage_enable(ep
, DIR_RX
);
539 return usb_receive(ep
);
542 return usb_receive(ep
);
545 int usb_drv_send_nonblocking(int ep
, void* ptr
, int length
)
547 /* First implement DMA... */
548 return usb_drv_send(ep
, ptr
, length
);
551 static void usb_drv_wait(int ep
, bool send
)
553 logf("usb_drv_wait(%d, %d)", ep
, send
);
556 while (endpoints
[ep
].out_in_progress
)
561 while (endpoints
[ep
].in_ack
)
566 int usb_drv_send(int ep
, void* ptr
, int length
)
568 logf("usb_drv_send_nb(%d, 0x%x, %d)", ep
, (int)ptr
, length
);
569 if(ep
== EP_CONTROL
&& length
== 0 && ptr
== NULL
)
571 usb_status_ack(ep
, DIR_RX
);
574 if(endpoints
[ep
].out_in_progress
== 1)
576 endpoints
[ep
].out_done
= out_callback
;
577 endpoints
[ep
].out_buf
= ptr
;
578 endpoints
[ep
].out_len
= length
;
579 endpoints
[ep
].out_ptr
= 0;
580 endpoints
[ep
].out_in_progress
= 1;
583 int rc
= usb_send(ep
);
584 usb_data_stage_enable(ep
, DIR_TX
);
585 usb_drv_wait(ep
, DIR_TX
);
592 void usb_drv_reset_endpoint(int ep
, bool send
)
594 logf("reset endpoint(%d, %d)", ep
, send
);
595 usb_setup_endpoint(ep_index(ep
, (int)send
), endpoints
[ep
].max_pkt_size
[(int)send
], endpoints
[ep
].type
);
596 usb_enable_endpoint(ep_index(ep
, (int)send
));
599 void usb_drv_cancel_all_transfers(void)
601 logf("usb_drv_cancel_all_tranfers()");
604 for(i
=0;i
<USB_NUM_ENDPOINTS
-1;i
++)
605 endpoints
[i
].halt
[0] = endpoints
[i
].halt
[1] = 1;
608 int usb_drv_request_endpoint(int type
, int dir
)
612 if (type
!= USB_ENDPOINT_XFER_BULK
)
615 bit
=(dir
& USB_DIR_IN
)? 2:1;
617 for (i
=1; i
< USB_NUM_ENDPOINTS
; i
++) {
618 if((endpoints
[i
].allocation
& bit
)!=0)
620 endpoints
[i
].allocation
|= bit
;
627 void usb_drv_release_endpoint(int ep
)
629 int mask
= (ep
& USB_DIR_IN
)? ~2:~1;
630 endpoints
[ep
& 0x7f].allocation
&= mask
;
633 static void bus_reset(void)
635 /* Enable CLKAON & GLINTENA */
636 ISP1583_INIT_MODE
= STANDARD_INIT_MODE
;
637 /* Enable USB interrupts */
638 ISP1583_INIT_INTCONF
= 0x54 | INT_CONF_TARGET
;
639 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, STANDARD_INTEN
);
641 /* Disable all OTG functions */
642 ISP1583_INIT_OTG
= 0;
644 /* Clear device address and enable it */
645 ISP1583_INIT_ADDRESS
= INIT_ADDRESS_DEVEN
;
649 /* Reset endpoints to default */
652 logf("bus reset->done");
655 /* Method for handling interrupts, must be called from usb-<target>.c */
656 void IRAM_ATTR
usb_drv_int(void)
659 ints
= ISP1583_GEN_INT_READ
& ISP1583_INIT_INTEN_READ
;
664 /* Unlock the device's registers */
665 ISP1583_GEN_UNLCKDEV
= ISP1583_UNLOCK_CODE
;
667 //logf(" handling int [0x%lx & 0x%lx = 0x%x]", ISP1583_GEN_INT_READ, ISP1583_INIT_INTEN_READ, (int)ints);
669 if(ints
& INT_IEBRST
) /* Bus reset */
672 high_speed_mode
= false;
674 usb_core_bus_reset();
675 /* Mask bus reset interrupt */
676 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, INT_IEBRST
);
679 if(ints
& INT_IEP0SETUP
) /* EP0SETUP interrupt */
682 usb_handle_setup_rx();
684 if(ints
& INT_IEHS_STA
) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */
687 high_speed_mode
= true;
690 if(ints
& INT_EP_MASK
) /* Endpoints interrupt */
692 unsigned long ep_event
;
693 unsigned short i
= 10;
694 ep_event
= ints
& INT_EP_MASK
;
700 if(ep_event
& (1 << i
))
702 logf("EP%d %s interrupt", (i
- 10) / 2, i
% 2 ? "RX" : "TX");
703 usb_handle_data_int((i
- 10) / 2, i
% 2);
704 ep_event
&= ~(1 << i
);
709 if(ints
& INT_IERESM
&& !(ints
& INT_IESUSP
)) /* Resume status: status change from suspend to resume (active) */
713 if(ints
& INT_IESUSP
&& !(ints
& INT_IERESM
)) /* Suspend status: status change from active to suspend */
717 if(ints
& INT_IEDMA
) /* change in the DMA Interrupt Reason register */
721 if(ints
& INT_IEVBUS
) /* transition from LOW to HIGH on VBUS */
725 /* Mask all (enabled) interrupts */
726 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, ints
);
731 void usb_drv_set_address(int address
)
733 logf("usb_drv_set_address(0x%x)", address
);
734 ISP1583_INIT_ADDRESS
= (address
& 0x7F) | INIT_ADDRESS_DEVEN
;
739 void usb_drv_set_test_mode(int mode
)
741 logf("usb_drv_set_test_mode(%d)", mode
);
744 ISP1583_GEN_TSTMOD
= 0;
748 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_JSTATE
;
751 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_KSTATE
;
754 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_SE0_NAK
;
757 //REG_PORTSC1 |= PORTSCX_PTC_PACKET;
760 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
766 int dbg_usb_num_items(void)
768 return 2+USB_NUM_ENDPOINTS
*2;
771 const char* dbg_usb_item(int selected_item
, void *data
,
772 char *buffer
, size_t buffer_len
)
774 if(selected_item
< 2)
776 switch(selected_item
)
779 snprintf(buffer
, buffer_len
, "USB connected: %s", (usb_drv_connected() ? "Yes" : "No"));
782 snprintf(buffer
, buffer_len
, "HS mode: %s", (high_speed_mode
? "Yes" : "No"));
788 int n
= ep_index((selected_item
- 2) / 2, (selected_item
- 2) % 2);
789 if(endpoints
[n
].enabled
== false)
790 snprintf(buffer
, buffer_len
, "EP%d[%s]: DISABLED", epidx_n(n
), (epidx_dir(n
) ? "TX" : "RX"));
795 if(endpoints
[n
].out_in_progress
)
796 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
);
798 snprintf(buffer
, buffer_len
, "EP%d[TX]: STANDBY", epidx_n(n
));
802 if(endpoints
[n
].in_buf
&& !endpoints
[n
].in_ack
)
803 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
);
805 snprintf(buffer
, buffer_len
, "EP%d[RX]: STANDBY", epidx_n(n
));