void sd_mmc_mci_read_multiple_sector_callback(const void *psector) { #ifdef USB_DEVICE_VENDOR_ID // USB Device Stack V2 udi_msc_trans_block( true, (uint8_t*)psector, SD_MMC_SECTOR_SIZE, NULL); #else // USB Device Stack V1 uint16_t data_to_transfer = SD_MMC_SECTOR_SIZE; // Transfer read sector to the USB interface. while (data_to_transfer) { while (!Is_usb_in_ready(g_scsi_ep_ms_in)) { if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) return; // USB Reset } Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_in); data_to_transfer = usb_write_ep_txpacket(g_scsi_ep_ms_in, psector, data_to_transfer, &psector); Usb_ack_in_ready_send(g_scsi_ep_ms_in); } #endif }
void sd_mmc_mci_write_multiple_sector_callback(void *psector) { #ifdef USB_DEVICE_VENDOR_ID // USB Device Stack V2 udi_msc_trans_block( false, (uint8_t*)psector, SD_MMC_SECTOR_SIZE, NULL); #else // USB Device Stack V1 uint16_t data_to_transfer = SD_MMC_SECTOR_SIZE; // Transfer sector to write from the USB interface. while (data_to_transfer) { while (!Is_usb_out_received(g_scsi_ep_ms_out)) { if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_out)) return; // USB Reset } Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_out); data_to_transfer = usb_read_ep_rxpacket(g_scsi_ep_ms_out, psector, data_to_transfer, &psector); Usb_ack_out_received_free(g_scsi_ep_ms_out); } #endif }
void sendKeys(u8* buffer) { u32 i; #ifdef NOT_USED if (bDeviceState == CONFIGURED) { while(!PrevXferComplete); PrevXferComplete = 0; /* Use the memory interface function to write to the selected endpoint */ UserToPMABufferCopy(buffer, ENDP4_TXADDR, 8); /* Update the data length in the control register */ SetEPTxCount(ENDP4, 8); SetEPTxStatus (ENDP4, EP_TX_VALID); } #endif while (Is_usb_endpoint_stall_requested(EP_KB_IN)) { if (Is_usb_setup_received()) { usb_process_request(); } } // MSC Compliance - Free BAD out receive during SCSI command while( Is_usb_out_received(EP_CCID_OUT) ) { Usb_ack_out_received_free(EP_CCID_OUT); } while (!Is_usb_in_ready(EP_KB_IN)) { if(!Is_usb_endpoint_enabled(EP_KB_IN)) { i = 0; // todo USB Reset } } Usb_reset_endpoint_fifo_access(EP_KB_IN); /* Usb_write_endpoint_data(EP_KB_IN, 8, 'D'); Usb_write_endpoint_data(EP_KB_IN, 8, 'D'); Usb_write_endpoint_data(EP_KB_IN, 8, 'D'); Usb_write_endpoint_data(EP_KB_IN, 8, 'D'); */ usb_write_ep_txpacket(EP_KB_IN, buffer, 8, NULL); // Usb_send_in(EP_CONTROL); Usb_ack_in_ready_send(EP_KB_IN); // MSC Compliance - Wait end of all transmitions on USB line while( 0 != Usb_nb_busy_bank(EP_KB_IN) ) { if (Is_usb_setup_received()) usb_process_request(); } }
void cdc_ecm_notify_connection_speed_change(uint32_t upstream,uint32_t downstream) { #if CDC_ECM_USES_INTERRUPT_ENDPOINT Usb_select_endpoint(INT_EP); if(!Is_usb_endpoint_enabled()) return; if(usb_endpoint_wait_for_IN_ready()!=0) return; Usb_send_control_in(); Usb_write_byte(0x51); // 10100001b Usb_write_byte(CDC_NOTIFY_CONNECTION_SPEED_CHANGE); Usb_write_word(0x0000); Usb_write_word(ECM_INTERFACE0_NB); Usb_write_word(0x0008); Usb_send_in(); if(usb_endpoint_wait_for_write_enabled()!=0) return; Usb_write_long(upstream); Usb_write_long(downstream); Usb_send_in(); PRINTF_P(PSTR("cdc_ecm: CDC_NOTIFY_CONNECTION_SPEED_CHANGE UP:%d DOWN:%d\n"),upstream,downstream); #endif }
void cdc_ecm_notify_network_connection(uint8_t value) { #if CDC_ECM_USES_INTERRUPT_ENDPOINT Usb_select_endpoint(INT_EP); if(!Is_usb_endpoint_enabled()) { //PRINTF_P(PSTR("cdc_ecm: cdc_ecm_notify_network_connection: endpoint not enabled\n")); return; } if(usb_endpoint_wait_for_IN_ready()!=0) { //PRINTF_P(PSTR("cdc_ecm: cdc_ecm_notify_network_connection: Timeout waiting for interrupt endpoint to be available\n")); return; } Usb_send_control_in(); Usb_write_byte(0x51); // 10100001b Usb_write_byte(CDC_NOTIFY_NETWORK_CONNECTION); Usb_write_byte(value); Usb_write_byte(0x00); Usb_write_word(ECM_INTERFACE0_NB); Usb_write_word(0x0000); Usb_send_in(); PRINTF_P(PSTR("cdc_ecm: CDC_NOTIFY_NETWORK_CONNECTION %d\n"),value); #endif }
//! usb_init_device. //! //! This function initializes the USB device controller and //! configures the Default Control Endpoint. //! //! //! @param none //! //! @return status //! U8 usb_init_device (void) { Usb_select_device(); if(Is_usb_id_device()) { Usb_select_endpoint(EP_CONTROL); if(!Is_usb_endpoint_enabled()) { #if (USB_LOW_SPEED_DEVICE==DISABLE) return usb_configure_endpoint(EP_CONTROL, \ TYPE_CONTROL, \ DIRECTION_OUT, \ SIZE_64, \ ONE_BANK, \ NYET_DISABLED); #else return usb_configure_endpoint(EP_CONTROL, \ TYPE_CONTROL, \ DIRECTION_OUT, \ SIZE_8, \ ONE_BANK, \ NYET_DISABLED); #endif } } return FALSE; }
//! usb_init_device //! //! This function initializes the USB device controller and //! configures the Default Control Endpoint. //! //! @return Status //! Status_bool_t usb_init_device(void) { return Is_usb_id_device() && !Is_usb_endpoint_enabled(EP_CONTROL) && Usb_configure_endpoint(EP_CONTROL, TYPE_CONTROL, DIRECTION_OUT, EP_CONTROL_LENGTH, SINGLE_BANK); }
//! usb_set_feature. //! //! This function manages the SET FEATURE request. The USB test modes are //! supported by this function. //! //! @warning Code:xx bytes (function code length) //! //! @param none //! //! @return none //! void usb_set_feature(void) { U8 wValue; U8 wIndex; U8 dummy; if (bmRequestType == INTERFACE_TYPE) { //!< keep that order (set StallRq/clear RxSetup) or a //!< OUT request following the SETUP may be acknowledged Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } else if (bmRequestType == ENDPOINT_TYPE) { wValue = Usb_read_byte(); dummy = Usb_read_byte(); //!< dummy read if (wValue == FEATURE_ENDPOINT_HALT) { wIndex = (Usb_read_byte() & MSK_EP_DIR); if (wIndex == EP_CONTROL) { Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } Usb_select_endpoint(wIndex); if(Is_usb_endpoint_enabled()) { Usb_enable_stall_handshake(); Usb_select_endpoint(EP_CONTROL); endpoint_status[wIndex] = 0x01; Usb_ack_receive_setup(); Usb_send_control_in(); } else { Usb_select_endpoint(EP_CONTROL); Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } } else { Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } } }
static void USB_CCID_SendDataToUSB (void) { int USB_Datalen_s32; int i; while (Is_usb_endpoint_stall_requested (EP_CCID_IN)) { if (Is_usb_setup_received ()) usb_process_request (); } while (Is_usb_endpoint_stall_requested (EP_CCID_OUT)) { if (Is_usb_setup_received ()) usb_process_request (); } // MSC Compliance - Free BAD out receive during SCSI command while (Is_usb_out_received (EP_CCID_OUT)) { Usb_ack_out_received_free (EP_CCID_OUT); } while (!Is_usb_in_ready (EP_CCID_IN)) { if (!Is_usb_endpoint_enabled (EP_CCID_IN)) { i = 0; // todo USB Reset } } Usb_reset_endpoint_fifo_access (EP_CCID_IN); USB_Datalen_s32 = USB_CCID_data_st.CCID_datalen + 10; for (i = 0; i < USB_Datalen_s32; i++) { Usb_write_endpoint_data (EP_CCID_IN, 8, USB_CCID_data_st.USB_data[i]); } Usb_ack_in_ready_send (EP_CCID_IN); USB_Log_st.CCID_ReadCalls_u32++; USB_Log_st.CCID_BytesRead_u32 += USB_Datalen_s32; // MSC Compliance - Wait end of all transmitions on USB line while (0 != Usb_nb_busy_bank (EP_CCID_IN)) { if (Is_usb_setup_received ()) usb_process_request (); } }
//! usb_clear_feature. //! //! This function manages the SET FEATURE request. //! //! @warning Code:xx bytes (function code length) //! void usb_clear_feature(void) { U8 wValue; U8 wIndex; U8 dummy; if (bmRequestType == ZERO_TYPE) { return; } else if (bmRequestType == INTERFACE_TYPE) { return; } else if (bmRequestType == ENDPOINT_TYPE) { wValue = Usb_read_byte(); dummy = Usb_read_byte(); //!< dummy read if (wValue == FEATURE_ENDPOINT_HALT) { wIndex = (Usb_read_byte() & MSK_EP_DIR); Usb_select_endpoint(wIndex); if(Is_usb_endpoint_enabled()) { if(wIndex != EP_CONTROL) { Usb_disable_stall_handshake(); Usb_reset_endpoint(wIndex); Usb_reset_data_toggle(); } Usb_select_endpoint(EP_CONTROL); endpoint_status[wIndex] = 0x00; Usb_ack_receive_setup(); Usb_send_control_in(); } else { return; } } else { return; } } }
//! This function manages the CLEAR FEATURE request. //! void usb_clear_feature(void) { U8 wValue; U8 wIndex; switch (bmRequestType) { #if (USB_REMOTE_WAKEUP_FEATURE == true) case USB_SETUP_SET_STAND_DEVICE: wValue = Usb_read_endpoint_data(EP_CONTROL, 8); if (wValue != FEATURE_DEVICE_REMOTE_WAKEUP) break; // Invalid request device_status &= ~USB_DEV_STATUS_REMOTEWAKEUP; remote_wakeup_feature = false; Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); return; #endif case USB_SETUP_SET_STAND_INTERFACE: break; case USB_SETUP_SET_STAND_ENDPOINT: wValue = Usb_read_endpoint_data(EP_CONTROL, 8); if (wValue != FEATURE_ENDPOINT_HALT) break; Usb_read_endpoint_data(EP_CONTROL, 8); //!< dummy read (MSB of wValue) wIndex = Usb_read_endpoint_data(EP_CONTROL, 8); wIndex = Get_desc_ep_nbr(wIndex); if (!Is_usb_endpoint_enabled(wIndex)) break; if (wIndex != EP_CONTROL) { Usb_disable_stall_handshake(wIndex); Usb_reset_endpoint(wIndex); Usb_reset_data_toggle(wIndex); } Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); return; default: break; } Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); }
//! This function manages the CLEAR FEATURE request. //! void usb_clear_feature(void) { U8 wValue; U8 wIndex; if (bmRequestType == DEVICE_TYPE || bmRequestType == INTERFACE_TYPE) { //!< keep that order (set StallRq/clear RxSetup) or a //!< OUT request following the SETUP may be acknowledged Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); } else if (bmRequestType == ENDPOINT_TYPE) { wValue = Usb_read_endpoint_data(EP_CONTROL, 8); if (wValue == FEATURE_ENDPOINT_HALT) { Usb_read_endpoint_data(EP_CONTROL, 8); //!< dummy read (MSB of wValue) wIndex = Usb_read_endpoint_data(EP_CONTROL, 8); wIndex = Get_desc_ep_nbr(wIndex); if (Is_usb_endpoint_enabled(wIndex)) { if (wIndex != EP_CONTROL) { Usb_disable_stall_handshake(wIndex); Usb_reset_endpoint(wIndex); Usb_reset_data_toggle(wIndex); } endpoint_status[wIndex] = 0; // Halt feature flag Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); } else { Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); } } else { Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); } } }
void at45dbx_write_multiple_sector_callback(void *psector) { U16 data_to_transfer = AT45DBX_SECTOR_SIZE; // Transfer sector to write from the USB interface. while (data_to_transfer) { while (!Is_usb_out_received(g_scsi_ep_ms_out)) { if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_out)) return; // USB Reset } Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_out); data_to_transfer = usb_read_ep_rxpacket(g_scsi_ep_ms_out, psector, data_to_transfer, &psector); Usb_ack_out_received_free(g_scsi_ep_ms_out); } }
void at45dbx_read_multiple_sector_callback(const void *psector) { U16 data_to_transfer = AT45DBX_SECTOR_SIZE; // Transfer read sector to the USB interface. while (data_to_transfer) { while (!Is_usb_in_ready(g_scsi_ep_ms_in)) { if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) return; // USB Reset } Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_in); data_to_transfer = usb_write_ep_txpacket(g_scsi_ep_ms_in, psector, data_to_transfer, &psector); Usb_ack_in_ready_send(g_scsi_ep_ms_in); } }
//! usb_init_device. //! //! This function initializes the USB device controller and //! configures the Default Control Endpoint. //! //! @returns Zero is returned if the device could not be initialized. A non-zero, //! positive number is returned if the initialization was successful. uint8_t usb_init_device (void) { Usb_select_device(); if(Is_usb_id_device()) { Usb_select_endpoint(EP_CONTROL); if(!Is_usb_endpoint_enabled()) { return usb_configure_endpoint(EP_CONTROL, \ TYPE_CONTROL, \ DIRECTION_OUT, \ SIZE_64, \ ONE_BANK, \ NYET_DISABLED); } } return false; }
Bool sbc_inquiry (void) { U8 allocation_length; DelayMs (2); // CMDT or EPVD bit is not 0 or PAGE or OPERATION CODE fields != 0x00. if ((g_scsi_command[1] & 0x03) || g_scsi_command[2]) { sbc_lun_status_is_cdb_field (); return FALSE; } // Send standard INQUIRY data (bytes 0 to (allocation_length - 1)). allocation_length = min (g_scsi_command[4], sizeof (sbc_st_std_inquiry_data)); if (allocation_length != 0) { while (!Is_usb_in_ready (g_scsi_ep_ms_in)) { if (!Is_usb_endpoint_enabled (g_scsi_ep_ms_in)) return FALSE; // USB Reset } Usb_reset_endpoint_fifo_access (g_scsi_ep_ms_in); usb_write_ep_txpacket (g_scsi_ep_ms_in, &sbc_std_inquiry_data, allocation_length, NULL); Sbc_valid_write_usb (allocation_length); // MSC Compliance - Wait end of all transmitions on USB line, because a stall may be send after data while (0 != Usb_nb_busy_bank (EP_MS_IN)); } sbc_lun_status_is_good (); if (allocation_length > g_scsi_command[4]) // Not enough space { return (FALSE); } return (TRUE); }
uint8_t cdc_ecm_process(void) { static uint8_t doInit = 1; Usb_select_endpoint(RX_EP); if(!Is_usb_endpoint_enabled()) { return 0; } if (doInit) { #ifdef USB_ETH_HOOK_INIT USB_ETH_HOOK_INIT(); #endif cdc_ecm_notify_network_connection(1); cdc_ecm_notify_connection_speed_change(250000,250000); doInit = 0; if(usb_ecm_packet_filter & PACKET_TYPE_PROMISCUOUS) { #if RF230BB rf230_set_promiscuous_mode(true); #else radio_set_trx_state(RX_ON); #endif } // Select again, just to make sure. Usb_select_endpoint(RX_EP); } if(!usb_eth_is_active) { // If we aren't active, just eat the packets. if(Is_usb_read_enabled()) { Usb_ack_receive_out(); } return 0; } //Connected! Led0_on(); if(Is_usb_read_enabled()) { uint16_t bytecounter; uint16_t bytes_received = 0; U8 * buffer = uip_buf; if(!usb_eth_ready_for_next_packet()) { // Since we aren't ready for a packet yet, // just return. goto bail; } #ifdef USB_ETH_HOOK_RX_START USB_ETH_HOOK_RX_START(); #endif while((bytecounter=Usb_byte_counter_8())==CDC_ECM_DATA_ENDPOINT_SIZE) { while((bytes_received<USB_ETH_MTU) && (bytecounter--)) { *buffer++ = Usb_read_byte(); bytes_received++; } bytes_received+=bytecounter+1; //ACK previous data Usb_ack_receive_out(); //Wait for new data if(usb_endpoint_wait_for_read_enabled()!=0) { USB_ETH_HOOK_RX_ERROR("Timeout: read enabled"); goto bail; } } bytecounter = Usb_byte_counter_8(); while((bytes_received<USB_ETH_MTU) && (bytecounter--)) { *buffer++ = Usb_read_byte(); bytes_received++; } bytes_received+=bytecounter+1; //Ack final data packet Usb_ack_receive_out(); //PRINTF_P(PSTR("cdc_ecm: Got packet %d bytes long\n"),bytes_received); #ifdef USB_ETH_HOOK_RX_END USB_ETH_HOOK_RX_END(); #endif //Send data over RF or to local stack if(bytes_received<=USB_ETH_MTU) { USB_ETH_HOOK_HANDLE_INBOUND_PACKET(uip_buf,bytes_received); } else { USB_ETH_HOOK_RX_ERROR("Oversized packet"); } } bail: return 1; }
//! This function manages the SET FEATURE request. The USB test modes are //! supported by this function. //! void usb_set_feature(void) { U16 wValue = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); U16 wIndex = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); U16 wLength = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); if (wLength) goto unsupported_request; if (bmRequestType==USB_SETUP_SET_STAND_DEVICE) { #if (USB_REMOTE_WAKEUP_FEATURE == true) if (FEATURE_DEVICE_REMOTE_WAKEUP == wValue) { device_status |= USB_DEV_STATUS_REMOTEWAKEUP; remote_wakeup_feature = true; Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); return; } #endif goto unsupported_request; } switch (wValue) { case FEATURE_ENDPOINT_HALT: wIndex = Get_desc_ep_nbr(wIndex); // clear direction flag if (bmRequestType != ENDPOINT_TYPE || wIndex == EP_CONTROL || !Is_usb_endpoint_enabled(wIndex)) goto unsupported_request; Usb_enable_stall_handshake(wIndex); Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); break; #if (USB_HIGH_SPEED_SUPPORT==true) case FEATURE_TEST_MODE: if (bmRequestType != DEVICE_TYPE || wIndex & 0x00FF) goto unsupported_request; switch (wIndex >> 8) { case TEST_J: Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2); Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTJ_MASK); break; case TEST_K: Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2); Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTK_MASK); break; case TEST_SE0_NAK: Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2); break; case TEST_PACKET: { static const U8 test_packet[] = { // 00000000 * 9 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 01010101 * 8 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // 01110111 * 8 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, // 0, {111111S * 15}, 111111 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // S, 111111S, {0111111S * 7} 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, // 00111111, {S0111111 * 9}, S0 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E }; Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2); Usb_disable_endpoint(EP_CONTROL); Usb_unallocate_memory(EP_CONTROL); (void)Usb_configure_endpoint(EP_CONTROL, TYPE_BULK, DIRECTION_IN, 64, SINGLE_BANK); Usb_reset_endpoint(EP_CONTROL); Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTPCKT_MASK); usb_write_ep_txpacket(EP_CONTROL, &test_packet, sizeof(test_packet), NULL); Usb_send_in(EP_CONTROL); } break; case TEST_FORCE_ENABLE: // Only for downstream facing hub ports default: goto unsupported_request; } break; #endif case FEATURE_DEVICE_REMOTE_WAKEUP: default: goto unsupported_request; } return; unsupported_request: Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); }
static void usb_mass_storage_csw(void) { volatile U32 timeoutTickCount = g_lifetimeHalfSecondTickCount + 6; while (Is_usb_endpoint_stall_requested(EP_MS_IN)) { if (!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) { return; } // USB Reset if ((volatile U32)timeoutTickCount == (volatile U32)g_lifetimeHalfSecondTickCount) { return; } if (Is_usb_setup_received()) { usb_process_request(); timeoutTickCount = (volatile U32)g_lifetimeHalfSecondTickCount + 6; } } timeoutTickCount = (volatile U32)g_lifetimeHalfSecondTickCount + 6; while (Is_usb_endpoint_stall_requested(EP_MS_OUT)) { if (!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) { return; } // USB Reset if ((volatile U32)timeoutTickCount == (volatile U32)g_lifetimeHalfSecondTickCount) { return; } if (Is_usb_setup_received()) { usb_process_request(); timeoutTickCount = (volatile U32)g_lifetimeHalfSecondTickCount + 6; } } // MSC Compliance - Free BAD out receive during SCSI command while( Is_usb_out_received(EP_MS_OUT) ) { Usb_ack_out_received_free(EP_MS_OUT); } timeoutTickCount = (volatile U32)g_lifetimeHalfSecondTickCount + 6; while (!Is_usb_in_ready(EP_MS_IN)) { if (!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) { return; } // USB Reset if ((volatile U32)timeoutTickCount == (volatile U32)g_lifetimeHalfSecondTickCount) { return; } } Usb_reset_endpoint_fifo_access(EP_MS_IN); //! Write CSW Signature Usb_write_endpoint_data(EP_MS_IN, 32, *(uint32_t *)&"USBS"); //! Write stored CBW Tag Usb_write_endpoint_data(EP_MS_IN, 32, dCBWTag); //! Write data residual value Usb_write_endpoint_data(EP_MS_IN, 32, usb_format_mcu_to_usb_data(32, g_scsi_data_remaining)); //! Write command status Usb_write_endpoint_data(EP_MS_IN, 8, g_scsi_status); Usb_ack_in_ready_send(EP_MS_IN); // MSC Compliance - Wait end of all transmissions on USB line while( 0 != Usb_nb_busy_bank(EP_MS_IN) ) { if (Is_usb_setup_received()) usb_process_request(); } }