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