📄 usb_ep0.c
字号:
usbd_info.address = address; usbctl_next_state_on_event( kEvAddress ); set_ep0_de_out; ep0_state = EP0_STATE_IDLE;// printf( "%sI have been assigned address: %d\n", pszMe, address ); break; case SET_DESCRIPTOR : set_descriptor(); break; case SET_CONFIGURATION : set_configuration = (__u8)req.wValue; /* low byte */#if 0 set_ep0_de_out;#endif if(req.wValue == 1 ) { /* configured */ if( usbctl_next_state_on_event( kEvConfig ) != kError ) { desc_t *pDesc = s3c24x0_usb_get_descriptor_ptr(); __u32 in = __le16_to_cpu(pDesc->b.ep2.wMaxPacketSize); __u32 out = __le16_to_cpu(pDesc->b.ep1.wMaxPacketSize); UD_INDEX = 2; UD_MAXP = UD_MAXP_64; UD_INDEX = 1; UD_MAXP = UD_MAXP_64; //printf("%sConfigured (IN MAX PACKET=%d, OUT MAX PACKET=%d)\n",pszMe, in, out); } }else if( req.wValue == 0 ) { if( usbctl_next_state_on_event( kEvDeConfig ) != kError ) printf("%sDe-Configuration\n", pszMe ); }else{ printf("%ssetup phase : Unknown [set configuration] data %d\n", pszMe, req.wValue ); } set_ep0_de_out; break; case GET_STATUS : clear_ep0_opr; UD_FIFO0 = device_status; UD_FIFO0 = 0x00; set_ep0_de_in; break; case GET_CONFIGURATION : clear_ep0_opr; UD_FIFO0 = set_configuration; set_ep0_de_in; break; case GET_DESCRIPTOR : get_descriptor(req); break; default : set_ep0_de_out; } break; /* Interface Recipient */ case kTargetInterface : switch ( req.bRequest ) { case SET_INTERFACE : set_interface = req.wValue; set_ep0_de_out; break; case GET_INTERFACE : clear_ep0_opr; UD_FIFO0 = set_interface; set_ep0_de_in; break; } break; case kTargetEndpoint : switch( req.bRequest ) { case SET_FEATURE : set_feature(req); break; case CLEAR_FEATURE : clear_feature(req); break; case GET_STATUS : clear_ep0_opr; e = windex_to_ep_num( req.wIndex ); if( e == 0 ) { UD_FIFO0 = ep0_status; UD_FIFO0 = 0x00; }else if( e == 2 ) { UD_FIFO0 = ep_bulk_in_status; UD_FIFO0 = 0x00; }else if( e == 1 ) { UD_FIFO0 = ep_bulk_out_status; UD_FIFO0 = 0x00; } set_ep0_de_in; break; case GET_DESCRIPTOR : get_descriptor(req); break; } }}static void get_descriptor(usb_dev_request_t req){ string_desc_t * pString; desc_t * pDesc = s3c24x0_usb_get_descriptor_ptr(); int type = req.wValue >> 8; int idx = req.wValue & 0xFF; switch( type ) { case USB_DESC_DEVICE : clear_ep0_opr; wr.p = (unsigned char *)&pDesc->dev; PRINTKD("\nget descriptor() DEV: req.wLengh=%d, pDesc->dev.bength=%d\n\n"\ ,req.wLength, pDesc->dev.bLength); wr.transfer_length = MIN(req.wLength, pDesc->dev.bLength); wr.transfered_data = 0; // 檬扁拳 ep0_state = EP0_STATE_TRANSFER; ep0_transmit(); break; case USB_DESC_CONFIG : clear_ep0_opr; wr.p = (unsigned char *)&pDesc->b; wr.transfer_length = MIN(req.wLength, sizeof( struct cdb )); PRINTKD("\nget descriptor() CONFIG: req.wLengh=%d, pDesc->dev.bength=%d\n\n"\ ,req.wLength, pDesc->dev.bLength); ep0_state = EP0_STATE_TRANSFER; wr.transfered_data = 0; ep0_transmit(); break; case USB_DESC_STRING : PRINTKD("STRING STRING\n"); pString = s3c24x0_usb_get_string_descriptor( idx ); if( pString ) { if (idx != 0) { // if not language index printf("%sReturn string %d: ",pszMe, idx); psdesc( pString ); } clear_ep0_opr; wr.p = (unsigned char *)pString; wr.transfer_length = MIN(req.wLength, pString->bLength); PRINTKD("\nget descriptor() String: req.wLengh=%d, pDesc->dev.bength=%d\n\n"\ ,req.wLength, pDesc->dev.bLength); ep0_state = EP0_STATE_TRANSFER; wr.transfered_data = 0; ep0_transmit(); break; } default : clear_ep0_opr; set_ep0_de_in; break; }}static void ep0_transmit(void){ int i, data_length; __u32 reg_ep0_status; __u32 reg_int_status; UD_INDEX = UD_INDEX_EP0; reg_ep0_status = UD_ICSR1; PRINTKD("EP0 want to send : %d byte\n",wr.transfer_length); /* ep0 input fifo check */ if( ( reg_ep0_status & EP0_CSR_IPKRDY) == 0 ) { data_length = wr.transfer_length - wr.transfered_data; data_length = MIN(data_length, 8); /* EP0 MAX Packet size == 8 */ /* need to check RESET, RESUME and SUSPEND Interrupts */ reg_int_status = UD_USBINT; reg_int_status &= UD_USBINT_RESET | UD_USBINT_RESUM | UD_USBINT_SUSPND; if( reg_int_status == UD_USBINT_RESET) {// if RESET occures, just return// printf(__FUNCTION__"(): UD_USBINT_RESET\n"); return; } PRINTKD(" SENDING... ["); for(i = 0; i < data_length; i++) { UD_FIFO0 = *wr.p; PRINTKD("%2.2X ", *wr.p); wr.p++; wr.transfered_data++; } PRINTKD("] \n"); PRINTKD("EP0 transfered : %d bytes\n", wr.transfered_data); PRINTKD("wr.transfered_data = %d, wr.transfer_length = %d\n", wr.transfered_data, wr.transfer_length); if( wr.transfered_data == wr.transfer_length) { reg_int_status = UD_USBINT; reg_int_status &= UD_USBINT_RESET | UD_USBINT_RESUM | UD_USBINT_SUSPND; if(reg_int_status == UD_USBINT_RESET) return; if( (wr.transfer_length % 16) == 0 && control_complete == 0 ) { control_complete = 1; set_ep0_ipr; }else{ control_complete = 0; set_ep0_de_in; ep0_state = EP0_STATE_IDLE; } return; } set_ep0_ipr; }}static void set_feature(usb_dev_request_t req){ int ep; switch( req.wValue ) { case fEndpoint_Halt : ep = windex_to_ep_num( req.wIndex ); if( ep == 0 ) { printf("%sset feature [endpoint halt] on control\n", pszMe); ep0_status = 0x001; set_ep0_ss; clear_ep0_opr; }else if( ep == 2 ) { printf("%set feature [endpoint halt] on xmitter\n",pszMe); ep_bulk_in_status = 0x0001; UD_INDEX = UD_INDEX_EP2; UD_ICSR1 |= UD_ICSR1_CLRDT; // ep2_stall(); }else if( ep == 1 ) { printf("%set feature [endpoint halt] on receiver\n",pszMe); ep_bulk_out_status = 0x0001; UD_INDEX = UD_INDEX_EP1; UD_OCSR1 |= UD_OCSR1_SENDSTL; // ep1_stall(); }else { printf("%sUnsupported feature selector (%d) in set feature\n", pszMe, req.wValue); set_ep0_de_out; } break; case fDevice_Remote_Wakeup : device_status = 0x02; set_ep0_de_out; break; default : set_ep0_de_out; break; }} static void clear_feature(usb_dev_request_t req){ int ep; switch( req.wValue ) { case fEndpoint_Halt : ep = windex_to_ep_num( req.wIndex ); if( ep == 0 ) // ep0 ep0_status = 0x0000; else if( ep == 2 ) { // ep2 input ep_bulk_in_status = 0x0000; clear_stall_ep4_out; // ep4?? PRINTKD(__FUNCTION__"(): confused. - bushi\n"); }else if( ep == 1 ) { // ep1 output ep_bulk_out_status = 0x0000; clear_stall_ep1_out; //?? }else PRINTKD("%sUnsupported endpoint (%d)\n", pszMe, ep); set_ep0_de_out; break; case fDevice_Remote_Wakeup : device_status = 0x00; set_ep0_de_out; break; default : set_ep0_de_out; break; }}static void set_descriptor(void){ set_ep0_de_out;}static void ep0_receive(void){}/* * read_fifo() * Read 1-8 bytes out of FIFO and put in request. * Called to do the initial read of setup requests * from the host. Return number of bytes read. * * Like write fifo above, this driver uses multiple * reads checked agains the count register with an * overall timeout. * */static intread_fifo( usb_dev_request_t * request ){ int bytes_read = 0; int fifo_count = 0; int i, ep; unsigned char * pOut = (unsigned char*) request; ep = windex_to_ep_num( request->wIndex ); PRINTKD(__FUNCTION__"(): ep = %d\n", ep); switch (ep) { case 0: UD_INDEX = UD_INDEX_EP0; break; case 2: UD_INDEX = UD_INDEX_EP2; break; case 1: UD_INDEX = UD_INDEX_EP1; break; default: PRINTKD(__FUNCTION__"(): ???? ep = %d\n", ep); UD_INDEX = UD_INDEX_EP0; } fifo_count = (( UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff; ASSERT( fifo_count <= 8 ); PRINTKD(__FUNCTION__ "(): fifo_count =%d ", fifo_count ); while( fifo_count-- ) { i = 0; do { *pOut = (unsigned char) UD_FIFO0; udelay( 10 ); i++; } while( ( (( UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff ) != fifo_count && i < 10 ); if ( i == 10 ) { printf( "%sread_fifo(): read failure\n", pszMe ); usbd_info.stats.ep0_fifo_read_failures++; } pOut++; bytes_read++; } PRINTKD( "bytes_read=%d\n", bytes_read ); usbd_info.stats.ep0_bytes_read++; return bytes_read;}/* end usb_ep0.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -