📄 usb_hwinterface_layer.c
字号:
buffer_addrs_page0 = alloc_buffer(); /* 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 << endpt_num ); /* Endpoint Configured for output */ g_out_endpoint= endpt_num; } else { total_bytes = 0x4 ; qhead.dqh_base = ipl_get_dqh(endpt_num,direction); qhead.zlt = ZLT_DISABLE; qhead.mps = config_data->max_pkt_size; qhead.ios = IOS_SET; qhead.next_link_ptr = ipl_get_dtd(endpt_num,direction); qhead.terminate = TERMINATE; qhead.total_bytes = total_bytes; qhead.ioc = IOC_SET; qhead.status = NO_STATUS; qhead.buffer_ptr0 = 0; qhead.current_offset = 0; qhead.buffer_ptr1 = 0; qhead.buffer_ptr2 = 0; qhead.buffer_ptr3 = 0; qhead.buffer_ptr4 = 0; ipl_setup_qhead(&qhead); /* Endpoint Configured for Input */ g_in_endpoint= endpt_num; /* Endpoint 2: MPS = 64, IN (Tx endpoint) */ *(VP_U32)(USB_OTG_ENDPTCTRL0 + (0x4*endpt_num)) = 0x00480008; /* Enable EP2 IN */ *(VP_U32)(USB_OTG_ENDPTCTRL0 + (0x4*endpt_num)) |= EPIN_ENABLE; /* 3. prime endpoint by writing '1' in ENDPTPRIME */#ifndef SIMULATOR_TESTING *(VP_U32)USB_OTG_ENDPTPRIME |= (EPIN_PRIME << g_in_endpoint);#endif } } else { /* error handling TBD */ } }/*==================================================================================================FUNCTION: ipl_send_data DESCRIPTION: This function Send Data on the USB channel.ARGUMENTS PASSED: U8 endptno : Endpoint number on which data it to be send. usb_buffer_descriptor_t *bd : This is the pointer to the buffer descriptor. BOOL zlt : Boolean to decide whether Zero Length Packet is to be send or notRETURN VALUE: USB_SUCCESS - The buffer was successfully processed by the USB device and data sent to the Host. USB_FAILURE - Some failure occurred in transmitting the data. IMPORTANT NOTES: None ==================================================================================================*/usb_status_tipl_send_data(U8 endptno , usb_buffer_descriptor_t* bd,BOOL zlt){ struct dtd_t td; U32 total_bytes ; U32 dtd_address,dqh_address; U32 buffer_addrs_page0; U8* buffer_src_ptr = 0x0; U32* buffer_dest_ptr = 0x0; U32 size = 0x0; usb_status_t status = USB_SUCCESS; /* varify Endpoint Number and address */ if((endptno == EP0) ||(( endptno == g_in_endpoint) && ( bd->buffer != NULL))) { /* Get Device Transfer Descriptor of the requested endpoint */ dtd_address = ipl_get_dtd(endptno,IN); /* Get Device Queue head of the requested endpoint */ dqh_address = ipl_get_dqh(endptno,IN); /* Get Total Bytes to Be recieved */ total_bytes = bd->size; switch(endptno) { case EP0 : td.dtd_base = dtd_address; td.next_link_ptr = 0; 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); /* Enable ZLT when data size is in multiple of Maximum Packet Size */ if(zlt) { /* set ZLT enable */ (*(VP_U32)(dqh_address)) &= ~0x20000000; } /* 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 |= BIT16; /* wait for complete set and clear */ while (!((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & EPIN_COMPLETE)); *(VP_U32)USB_OTG_ENDPTCOMPLETE = EPIN_COMPLETE; status = USB_SUCCESS; break; default : /* allocate memory for data transfer */ buffer_addrs_page0 = alloc_buffer(); buffer_dest_ptr = (U32 *)buffer_addrs_page0 ; /* Get the source data pointer */ buffer_src_ptr =(U8 *) bd->buffer; if(buffer_addrs_page0 != NULL) { while(total_bytes) { if(total_bytes < BULK_BUFFER_SIZE ) { size = total_bytes; } else { size = BULK_BUFFER_SIZE; } /* copy the data to the allocated buffer */ copy_to_buffer(buffer_src_ptr,buffer_dest_ptr,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 = buffer_addrs_page0; td.current_offset = (buffer_addrs_page0 & 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 = ( EPIN_PRIME << endptno); /* wait for complete set and clear */ while (!((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & (EPIN_COMPLETE<<endptno))); *(VP_U32)USB_OTG_ENDPTCOMPLETE = ( EPIN_COMPLETE << endptno); total_bytes -= size; buffer_src_ptr += size; } /* Free the allocated buffer as transmitt is complete */ free_buffer(buffer_addrs_page0); status = USB_SUCCESS; } else { /* Return Error - TBD */ } } } else { status = USB_INVALID ; } return status;}/*==================================================================================================FUNCTION: ipl_receive_dataDESCRIPTION: This function Handle the Status Token (IN/OUT) from USB HostARGUMENTS PASSED: U8 endptno : Endpoint number on which data it to be send. usb_buffer_descriptor_t *bd : This is the pointer to the buffer descriptor. 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_data(U8 endptno, usb_buffer_descriptor_t* bd){ struct dtd_t td; usb_status_t status = USB_FAILURE; U32 total_bytes; U32 dtd_address; U32 dqh_address; U32 received_buffer_addrs = 0x0; U32* buffer_ptr = 0x0; U32 received_data_length = 0x0; U32 data_size = 0x0; U8* destination_ptr = 0x0; U32* temp = 0x0; U32 buffer_addrs_page0; /* 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;#ifndef SIMULATOR_TESTING /* 3. prime endpoint by writing '1' in ENDPTPRIME */ *(VP_U32)USB_OTG_ENDPTPRIME |= ( EPOUT_PRIME << endptno );#endif /* 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); // printf("dqh_word->dqh_word10:0x%x\n", temp); *((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); // printf("dqh_word->dqh_word11:0x%x\n", temp); *((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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -