📄 usb_hwinterface_layer.c
字号:
This function set the Device AddressARGUMENTS PASSED: U8 Address : Address of Device to be Set. RETURN VALUE: None IMPORTANT NOTES: None ==================================================================================================*/voidipl_set_device_address(U16 Address){ /* set the USB Device address */ *(VP_U32)USB_OTG_DEVICEADDR = ((U32)Address & 0x7F) << 25;}/*==================================================================================================FUNCTION: ipl_send_stall_handshakeDESCRIPTION: This function Send/Receive the STALL HANDSHAKE to USB HostARGUMENTS PASSED: U8 endpoint - Endpoint Number . U8 direction - IN/OUT : direction of EndPoint. RETURN VALUE: None IMPORTANT NOTES: None ==================================================================================================*/voidipl_send_stall_handshake(U8 endpoint , U8 direction){ if( direction == OUT ) { *(VP_U32)( USB_OTG_ENDPTCTRL0 + (4*endpoint) ) |= STALL_RX; } else { *(VP_U32)( USB_OTG_ENDPTCTRL0 + (4*endpoint) ) |= STALL_TX; }}/*==================================================================================================FUNCTION: ipl_set_configurationDESCRIPTION: This function Handle the SET CONFIGRATION Request.ARGUMENTS PASSED: usb_end_pt_info_t* config_data;RETURN VALUE: None IMPORTANT NOTES: None ==================================================================================================*/voidipl_set_configuration(usb_end_pt_info_t* config_data){ struct dtd_t td; U32 total_bytes = 0x0; U32 buffer_addrs_page0 = 0; U32 dqh_address = 0; U32 dtd_address = 0; U8 endpt_num,direction; struct dqh_t qhead; /* get endpoint number to be configured and its direction */ endpt_num= config_data->end_pt_no; direction= config_data->direction; /* Check if the endpoint number and direction is withing the permitted range or not */ if (( endpt_num != EP0 ) && (endpt_num <= ( g_max_ep_supported - 1)) && ( direction == OUT || direction == IN)) { /* get the device q head and deice TD */ dqh_address = ipl_get_dqh(endpt_num,direction); dtd_address = ipl_get_dtd(endpt_num,direction); if ( direction == OUT ) { total_bytes = BULK_BUFFER_SIZE ; qhead.dqh_base = dqh_address; qhead.zlt = ZLT_DISABLE; qhead.mps = config_data->max_pkt_size; qhead.ios = IOS_SET; qhead.next_link_ptr = dtd_address ; 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 1 : MPS = 64, OUT (Rx endpoint) */ *(VP_U32)(USB_OTG_ENDPTCTRL0 + (0x4*endpt_num))= 0x00080048; /* Enable EP1 OUT */ *(VP_U32)(USB_OTG_ENDPTCTRL0 + ( 0x4 * endpt_num)) |= EPOUT_ENABLE; /* allocate buffer for receiving data */ 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -