📄 usb_hwinterface_layer.c
字号:
/* varify Endpoint Number and address */ if((endptno == EP0) ||(( endptno == g_out_endpoint) && ( bd->buffer != NULL))) { /* Get Device Device Queue Head of the requested endpoint */ dqh_address = ipl_get_dqh(endptno,OUT); /* Get Device Transfer Descriptor of the requested endpoint */ dtd_address = ipl_get_dtd(endptno,OUT); switch (endptno) { case EP0 : /* Get the total bytes to be received */ total_bytes = bd->size; td.dtd_base = dtd_address; td.next_link_ptr = dtd_address + 0x20; td.terminate = TERMINATE; td.total_bytes = total_bytes; td.ioc = IOC_SET; td.status = ACTIVE; td.buffer_ptr0 = g_buffer_map.ep0_buffer_addrs; td.current_offset = (g_buffer_map.ep0_buffer_addrs & 0xFFF); td.buffer_ptr1 = 0; td.buffer_ptr2 = 0; td.buffer_ptr3 = 0; td.buffer_ptr4 = 0; /* Set the Transfer Descriptor */ ipl_setup_transfer_desc(&td); /* 1. write dQH next ptr and dQH terminate bit to 0 */ *(VP_U32)(dqh_address+0x8)= dtd_address; /* 2. clear active & halt bit in dQH */ *(VP_U32)(dqh_address+0xC) &= ~0xFF; /* 3. prime endpoint by writing '1' in ENDPTPRIME */ *(VP_U32)USB_OTG_ENDPTPRIME |= ( EPOUT_PRIME << endptno );#ifndef SIMULATOR_TESTING /* 4. Wait for the Complete Status */ while (!((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & ( EPOUT_COMPLETE << endptno))); /*clear the complete status */ (*(VP_U32)USB_OTG_ENDPTCOMPLETE) = (EPOUT_COMPLETE << endptno);#endif status = USB_SUCCESS; break; default : if ((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & ( EPOUT_COMPLETE << endptno)) { /*clear the complete status */ (*(VP_U32)USB_OTG_ENDPTCOMPLETE) = (EPOUT_COMPLETE << endptno); /* get the address of the buffer in which data is received */ received_buffer_addrs = get_rxd_buffer(); if( received_buffer_addrs == NULL) { status = USB_INVALID; break; } buffer_ptr = (U32 *)received_buffer_addrs; /* calculate the received data length using number of bytes left in TD */ temp = (U32 *)dtd_address; temp++; /* pointer to total bytes in dtd */ received_data_length = (BULK_BUFFER_SIZE - (((*temp) >> 16 )&0x7FFF)); /* get the dTD buffer pointer */ buffer_addrs_page0 = alloc_buffer(); if( buffer_addrs_page0 == NULL) { status = USB_INVALID; break; } /* Get the total bytes to be received */ total_bytes = BULK_BUFFER_SIZE; /* OUT setup dTD */ td.dtd_base = dtd_address; td.next_link_ptr = dtd_address + 0x20; td.terminate = TERMINATE; td.total_bytes = total_bytes; td.ioc = IOC_SET; td.status = ACTIVE; td.buffer_ptr0 = buffer_addrs_page0; td.current_offset = ( buffer_addrs_page0 & 0xFFF ); td.buffer_ptr1 = 0x0; td.buffer_ptr2 = 0x0; td.buffer_ptr3 = 0x0; td.buffer_ptr4 = 0x0; /* Set the Transfer Descriptor */ ipl_setup_transfer_desc(&td); /* 1. write dQH next ptr and dQH terminate bit to 0 */ *(VP_U32)(dqh_address+0x8)= dtd_address; /* 2. clear active & halt bit in dQH */ *(VP_U32)(dqh_address+0xC) &= ~0xFF; /* 3. prime endpoint by writing '1' in ENDPTPRIME */ *(VP_U32)USB_OTG_ENDPTPRIME |= ( EPOUT_PRIME << endptno ); /* Copy the data from buffer to destionation pointed by buffer descriptor */ destination_ptr = ( U8 *)( bd->buffer); if(received_data_length < bd->size) { data_size = received_data_length ; } else { data_size = bd->size; } copy_from_buffer(buffer_ptr,destination_ptr,data_size); /* free the buffer after copying the data */ free_buffer(received_buffer_addrs); /* update the total bytes received in buffer descriptor */ bd->bytes_transfered = data_size ; status = USB_SUCCESS; } else { /* Endpoint Not complete is taken as 0 length data received and SUCCESS case */ /* update the total bytes received in buffer descriptor */ bd->bytes_transfered = 0x0 ; status = USB_SUCCESS; } break; } } else { status = USB_INVALID ; } return status;}/*==================================================================================================FUNCTION: ipl_receive_setup_dataDESCRIPTION: This function receive setupdata from host . ARGUMENTS PASSED: BufferDesc - This is the pointer to the buffer descriptor. Caller provides storage for the buffer and the data, RETURN VALUE: USB_SUCCESS - : The buffer was successfully processed by the USB device and data is received from the host. USB_FAILURE - : Some failure occurred in receiving the data. USB_INVALID -: If the endpoint is invalid. IMPORTANT NOTES: None ==================================================================================================*/usb_status_tipl_receive_setup_data(usb_buffer_descriptor_t* bd){ volatile struct dqh_setup_t * dqh_word ; U32 dqh_address; usb_status_t status = USB_FAILURE; U32 temp; /* varify that the address passed is not NULL */ if( bd->buffer != NULL ) { /* Get the Device Queue Head Address for EP0 OUT */ dqh_address = ipl_get_dqh(EP0,OUT); dqh_word = (volatile struct dqh_setup_t*)dqh_address; /* write '1' to clear corresponding bit in ENDPTSETUPSTAT */ *(VP_U32)USB_OTG_ENDPTSETUPSTAT = BIT0; do { /* write '1' to Setup Tripwire (SUTW) in USBCMD register */ *(VP_U32)USB_OTG_USBCMD |= BIT13; /* Copy the SetupBuffer into local software byte array */ temp = (dqh_word->dqh_word10);/* This is due to the simulator bug for word variant access on EMI but actually design has word invariant access */ *((U8 *)(bd->buffer)) = (U8 )(temp & 0x000000FF); (bd->buffer) =(U8 *)(bd->buffer) + 1; *((U8 *)(bd->buffer)) = (U8 )((temp & 0x0000FF00)>>8); (bd->buffer) =(U8 *)(bd->buffer) + 1; *((U8 *)(bd->buffer)) = (U8 )((temp & 0x00FF0000)>>16); (bd->buffer) =(U8 *)(bd->buffer) + 1; *((U8 *)(bd->buffer)) = (U8 )((temp & 0xFF000000)>>24); (bd->buffer) =(U8 *)(bd->buffer) + 1; temp = (dqh_word->dqh_word11); *((U8 *)(bd->buffer)) = (U8 )(temp & 0x000000FF); (bd->buffer) =(U8 *)(bd->buffer) + 1; *((U8 *)(bd->buffer)) = (U8 )((temp & 0x0000FF00)>>8); (bd->buffer) =(U8 *)(bd->buffer) + 1; *((U8 *)(bd->buffer)) = (U8 )((temp & 0x00FF0000)>>16); (bd->buffer) =(U8 *)(bd->buffer) + 1; *((U8 *)(bd->buffer)) = (U8 )((temp & 0xFF000000)>>24); (bd->buffer) =(U8 *)(bd->buffer) + 1; }while (!(*(VP_U32)USB_OTG_USBCMD & BIT13)); /* Write '0' to clear SUTW in USBCMD register */ *(VP_U32)USB_OTG_USBCMD &= ~BIT13; status = USB_SUCCESS; } else { status = USB_INVALID; } return status;}/*==================================================================================================FUNCTION: ipl_get_ep0_rxtx_bufferDESCRIPTION: This function returns the buffer address for EP0ARGUMENTS PASSED: None RETURN VALUE: None IMPORTANT NOTES: None ==================================================================================================*/U32 ipl_get_ep0_rxtx_buffer(){ return (g_buffer_map.ep0_buffer_addrs) ;}/*==================================================================================================FUNCTION: ipl_setup_transfer_descDESCRIPTION: This function is used to setup the dTDARGUMENTS PASSED: U32 dtd_base - Base Address of the dTD U32 next_link_ptr - Next Link Pointer, U8 terminate - terminate - TERMINATE; not terminate - NOT_TERMINATE U16 total_bytes - Total Bytes to be transfered in this dQH U8 ioc - interrupt on complete, set - IOC_SET, not set - IOC_NOTSET U8 Status - Status U32 buffer_ptr0 - Buffer Pointer page 0 U16 current_offset - current offset U32 buffer_ptr1 - Buffer Pointer page 1 U32 buffer_ptr2 - Buffer Pointer page 1 U32 buffer_ptr3 - Buffer Pointer page 1 U32 buffer_ptr4 - Buffer Pointer page 1 RETURN VALUE: None IMPORTANT NOTES: None ==================================================================================================*/void ipl_setup_transfer_desc(struct dtd_t* td){ volatile struct dtd_setup_t* dtd_word = (volatile struct dtd_setup_t *) td->dtd_base; /* Bit31:5 Next Link Pointer ; Bit0 terminate */ dtd_word->dtd_word0 = ((td->next_link_ptr & 0xFFFFFFE0) | td->terminate); /* Bit30:16 total_bytes, Bit15 ioc, Bit7:0 status */ dtd_word->dtd_word1 = ((((U32)td->total_bytes & 0x7FFF) << 16)| ((U32)td->ioc <<15) | (td->status)); /* Bit31:12 Buffer Pointer Page 0 ; Bit11:0 Current Offset */ dtd_word->dtd_word2 = ((td->buffer_ptr0 & 0xFFFFF000) | (td->current_offset & 0xFFF)); /* Bit31:12 Buffer Pointer Page 1 ; Bit10:0 Frame Number */ dtd_word->dtd_word3 = (td->buffer_ptr1 & 0xFFFFF000); /* Bit31:12 Buffer Pointer Page 2 ; */ dtd_word->dtd_word4 = (td->buffer_ptr2 & 0xFFFFF000); /* Bit31:12 Buffer Pointer Page 3 ; */ dtd_word->dtd_word5 = (td->buffer_ptr3 & 0xFFFFF000); /* Bit31:12 Buffer Pointer Page 4 ; */ dtd_word->dtd_word6 = (td->buffer_ptr4 & 0xFFFFF000);}/*==================================================================================================FUNCTION: ipl_device_only_modeDESCRIPTION: This function is used to configure the USB OTG port to Device only modeARGUMENTS PASSED: None RETURN VALUE: None IMPORTANT NOTES: None ==================================================================================================*/void ipl_device_only_mode(void){ /* Set to Device only mode */ /* *(VP_U32)USB_OTG_MIRROR_REG |= 0x1; */#ifndef SIMULATOR_TESTING /* Reset */ *(VP_U32)USB_OTG_USBCMD |= BIT1; /* wait for the Reset complete */ while (*(VP_U32)USB_OTG_USBCMD & BIT1);#endif /* set to device controller */ *(VP_U32)USB_OTG_USBMODE = 0x2; /* check that device controller was configured to device mode only */ while (!(*(VP_U32)USB_OTG_USBMODE == 0x2));}/*==================================================================================================FUNCTION: ipl_clear_dqhDESCRIPTION: This function is used to Clear the DQH before initiateARGUMENTS PASSED: None RETURN VALUE: None IMPORTANT NOTES: None ==================================================================================================*/void ipl_clear_dqh(void){ U8 i = 0; VP_U32 ep_q_hdr_base; ep_q_hdr_base = ((VP_U32)g_buffer_map.ep_dqh_base_addrs); /* Clear the dQH Memory */ for ( i = 0; i < (SIZE_OF_QHD*g_max_ep_supported*2)/sizeof(U32) ; i++) { *ep_q_hdr_base++ = 0; }}/*==================================================================================================FUNCTION: ipl_setup_qheadDESCRIPTION: This function is used to setup the dQH ------------------------ | EP2 IN (64 bytes) | | | ------------------------ dQH5 | EP2 OUT (64 bytes) | | | ------------------------ dQH4 | EP1 IN (64 bytes) | | | ------------------------ dQH3 | EP1 OUT (64 bytes) | | | ------------------------ dQH2 | EP0 IN (64 bytes) | | | ------------------------ dQH1 | EP0 OUT (64 bytes) |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -