Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00017 #include "nrf24lu1p.h"
00018 #include <stdint.h>
00019 #ifdef __ICC8051__
00020 #include <intrinsics.h>
00021 #endif
00022 #ifdef __C51__
00023 #include <intrins.h>
00024 #endif
00025
00026 #include "nordic_common.h"
00027 #include "hal_usb_desc.h"
00028 #include "usb.h"
00029 #include "hal_delay.h"
00030
00031
00032 #define ALLOCATE_USB_MAP
00033 #include "usb_map.h"
00034
00035
00036
00037
00038 #define CALCULATE_CS_IN_PTR(ep) (uint8_t xdata*)(&in1cs + 2 * ((ep & 0x7f) - 1 ))
00039 #define CALCULATE_CS_OUT_PTR(ep) (uint8_t xdata*)(&out1cs + 2 * ( (ep & 0x7f) - 1 ))
00040
00041
00042 #define CALCULATE_BC_OUT_PTR(ep) (uint8_t xdata *)(&out0bc + (ep * 2 ))
00043 #define CALCULATE_BC_IN_PTR(ep) (uint8_t xdata *)(&in0bc + ((ep & 0x7f ) * 2))
00044
00045
00046 #define CALCULATE_BUF_IN_PTR(ep) (uint8_t xdata *)(in0buf - (( ep & 0x7f) * 128))
00047 #define CALCULATE_BUF_OUT_PTR(ep) (uint8_t xdata *)(out0buf - (ep * 128 ))
00048
00049 static packetizer_t i_packetizer;
00050 static hal_usb_cb_endpoint_t i_endpoint_in_isr[USB_ENDPOINT_IN_COUNT];
00051 static hal_usb_cb_endpoint_t i_endpoint_out_isr[USB_ENDPOINT_OUT_COUNT];
00052
00053 static hal_usb_device_req req;
00054 hal_usb_t volatile g_hal_usb;
00055 static uint8_t stall_data_size0;
00056
00057 void hal_usb_init(bool usb_disconnect, hal_usb_cb_device_req_t device_req, hal_usb_cb_reset_t reset, hal_usb_cb_resume_t resume, hal_usb_cb_suspend_t suspend)
00058 {
00059
00060 g_hal_usb.descs.dev = &g_usb_dev_desc;
00061 g_hal_usb.descs.conf = &g_usb_conf_desc;
00062 g_hal_usb.descs.string = &g_usb_string_desc;
00063
00064
00065 g_hal_usb.descs.string_zero[0] = 0x04;
00066 g_hal_usb.descs.string_zero[1] = 0x03;
00067 g_hal_usb.descs.string_zero[2] = 0x09;
00068 g_hal_usb.descs.string_zero[3] = 0x04;
00069
00070
00071 g_hal_usb.state = DEFAULT;
00072 g_hal_usb.bm_state = 0;
00073 stall_data_size0 = 0;
00074
00075
00076 g_hal_usb.current_config = 0;
00077 g_hal_usb.current_alt_interface = 0;
00078
00079
00080 g_hal_usb.device_req = device_req;
00081 g_hal_usb.reset = reset;
00082 g_hal_usb.resume = resume;
00083 g_hal_usb.suspend = suspend;
00084
00085
00086 if(usb_disconnect)
00087 {
00088 usbcs |= 0x08;
00089 delay_ms(50);
00090 usbcs &= ~(0x08);
00091 }
00092
00093
00094 USBWU = 1;
00095 USB = 1;
00096
00097 usbien = 0x1d;
00098
00099 in_ien = 0x01;
00100 in_irq = 0x1f;
00101 out_ien = 0x01;
00102 out_irq = 0x1f;
00103
00104
00105 bout1addr = 16;
00106 bout2addr = 32;
00107 bout3addr = 48;
00108 bout4addr = 64;
00109 bout5addr = 80;
00110
00111 binstaddr = 0xc0;
00112 bin1addr = 16;
00113 bin2addr = 32;
00114 bin3addr = 48;
00115 bin4addr = 64;
00116 bin5addr = 80;
00117
00118
00119 inbulkval = 0x01;
00120 outbulkval = 0x01;
00121 inisoval = 0x00;
00122 outisoval = 0x00;
00123 }
00124
00125 void hal_usb_endpoint_stall(uint8_t ep_num, bool stall)
00126 {
00127 uint8_t temp;
00128 uint8_t xdata *cs_ptr;
00129
00130 temp = 2 * ((ep_num & 0x7f) - 1);
00131
00132
00133 if((ep_num & 0x80 ) == 0x80)
00134 {
00135
00136 cs_ptr = (uint8_t xdata*)(&in1cs + temp);
00137 }
00138 else
00139 {
00140
00141 cs_ptr = (uint8_t xdata*)(&out1cs + temp);
00142 }
00143
00144 if(stall == true)
00145 {
00146
00147 *cs_ptr = 0x01;
00148 }
00149 else
00150 {
00151
00152 *cs_ptr = 0x00;
00153 }
00154 }
00155
00156 uint8_t hal_usb_get_address()
00157 {
00158 return fnaddr;
00159 }
00160
00161 void hal_usb_endpoint_config(uint8_t ep_num, uint8_t ep_size, hal_usb_cb_endpoint_t endpoint_isr)
00162 {
00163 uint8_t xdata *bc_ptr;
00164 uint8_t temp = (ep_num & 0x7f) - 1;
00165 uint8_t stemp = 1 << (ep_num & 0x7f);
00166
00167
00168 ep_size = 0;
00169
00170 if((ep_num & 0x80 ) == 0x80)
00171 {
00172 i_endpoint_in_isr[temp] = endpoint_isr;
00173 if(endpoint_isr != NULL)
00174 {
00175
00176 in_ien |= stemp;
00177 inbulkval |= stemp;
00178 }
00179 else
00180 {
00181
00182 in_ien &= ~stemp;
00183 inbulkval &= ~stemp;
00184 }
00185 }
00186 else
00187 {
00188 i_endpoint_out_isr[temp] = endpoint_isr;
00189 if(endpoint_isr != NULL)
00190 {
00191
00192 out_ien |= stemp;
00193 outbulkval |= stemp;
00194
00195
00196 bc_ptr = CALCULATE_BC_OUT_PTR(ep_num);
00197 *bc_ptr = 0xff;
00198 }
00199 else
00200 {
00201
00202 out_ien &= ~stemp;
00203 outbulkval &= ~stemp;
00204 }
00205 }
00206 }
00207
00208 void hal_usb_wakeup()
00209 {
00210
00211 if((g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP)
00212 {
00213 USBCON = 0x40;
00214 delay_ms(1);
00215 USBCON = 0x00;
00216 }
00217 }
00218
00219 void hal_usb_reset()
00220 {
00221 SWRST = 1;
00222 }
00223
00224 #pragma disable
00225 hal_usb_state_t hal_usb_get_state()
00226 {
00227 return g_hal_usb.state;
00228 }
00229
00230 void hal_usb_send_data(uint8_t ep_num, uint8_t* array, uint8_t count)
00231 {
00232 uint8_t i;
00233
00234 uint8_t xdata *buf_ptr;
00235 uint8_t xdata *bc_ptr;
00236
00237
00238 buf_ptr = CALCULATE_BUF_IN_PTR(ep_num);
00239 bc_ptr = CALCULATE_BC_IN_PTR(ep_num);
00240
00241
00242 for( i = 0; i < count; i++ )
00243 {
00244 buf_ptr[i] = array[i];
00245 }
00246
00247
00248 *bc_ptr = count;
00249 }
00250
00251 void hal_usb_bus_disconnect()
00252 {
00253 usbcs |= 0x08;
00254 }
00255
00256 void hal_usb_bus_connect()
00257 {
00258 usbcs &= ~(0x08);
00259 }
00260
00261 void hal_usb_sleep()
00262 {
00263 USBSLP = 1;
00264 }
00265
00266 static void packetize(uint8_t *data_ptr, uint8_t data_size)
00267 {
00268 i_packetizer.data_ptr = data_ptr;
00269 i_packetizer.data_size = data_size;
00270 i_packetizer.pkt_size = g_hal_usb.descs.dev->bMaxPacketSize0;
00271 }
00272
00273
00274 static void packetizer_isr_ep0_in(void)
00275 {
00276 uint8_t size, i;
00277
00278
00279 if(i_packetizer.data_size == 0)
00280 {
00281 if (stall_data_size0 == 1)
00282 {
00283 USB_EP0_DSTALL();
00284 }
00285 else
00286 {
00287 stall_data_size0 = 1;
00288 in0bc = 0;
00289 USB_EP0_HSNAK();
00290 }
00291 return;
00292 }
00293
00294 size = MIN(i_packetizer.data_size, i_packetizer.pkt_size);
00295
00296
00297 for(i = 0; i < size; i++)
00298 {
00299 in0buf[i] = i_packetizer.data_ptr[i];
00300 }
00301
00302 if (size < i_packetizer.pkt_size)
00303 stall_data_size0 = 1;
00304
00305
00306 in0bc = size;
00307
00308
00309 i_packetizer.data_ptr += size;
00310 i_packetizer.data_size -= size;
00311
00312 return;
00313 }
00314
00316 static void usb_process_dev_req_cb_response(void)
00317 {
00318 uint8_t *data_ptr;
00319 uint8_t data_size;
00320 hal_usb_dev_req_resp_t ret = g_hal_usb.device_req(&req, &data_ptr, &data_size);
00321
00322 switch(ret)
00323 {
00324 case DATA:
00325 packetize((uint8_t *)data_ptr, MIN(req.wLength, data_size));
00326 packetizer_isr_ep0_in();
00327 break;
00328 case NO_RESPONSE:
00329 break;
00330 case EMPTY_RESPONSE:
00331 case NAK:
00332 USB_EP0_HSNAK();
00333 break;
00334 case ACK:
00335 out0bc = 0xff;
00336 break;
00337 case STALL:
00338 default:
00339 USB_EP0_STALL();
00340 break;
00341 }
00342 }
00343
00344 static void usb_process_get_status(void)
00345 {
00346 uint8_t xdata *ptr;
00347
00348 if(g_hal_usb.state == ADDRESSED)
00349 {
00350 if(req.wIndex != 0x00)
00351 {
00352 USB_EP0_STALL();
00353 }
00354 else
00355 {
00356 in0buf[0] = in0buf[1] =
00357 ((g_hal_usb.descs.conf->conf.bmAttributes & 0x40 ) >> 6);
00358 in0bc = 0x02;
00359 }
00360 }
00361 else if(g_hal_usb.state == CONFIGURED)
00362 {
00363 in0buf[1] = 0x00;
00364 switch(req.bmRequestType)
00365 {
00366 case 0x80:
00367 if((g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP)
00368 {
00369 in0buf[0] = 0x02;
00370 }
00371 else
00372 {
00373 in0buf[0] = 0x00;
00374 }
00375
00376 in0buf[0] |= ((g_hal_usb.descs.conf->conf.bmAttributes & 0x40 ) >> 6);
00377 in0bc = 0x02;
00378 break;
00379 case 0x81:
00380 in0buf[0] = 0x00;
00381 in0bc = 0x02;
00382 break;
00383 case 0x82:
00384 if((req.wIndex & 0x80) == 0x80)
00385 {
00386 ptr = CALCULATE_CS_IN_PTR(req.wIndex);
00387 }
00388 else
00389 {
00390 ptr = CALCULATE_CS_OUT_PTR(req.wIndex);
00391 }
00392
00393 in0buf[0] = *ptr & 0x01;
00394 in0bc = 0x02;
00395 break;
00396 default:
00397 USB_EP0_STALL();
00398 break;
00399 }
00400 }
00401 else
00402 {
00403
00404 USB_EP0_STALL();
00405 }
00406 }
00407
00408 static void usb_process_get_descriptor(void)
00409 {
00410
00411 switch(req.wValueMsb)
00412 {
00413 case USB_DESC_DEVICE:
00414 packetize((uint8_t *)g_hal_usb.descs.dev,
00415 MIN(req.wLength, sizeof(hal_usb_dev_desc_t)));
00416 packetizer_isr_ep0_in();
00417 break;
00418 case USB_DESC_CONFIGURATION:
00419
00420 packetize((uint8_t *)g_hal_usb.descs.conf,
00421 MIN(req.wLength, sizeof(usb_conf_desc_templ_t)));
00422 packetizer_isr_ep0_in();
00423 break;
00424 case USB_DESC_STRING:
00425
00426 if(req.wValueLsb == 0x00)
00427 {
00428 packetize(g_hal_usb.descs.string_zero, MIN(req.wLength, sizeof(g_hal_usb.descs.string_zero)));
00429 packetizer_isr_ep0_in();
00430 }
00431 else
00432 {
00433 if((req.wValueLsb - 1 ) < USB_STRING_DESC_COUNT)
00434 {
00435 packetize((uint8_t *)(g_hal_usb.descs.string->idx[req.wValueLsb-1]),
00436 MIN(req.wLength, g_hal_usb.descs.string->idx[req.wValueLsb-1][0]));
00437 packetizer_isr_ep0_in();
00438 }
00439 else
00440 {
00441 USB_EP0_STALL();
00442 }
00443 }
00444 break;
00445 case USB_DESC_INTERFACE:
00446 case USB_DESC_ENDPOINT:
00447 case USB_DESC_DEVICE_QUAL:
00448 case USB_DESC_OTHER_SPEED_CONF:
00449 case USB_DESC_INTERFACE_POWER:
00450 USB_EP0_STALL();
00451 break;
00452 default:
00453 usb_process_dev_req_cb_response();
00454 break;
00455 }
00456 }
00457
00458 static void isr_sudav(void)
00459 {
00460
00461 req.bmRequestType = setupbuf[0];
00462 req.bRequest = setupbuf[1];
00463 req.wValueLsb = setupbuf[2];
00464 req.wValueMsb = setupbuf[3];
00465 req.wIndex = setupbuf[4];
00466 req.wLength = setupbuf[6];
00467 if (setupbuf[7] > 0)
00468 {
00469 req.wLength = 0xff;
00470 }
00471
00472
00473 if((req.bmRequestType & 0x60) == 0x00)
00474 {
00475 switch(req.bRequest)
00476 {
00477 case USB_REQ_GET_DESCRIPTOR:
00478 usb_process_get_descriptor();
00479 break;
00480 case USB_REQ_GET_STATUS:
00481 usb_process_get_status();
00482 break;
00483 case USB_REQ_CLEAR_FEATURE:
00484 case USB_REQ_SET_FEATURE:
00485 switch(req.bmRequestType)
00486 {
00487 case 0x00:
00488 if(req.wValueLsb == USB_DEVICE_REMOTE_WAKEUP)
00489 {
00490 if (req.bRequest == USB_REQ_CLEAR_FEATURE)
00491 g_hal_usb.bm_state &= ~(USB_BM_STATE_ALLOW_REMOTE_WAKEUP);
00492 else
00493 g_hal_usb.bm_state |= USB_BM_STATE_ALLOW_REMOTE_WAKEUP;
00494 USB_EP0_HSNAK();
00495 }
00496 else
00497 {
00498 USB_EP0_STALL();
00499 }
00500 break;
00501
00502 case 0x02:
00503 if(req.wValueLsb == USB_ENDPOINT_HALT)
00504 {
00505 if (req.bRequest == USB_REQ_CLEAR_FEATURE)
00506 hal_usb_endpoint_stall(req.wIndex, false);
00507 else
00508 hal_usb_endpoint_stall(req.wIndex, true);
00509 USB_EP0_HSNAK();
00510 }
00511 else
00512 {
00513 USB_EP0_STALL();
00514 }
00515 break;
00516 case 0x01:
00517 default:
00518 USB_EP0_STALL();
00519 break;
00520 }
00521 break;
00522
00523 case USB_REQ_SET_ADDRESS:
00524 g_hal_usb.state = ADDRESSED;
00525 g_hal_usb.current_config = 0x00;
00526 break;
00527 case USB_REQ_GET_CONFIGURATION:
00528 switch(g_hal_usb.state)
00529 {
00530 case ADDRESSED:
00531 in0buf[0] = 0x00;
00532 in0bc = 0x01;
00533 break;
00534 case CONFIGURED:
00535 in0buf[0] = g_hal_usb.current_config;
00536 in0bc = 0x01;
00537 break;
00538 default:
00539 USB_EP0_STALL();
00540 break;
00541 }
00542 break;
00543 case USB_REQ_SET_CONFIGURATION:
00544 switch(req.wValueLsb)
00545 {
00546 case 0x00:
00547 g_hal_usb.state = ADDRESSED;
00548 g_hal_usb.current_config = 0x00;
00549 USB_EP0_HSNAK();
00550 break;
00551 case 0x01:
00552 g_hal_usb.state = CONFIGURED;
00553 g_hal_usb.bm_state |= USB_BM_STATE_CONFIGURED;
00554 g_hal_usb.current_config = 0x01;
00555 USB_EP0_HSNAK();
00556 break;
00557 default:
00558 USB_EP0_STALL();
00559 break;
00560 }
00561 break;
00562 case USB_REQ_GET_INTERFACE:
00563 in0buf[0] = g_hal_usb.current_alt_interface;
00564 in0bc = 0x01;
00565 break;
00566 case USB_REQ_SET_DESCRIPTOR:
00567 case USB_REQ_SET_INTERFACE:
00568 case USB_REQ_SYNCH_FRAME:
00569 default:
00570 USB_EP0_STALL();
00571 break;
00572 };
00573 }
00574
00575 else if((req.bmRequestType & 0x60 ) == 0x20)
00576 {
00577 if(req.wLength != 0 && ((req.bmRequestType & 0x80) == 0x00))
00578 {
00579
00580
00581 out0bc = 0xff;
00582 }
00583 else
00584 {
00585 usb_process_dev_req_cb_response();
00586 }
00587
00588 }
00589 else
00590 {
00591 USB_EP0_STALL();
00592 }
00593 }
00594
00595 static void isr_suspend(void)
00596 {
00597 uint8_t allow_remote_wu = 0;
00598 g_hal_usb.bm_state &= ~(USB_BM_STATE_HOST_WU);
00599
00600 if( g_hal_usb.state == CONFIGURED )
00601 {
00602 if( ( g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP )
00603 {
00604 allow_remote_wu = 1;
00605 }
00606 }
00607
00608 g_hal_usb.state = SUSPENDED;
00609
00610 if( g_hal_usb.suspend != NULL )
00611 {
00612 g_hal_usb.suspend(allow_remote_wu);
00613 }
00614 }
00615
00616 static void isr_usbreset(void)
00617 {
00618 g_hal_usb.state = DEFAULT;
00619 g_hal_usb.current_config = 0;
00620 g_hal_usb.current_alt_interface = 0;
00621 g_hal_usb.bm_state = 0;
00622 if( g_hal_usb.reset != NULL ) g_hal_usb.reset();
00623 }
00624
00625
00626 USB_WU_ISR()
00627 {
00628 #define ICH4
00629 #ifdef ICH4
00630 uint8_t t;
00631 #endif
00632
00633
00634
00635
00636 if( ( usbcs & 0x80 ) == 0x80 )
00637 {
00638
00639 usbcs = 0x80;
00640
00641
00642 if( ( g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP )
00643 {
00644 #ifdef ICH4
00645
00646 usbcs |= 0x02;
00647
00648
00649 _nop_();
00650 _nop_();
00651
00652 t = usbcs;
00653
00654
00655 t &= ~0x02;
00656
00657
00658 t |= 0x01;
00659
00660
00661
00662 usbcs = t;
00663 #else
00664 usbcs |= 0x01;
00665 #endif
00666 delay_ms(7);
00667
00668
00669 usbcs &= ~0x01;
00670 }
00671 }
00672 else
00673 {
00674
00675 g_hal_usb.bm_state |= USB_BM_STATE_HOST_WU;
00676 }
00677
00678 if((g_hal_usb.bm_state & USB_BM_STATE_CONFIGURED ) == USB_BM_STATE_CONFIGURED)
00679 {
00680 g_hal_usb.state = CONFIGURED;
00681 }
00682 else
00683 {
00684 g_hal_usb.state = DEFAULT;
00685 }
00686
00687
00688 g_hal_usb.resume();
00689 }
00690
00691
00692 static void usb_process_ep_response(uint8_t ret, uint8_t xdata* cs_ptr, uint8_t xdata* bc_ptr)
00693 {
00694 if( ret == 0xff )
00695 {
00696 *bc_ptr = 0xff;
00697 }
00698 else if( ( ret & 0x80 ) == 0x80 )
00699 {
00700 *cs_ptr = 0x01;
00701 }
00702 else if( ( ret & 0x60 ) == 0x60 )
00703 {
00704 *cs_ptr = 0x02;
00705 }
00706 else if( ret == 0 )
00707 {
00708 *bc_ptr = 0;
00709 }
00710 else
00711 {
00712 *bc_ptr = ret;
00713 }
00714 }
00715
00716 USB_ISR()
00717 {
00718 uint8_t ep;
00719 uint8_t ret;
00720 uint8_t xdata *cs_ptr;
00721 uint8_t xdata *buf_ptr;
00722 uint8_t xdata *bc_ptr;
00723
00724 switch(ivec)
00725 {
00726 case INT_SUDAV:
00727 usbirq = 0x01;
00728 isr_sudav();
00729 break;
00730 case INT_SOF:
00731 usbirq = 0x02;
00732 break;
00733 case INT_SUTOK:
00734 usbirq = 0x04;
00735 i_packetizer.data_ptr = NULL;
00736 i_packetizer.data_size = 0;
00737 i_packetizer.pkt_size = 0;
00738 stall_data_size0 = 0;
00739 break;
00740 case INT_SUSPEND:
00741 usbirq = 0x08;
00742 isr_suspend();
00743 break;
00744 case INT_USBRESET:
00745 usbirq = 0x10;
00746 isr_usbreset();
00747 break;
00748 case INT_EP0IN:
00749 in_irq = 0x01;
00750 packetizer_isr_ep0_in();
00751 break;
00752 case INT_EP0OUT:
00753 out_irq = 0x01;
00754 i_packetizer.data_size = 0;
00755 usb_process_dev_req_cb_response();
00756 break;
00757 case INT_EP1IN:
00758 case INT_EP2IN:
00759 case INT_EP3IN:
00760 case INT_EP4IN:
00761 case INT_EP5IN:
00762
00763 ep = (ivec - INT_EP0IN ) >> 3;
00764
00765 in_irq = ( 1 << ep );
00766
00767 cs_ptr = CALCULATE_CS_IN_PTR(ep);
00768 buf_ptr = CALCULATE_BUF_IN_PTR(ep);
00769 bc_ptr = CALCULATE_BC_IN_PTR(ep);
00770
00771
00772 ret = i_endpoint_in_isr[ep - 1](buf_ptr, bc_ptr);
00773 usb_process_ep_response(ret, cs_ptr, bc_ptr);
00774 break;
00775 case INT_EP1OUT:
00776 case INT_EP2OUT:
00777 case INT_EP3OUT:
00778 case INT_EP4OUT:
00779 case INT_EP5OUT:
00780
00781 ep = (ivec - INT_EP0OUT) >> 3;
00782
00783
00784 out_irq = ( 1 << ep );
00785
00786 cs_ptr = CALCULATE_CS_OUT_PTR(ep);
00787 buf_ptr = CALCULATE_BUF_OUT_PTR(ep);
00788 bc_ptr = CALCULATE_BC_OUT_PTR(ep);
00789
00790
00791 ret = (i_endpoint_out_isr[ep - 1])(buf_ptr, bc_ptr);
00792 usb_process_ep_response(ret, cs_ptr, bc_ptr);
00793 break;
00794 default:
00795 break;
00796 };
00797 }