00001
00015 #include "pic_usb.h"
00016 #include "pic_serial.h"
00017 #include "memory.h"
00018 #include "config.h"
00019 #include "pic_usb_buffer_mgt.h"
00020
00021
00022
00023
00024 usb_state_type usb_state = st_POWERED;
00025
00026 setup_data_packet usb_sdp;
00027
00028 uns8 usb_address;
00029 control_mode_type control_mode;
00030 uns16 delivery_bytes_to_send,
00031 delivery_bytes_max_send,
00032 delivery_bytes_sent;
00033 uns8 *delivery_ptr;
00034 uns8 delivery_buffer_size;
00035 uns8 *delivery_buffer;
00036 buffer_descriptor *delivery_bd;
00037
00038 usb_status_type usb_status;
00039
00040 void usb_configure_endpoints() {
00041
00042 serial_print_str("Config eps ");
00043 #ifdef USB_EP1
00044 set_bit (uep1, EPHSHK);
00045 #ifdef USB_EP1_OUT_SIZE
00046 set_bit(uep1, EPOUTEN);
00047 #else
00048 clear_bit(uep1, EPOUTEN);
00049 #endif
00050 #ifdef USB_EP1_IN_SIZE
00051 set_bit(uep1, EPINEN);
00052 #else
00053 clear_bit(uep1, EPINEN);
00054 #endif
00055 set_bit (uep1, EPCONDIS);
00056
00057
00058 #ifdef USB_EP1_IN_SIZE
00059 set_bit(bd1in.stat, DTS);
00060 clear_bit(bd1in.stat, KEN);
00061 clear_bit(bd1in.stat, INCDIS);
00062 clear_bit(bd1in.stat, DTSEN);
00063 clear_bit(bd1in.stat, BSTALL);
00064 clear_bit(bd1in.stat, BC9);
00065 clear_bit(bd1in.stat, BC8);
00066
00067 clear_bit(bd1in.stat, UOWN);
00068 #endif
00069
00070 #ifdef USB_EP1_OUT_SIZE
00071 bd1out.count = USB_EP1_OUT_SIZE;
00072 bd1out.addr = USB_EP1_OUT_ADDR;
00073
00074 clear_bit(bd1out.stat, DTS);
00075 clear_bit(bd1out.stat, KEN);
00076 clear_bit(bd1out.stat, INCDIS);
00077 clear_bit(bd1out.stat, DTSEN);
00078 clear_bit(bd1out.stat, BSTALL);
00079 clear_bit(bd1out.stat, BC9);
00080 clear_bit(bd1out.stat, BC8);
00081 set_bit (bd1out.stat, UOWN);
00082
00083 #endif
00084
00085
00086 #endif
00087
00088 #ifdef USB_EP2
00089 set_bit (uep2, EPHSHK);
00090 #ifdef USB_EP2_OUT_SIZE
00091 set_bit(uep2, EPOUTEN);
00092 #else
00093 clear_bit(uep2, EPOUTEN);
00094 #endif
00095 #ifdef USB_EP2_IN_SIZE
00096 set_bit(uep2, EPINEN);
00097 #else
00098 clear_bit(uep2, EPINEN);
00099 #endif
00100 set_bit (uep2, EPCONDIS);
00101
00102
00103 #ifdef USB_EP2_IN_SIZE
00104
00105 set_bit(bd2in.stat, DTS);
00106 clear_bit(bd2in.stat, KEN);
00107 clear_bit(bd2in.stat, INCDIS);
00108 clear_bit(bd2in.stat, DTSEN);
00109 clear_bit(bd2in.stat, BSTALL);
00110 clear_bit(bd2in.stat, BC9);
00111 clear_bit(bd2in.stat, BC8);
00112
00113 clear_bit(bd2in.stat, UOWN);
00114 #endif
00115
00116 #ifdef USB_EP2_OUT_SIZE
00117 bd2out.count = USB_EP2_OUT_SIZE;
00118 bd2out.addr = USB_EP2_OUT_ADDR;
00119
00120 clear_bit(bd2out.stat, DTS);
00121 clear_bit(bd2out.stat, KEN);
00122 clear_bit(bd2out.stat, INCDIS);
00123 clear_bit(bd2out.stat, DTSEN);
00124 clear_bit(bd2out.stat, BSTALL);
00125 clear_bit(bd2out.stat, BC9);
00126 clear_bit(bd2out.stat, BC8);
00127 set_bit (bd2out.stat, UOWN);
00128 #endif
00129 #endif
00130
00131 #ifdef USB_EP3
00132 set_bit (uep3, EPHSHK);
00133 #ifdef USB_EP3_OUT_SIZE
00134 set_bit(uep3, EPOUTEN);
00135 #else
00136 clear_bit(uep3, EPOUTEN);
00137 #endif
00138 #ifdef USB_EP3_IN_SIZE
00139 set_bit(uep3, EPINEN);
00140 #else
00141 clear_bit(uep3, EPINEN);
00142 #endif
00143 set_bit (uep3, EPCONDIS);
00144
00145 #ifdef USB_EP3_IN_SIZE
00146 set_bit(bd3in.stat, DTS);
00147 clear_bit(bd3in.stat, KEN);
00148 clear_bit(bd3in.stat, INCDIS);
00149 clear_bit(bd3in.stat, DTSEN);
00150 clear_bit(bd3in.stat, BSTALL);
00151 clear_bit(bd3in.stat, BC9);
00152 clear_bit(bd3in.stat, BC8);
00153
00154 clear_bit(bd3in.stat, UOWN);
00155 #endif
00156
00157 #ifdef USB_EP3_OUT_SIZE
00158 bd3out.count = USB_EP3_OUT_SIZE;
00159 bd3out.addr = USB_EP3_OUT_ADDR;
00160
00161 clear_bit(bd3out.stat, DTS);
00162 clear_bit(bd3out.stat, KEN);
00163 clear_bit(bd3out.stat, INCDIS);
00164 clear_bit(bd3out.stat, DTSEN);
00165 clear_bit(bd3out.stat, BSTALL);
00166 clear_bit(bd3out.stat, BC9);
00167 clear_bit(bd3out.stat, BC8);
00168 set_bit (bd3out.stat, UOWN);
00169 #endif
00170
00171 #endif
00172
00173 }
00174
00175 void usb_stall_ep0() {
00176 set_bit(bd0in.stat, BSTALL);
00177 set_bit(bd0in.stat, UOWN);
00178 set_bit(bd0out.stat, BSTALL);
00179 set_bit(bd0out.stat, UOWN);
00180
00181 }
00182
00183 void usb_send_data(uns8 ep, uns8 *data, uns8 send_count, bit first) {
00184 uns8 count;
00185 buffer_descriptor *bd;
00186 uns8 *buffer;
00187
00188
00189
00190
00191 buffer = ep_in_buffer_location[ep];
00192
00193 bd = ep_in_bd_location[ep];
00194
00195 if (test_bit(bd->stat, UOWN)) {
00196 serial_print_str(" don't own it! ");
00197 return;
00198 }
00199 serial_putc('>');
00200
00201 count = 0;
00202 while ((count < send_count)) {
00203 buffer[count] = data[count];
00204 count++;
00205 }
00206
00207
00208 bd->count = count;
00209 bd->addr = (uns16)buffer;
00210 if (first) {
00211 clear_bit(bd->stat, DTS);
00212 }
00213
00214 toggle_bit(bd->stat, DTS);
00215 clear_bit(bd->stat, KEN);
00216 clear_bit(bd->stat, INCDIS);
00217 set_bit (bd->stat, DTSEN);
00218 clear_bit(bd->stat, BSTALL);
00219 clear_bit(bd->stat, BC9);
00220 clear_bit(bd->stat, BC8);
00221
00222 set_bit (bd->stat, UOWN);
00223 }
00224
00225
00226
00227 void usb_send_data_chunk() {
00228
00229 uns8 count;
00230
00231 count = 0;
00232
00233 while ((count < delivery_buffer_size) &&
00234 (delivery_bytes_sent < delivery_bytes_to_send) &&
00235 (delivery_bytes_sent < delivery_bytes_max_send)) {
00236
00237 delivery_buffer[count] = *delivery_ptr;
00238 delivery_ptr++;
00239 delivery_bytes_sent++;
00240 count++;
00241 }
00242
00243 if ((count < delivery_buffer_size) &&
00244 ((delivery_bytes_sent == delivery_bytes_max_send) ||
00245 (delivery_bytes_sent == delivery_bytes_to_send))) {
00246 control_mode = cm_CTRL_READ_AWAITING_STATUS;
00247 }
00248
00249
00250
00251 bd0in.count = count;
00252 bd0in.addr = (uns16)&buffer_0_in;
00253 toggle_bit(bd0in.stat, DTS);
00254 clear_bit(bd0in.stat, KEN);
00255 clear_bit(bd0in.stat, INCDIS);
00256 set_bit (bd0in.stat, DTSEN);
00257 clear_bit(bd0in.stat, BSTALL);
00258 clear_bit(bd0in.stat, BC9);
00259 clear_bit(bd0in.stat, BC8);
00260
00261 set_bit (bd0in.stat, UOWN);
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 }
00276
00277
00278 void usb_send_empty_data_pkt() {
00279 delivery_buffer_size = USB_EP0_IN_SIZE;
00280 delivery_bd = &bd0in;
00281 delivery_buffer = &buffer_0_in;
00282 delivery_bytes_sent = 0;
00283 delivery_bytes_to_send = 0;
00284 delivery_bytes_max_send = 0;
00285 delivery_ptr = (uns8 *) 0;
00286 clear_bit(bd0in.stat, DTS);
00287 usb_send_data_chunk();
00288 }
00289
00290 uns8 buffer_byte;
00291
00292 void usb_send_one_byte(uns8 data) {
00293 delivery_buffer_size = USB_EP0_IN_SIZE;
00294 delivery_bytes_sent = 0;
00295 delivery_bytes_to_send = 1;
00296 delivery_bytes_max_send = 0;
00297 buffer_byte = data;
00298 delivery_ptr = (uns8 *) &buffer_byte;
00299 delivery_bd = &bd0in;
00300 delivery_buffer = &buffer_0_in;
00301
00302 clear_bit(bd0in.stat, DTS);
00303 usb_send_data_chunk();
00304 }
00305
00306 void usb_prime_ep0_out() {
00307 serial_putc('P');
00308 bd0out.count = USB_EP0_OUT_SIZE;
00309 bd0out.addr = USB_EP0_OUT_ADDR;
00310
00311 set_bit(bd0out.stat, DTS);
00312 clear_bit(bd0out.stat, KEN);
00313 clear_bit(bd0out.stat, INCDIS);
00314
00315 set_bit (bd0out.stat, DTSEN);
00316 clear_bit(bd0out.stat, BSTALL);
00317 clear_bit(bd0out.stat, BC9);
00318 clear_bit(bd0out.stat, BC8);
00319
00320 set_bit (bd0out.stat, UOWN);
00321 }
00322
00323 void usb_handle_standard_request(setup_data_packet sdp) {
00324
00325 switch (sdp.bRequest) {
00326 case req_Get_Descriptor:
00327 serial_print_str(" GD: ");
00328 uns8 descriptor_type = sdp.wValue >> 8;
00329 uns8 descriptor_num = sdp.wValue & 0xff;
00330 serial_print_int(descriptor_type);
00331
00332 usb_get_descriptor_callback(descriptor_type, descriptor_num, &delivery_ptr, &delivery_bytes_to_send);
00333 if (delivery_ptr != 0) {
00334 control_mode = cm_CTRL_READ_DATA_STAGE;
00335 delivery_bytes_max_send = sdp.wLength;
00336 delivery_bytes_sent = 0;
00337 delivery_buffer_size = USB_EP0_IN_SIZE;
00338 delivery_bd = &bd0in;
00339 delivery_buffer = (uns8 *)USB_EP0_IN_ADDR;
00340 clear_bit(bd0in.stat, DTS);
00341 usb_send_data_chunk();
00342 } else {
00343 serial_print_str(" <stall> ");
00344 usb_stall_ep0();
00345 }
00346
00347 break;
00348 case req_Set_Address:
00349 serial_print_str(" SA:");
00350 usb_address = sdp.wValue & 0xff;
00351 serial_print_int_hex(usb_address);
00352 usb_status = us_SET_ADDRESS;
00353
00354
00355 usb_send_status_ack();
00356 control_mode = cm_CTRL_WRITE_SENDING_STATUS;
00357 break;
00358 case req_Set_Configuration:
00359 serial_print_str(" SC: ");
00360
00361 control_mode = cm_CTRL_WRITE_SENDING_STATUS;
00362 usb_send_status_ack();
00363
00364 usb_state = st_CONFIGURED;
00365
00366
00367 usb_configure_endpoints();
00368
00369 #ifdef USB_CALLBACK_ON_DEVICE_CONFIGURED
00370 usb_device_configured_callback();
00371 #endif
00372 break;
00373 case req_Get_Interface:
00374 serial_print_str(" GI ");
00375 control_mode = cm_CTRL_READ_DATA_STAGE;
00376 usb_send_one_byte(1);
00377 case req_Get_Status:
00378
00379 serial_print_str(" GS ");
00380 #ifdef USB_SELF_POWERED
00381 usb_send_one_byte(1);
00382 #else
00383 usb_send_one_byte(0);
00384 #endif
00385 break;
00386 default:
00387 serial_print_str(" ??SR ");
00388 serial_print_int(sdp.bRequest);
00389 break;
00390
00391 }
00392 }
00393
00394
00395 void usb_handle_transaction() {
00396
00397 uns8 end_point, pid;
00398
00399 end_point = ustat >> 3;
00400
00401
00402
00403
00404
00405
00406 if (test_bit(ustat, DIR)) {
00407 serial_print_str("\nDI ");
00408 pid = (bd0in.stat >> 2) & 0x0f;
00409
00410
00411
00412 } else {
00413 serial_print_str("\nDO ");
00414 pid = (bd0out.stat >> 2) & 0x0f;
00415
00416
00417
00418 }
00419 if (end_point != 0) {
00420 serial_putc('E');
00421 serial_print_int_hex(end_point);
00422 serial_print_spc();
00423 }
00424
00425
00426
00427 if (end_point == 0) {
00428
00429
00430
00431 if (pid == pid_SETUP) {
00432
00433 memcpy( (void*)&usb_sdp, (void *)&buffer_0_out, 8);
00434 serial_print_int_hex(usb_sdp.bmRequestType);
00435
00436 usb_prime_ep0_out();
00437 serial_putc('S');
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 if (!test_bit(usb_sdp.bmRequestType, REQUEST_TYPE1) &&
00449 !test_bit(usb_sdp.bmRequestType, REQUEST_TYPE0)) {
00450
00451 if ((usb_sdp.bmRequestType & 0b00011111) == 0) {
00452
00453 } else if ((usb_sdp.bmRequestType & 0b00011111) == 1) {
00454
00455 } else if ((usb_sdp.bmRequestType & 0b00011111) == 0b00011) {
00456
00457 }
00458
00459 usb_handle_standard_request(usb_sdp);
00460 } else if (!test_bit(usb_sdp.bmRequestType, REQUEST_TYPE1) &&
00461 test_bit(usb_sdp.bmRequestType, REQUEST_TYPE0)) {
00462
00463 #ifdef USB_CALLBACK_ON_CTRL_CLASS
00464 usb_handle_class_request(usb_sdp);
00465 #endif
00466 } else {
00467
00468
00469
00470 serial_print_str(" ??req t ");
00471 serial_print_int(usb_sdp.bmRequestType);
00472 }
00473 clear_bit(ucon, PKTDIS);
00474
00475
00476 } else if (pid == pid_IN) {
00477
00478 if (control_mode == cm_CTRL_READ_DATA_STAGE) {
00479
00480 usb_send_data_chunk();
00481 } else if (control_mode == cm_CTRL_WRITE_SENDING_STATUS) {
00482
00483 control_mode = cm_IDLE;
00484 if (usb_status == us_SET_ADDRESS) {
00485
00486 usb_state = st_ADDRESS;
00487 uaddr = usb_address;
00488
00489
00490 usb_status = us_IDLE;
00491 }
00492 } else if (control_mode == cm_CTRL_READ_AWAITING_STATUS) {
00493
00494 nop();
00495 } else if (control_mode == cm_CTRL_READ_DATA_STAGE_CLASS) {
00496
00497 #ifdef USB_CALLBACK_ON_CTRL_CLASS
00498 usb_handle_ctrl_read_class();
00499 #else
00500 nop();
00501 #endif
00502 } else {
00503 serial_print_str(" ?? cm=");
00504 serial_print_int((uns8)control_mode);
00505 serial_print_spc();
00506 }
00507 } else if (pid == pid_ACK) {
00508 serial_print_str("A\n");
00509 if (control_mode == cm_CTRL_READ_DATA_STAGE) {
00510 serial_print_str(" &2 ");
00511 usb_send_data_chunk();
00512 } else if (control_mode == cm_CTRL_READ_DATA_STAGE_CLASS) {
00513 #ifdef USB_CALLBACK_ON_CTRL_CLASS
00514 usb_handle_ctrl_read_class();
00515 #else
00516 nop();
00517 #endif
00518 } else if (control_mode == cm_CTRL_WRITE_SENDING_STATUS) {
00519 serial_print_str(" st sent ");
00520 control_mode = cm_IDLE;
00521 }
00522
00523 } else if (pid == pid_OUT) {
00524
00525
00526 if (control_mode == cm_CTRL_READ_AWAITING_STATUS) {
00527
00528 control_mode = cm_IDLE;
00529 } else if (control_mode == cm_CTRL_WRITE_DATA_STAGE_CLASS) {
00530 #ifdef USB_CALLBACK_ON_CTRL_CLASS
00531 usb_handle_ctrl_write_class((uns8 *)&buffer_0_out, bd0out.count);
00532
00533
00534 #else
00535 nop();
00536 #endif
00537 } else if (control_mode == cm_CTRL_READ_DATA_STAGE) {
00538
00539 control_mode = cm_IDLE;
00540 } else {
00541
00542 serial_print_str("unk pid_OUT ");
00543 serial_print_int((uns8)control_mode);
00544 }
00545 usb_prime_ep0_out();
00546
00547 } else {
00548 serial_print_str(" UKPID = ");
00549 serial_print_int(pid);
00550 }
00551
00552 } else {
00553 buffer_descriptor *bd;
00554 if (test_bit(ustat, DIR)) {
00555
00556 #ifdef USB_EP_DATA_CALLBACK
00557 bd = ep_in_bd_location[end_point];
00558 usb_ep_data_in_callback(end_point, bd->count);
00559 #else
00560 nop();
00561 #endif
00562 } else {
00563
00564 bd = ep_out_bd_location[end_point];
00565
00566 #ifdef USB_EP_DATA_CALLBACK
00567 usb_ep_data_out_callback(end_point, ep_out_buffer_location[end_point],
00568 bd->count);
00569 #endif
00570
00571 bd->count = ep_out_buffer_size[end_point];
00572
00573
00574
00575 clear_bit(bd->stat, DTS);
00576 clear_bit(bd->stat, KEN);
00577 clear_bit(bd->stat, INCDIS);
00578 clear_bit(bd->stat, DTSEN);
00579 clear_bit(bd->stat, BSTALL);
00580 clear_bit(bd->stat, BC9);
00581 clear_bit(bd->stat, BC8);
00582 set_bit (bd->stat, UOWN);
00583
00584
00585 }
00586 }
00587 }
00588
00589 void usb_handle_reset() {
00590 usb_address = 0;
00591
00592
00593 control_mode = cm_IDLE;
00594 usb_status = us_IDLE;
00595
00596
00597 clear_bit(uir, TRNIF);
00598 clear_bit(uir, TRNIF);
00599 clear_bit(uir, TRNIF);
00600 clear_bit(uir, TRNIF);
00601
00602
00603
00604
00605
00606 bd0out.count = 8;
00607 bd0out.addr = 0x0500;
00608
00609 clear_bit(bd0out.stat, DTS);
00610 clear_bit(bd0out.stat, KEN);
00611 clear_bit(bd0out.stat, INCDIS);
00612 clear_bit (bd0out.stat, DTSEN);
00613 clear_bit(bd0out.stat, BSTALL);
00614 clear_bit(bd0out.stat, BC9);
00615 clear_bit(bd0out.stat, BC8);
00616
00617 set_bit (bd0out.stat, UOWN);
00618
00619
00620
00621 bd0in.count = 8;
00622 bd0in.addr = 0x0508;
00623 clear_bit(bd0in.stat, DTS);
00624 clear_bit(bd0in.stat, KEN);
00625 clear_bit(bd0in.stat, INCDIS);
00626 clear_bit(bd0in.stat, BSTALL);
00627 clear_bit(bd0in.stat, BC9);
00628 clear_bit(bd0in.stat, BC8);
00629
00630 clear_bit(bd0in.stat, UOWN);
00631
00632 serial_print_str("\nR ");
00633 serial_print_int_hex(uir);
00634
00635 }
00636
00637 void usb_handle_stall() {
00638 serial_print_str(" U:Stall ");
00639 }
00640
00641
00642
00643 void usb_handle_isr() {
00644
00645 if (test_bit(pir2, USBIF)) {
00646 clear_bit(pir2, USBIF);
00647
00648 if (test_bit(uir, TRNIF)) {
00649 usb_handle_transaction();
00650 clear_bit(uir, TRNIF);
00651 }
00652
00653 if (test_bit(uir, URSTIF)) {
00654 usb_handle_reset();
00655 clear_bit(uir, URSTIF);
00656 }
00657
00658 if (test_bit(uir, STALLIF)) {
00659 usb_handle_stall();
00660 clear_bit(uir, STALLIF);
00661 }
00662 #ifdef USB_CALLBACK_ON_SOF
00663 if (test_bit(uir, SOFIF)) {
00664 usb_SOF_callback(ufrm);
00665 clear_bit(uir, SOFIF);
00666 }
00667 #endif
00668 }
00669 }
00670
00671
00672 void usb_setup() {
00673
00674 usb_state = st_POWERED;
00675
00676
00677 clear_bit(ucfg, UTRDIS);
00678 set_bit(ucfg, FSEN);
00679 set_bit (ucfg, UPUEN);
00680
00681 clear_bit(ucfg, PPB1);
00682 clear_bit(ucfg, PPB0);
00683
00684
00685
00686
00687
00688
00689 ep_in_bd_location[0] = &bd0in;
00690 #if USB_HIGHEST_EP >= 1
00691 ep_in_bd_location[1] = &bd1in;
00692 #endif
00693 #if USB_HIGHEST_EP >= 2
00694 ep_in_bd_location[2] = &bd2in;
00695 #endif
00696 #if USB_HIGHEST_EP >= 3
00697 ep_in_bd_location[3] = &bd3in;
00698 #endif
00699 #if USB_HIGHEST_EP >= 4
00700 ep_in_bd_location[4] = &bd4in;
00701 #endif
00702
00703 ep_out_bd_location[0] = &bd0out;
00704 #if USB_HIGHEST_EP >= 1
00705 ep_out_bd_location[1] = &bd1out;
00706 #endif
00707 #if USB_HIGHEST_EP >= 2
00708 ep_out_bd_location[2] = &bd2out;
00709 #endif
00710 #if USB_HIGHEST_EP >= 3
00711 ep_out_bd_location[3] = &bd3out;
00712 #endif
00713 #if USB_HIGHEST_EP >= 4
00714 ep_out_bd_location[4] = &bd4out;
00715 #endif
00716
00717
00718
00719 set_bit(uep0, EPHSHK);
00720 set_bit(uep0, EPOUTEN);
00721 set_bit(uep0, EPINEN);
00722 clear_bit(uep0, EPCONDIS);
00723
00724
00725
00726 set_bit(uie, STALLIE);
00727 set_bit(uie, TRNIE);
00728 set_bit(uie, URSTIE);
00729 set_bit(pie2, USBIE);
00730 #ifdef USB_CALLBACK_ON_SOF
00731 set_bit(uie, SOFIE);
00732 #endif
00733
00734 }
00735
00736 void usb_enable_module() {
00737
00738 uir = 0;
00739 set_bit(ucon, USBEN);
00740 usb_state = st_DEFAULT;
00741 }
00742
00743 usb_state_type usb_get_state() {
00744 return usb_state;
00745 }