/* determine what buffer has data to send and call DMA setup function*/ void USB2UART_DMATransmit(kal_uint8 ep_num, kal_bool b_force_isr_buffer) { kal_uint32 addr; kal_uint32 length=0; // kal_uint32 savedMask; // savedMask = SaveAndSetIRQMask(); if(b_force_isr_buffer == KAL_TRUE) { length = USB2UART_Check_Transmit_Data(&addr, KAL_FALSE); } else { length = USB2UART_Check_Transmit_Data(&addr, g_UsbACM.threshold_enable); } // RestoreIRQMask(savedMask); if (length) { USB_Dbg_Trace(USB_ACM_DMA_SETUP, drv_get_current_time(), length, USB2Uart_MemType); /* dma running state is cleared by USB2UART_Tx_DMA_Callback */ // USB_DMA_Setup(ep_num, USB_TX_EP_TYPE, addr, length, USB2UART_Tx_DMA_Callback, KAL_TRUE); USB_DMA_Setup(ep_num, USB_TX_EP_TYPE, USB_ENDPT_BULK, addr, length, USB2UART_Tx_DMA_Callback, KAL_FALSE, KAL_TRUE, USB_DMA1_TYPE); } else { g_UsbACM.setup_dma = KAL_FALSE; } }
/* USB task run */ static void USB_Host_Ms_Error_Handler(kal_uint8 ms_index) { OTG_DRV_CTRL_GET_PLUG_TYPE_T dcl_data; OTG_PLUG_TYPE plug_type; //DclSGPT_Control((DCL_HANDLE)(g_UsbHostMs[ms_index].gpt_handle), SGPT_CMD_STOP, 0); USB_GPTI_StopItem(g_UsbHostMs[ms_index].gpt_handle); //DclSGPT_Control((DCL_HANDLE)(g_UsbHostMs[ms_index].sleep_timer_handle), SGPT_CMD_STOP, 0); USB_GPTI_StopItem(g_UsbHostMs[ms_index].sleep_timer_handle); DclOTG_DRV_Control(g_OTG_Dcl_Handle, OTG_DRV_CMD_GET_PLUG_TYPE, (DCL_CTRL_DATA_T *)&dcl_data); plug_type = (OTG_PLUG_TYPE)dcl_data.type; USB_Dbg_Trace(USB_HOST_MS_ERROR_HLDR, (kal_uint32)plug_type, (kal_uint32)g_UsbHostMs[ms_index].dev_attatch); if(g_UsbHostMs[ms_index].dev_attatch == KAL_TRUE) { /* If cable is plugged out then error, do not turn off Vbus */ /* Stop OTG action */ // if(OTG_Get_Plug_Type() == OTG_PLUG_A) if(plug_type == OTG_PLUG_A) { DclOTG_DRV_Control(g_OTG_Dcl_Handle, OTG_DRV_CMD_A_STOP_HOST, NULL); // OTG_A_Stop_Host(); } else { DclOTG_DRV_Control(g_OTG_Dcl_Handle, OTG_DRV_CMD_B_STOP_HOST, NULL); // OTG_B_Stop_Host(); } OTG_Display_Message(OTG_DISPLAY_MSG_UN_SUPPORT); drv_trace1(TRACE_FUNC, (kal_uint32)USB_HOST_MS_CHECK_MEDIA_STATE, g_UsbHostMs[ms_index].media_state_change); USB_Dbg_Trace(USB_HOST_MS_REPORT_MEDIA_STATE, g_UsbHostMs[ms_index].media_state_change, (kal_uint32)g_UsbHostMs[ms_index].b_sending_change_ilm); if((g_UsbHostMs[ms_index].media_state_change != 0) && (g_UsbHostMs[ms_index].b_sending_change_ilm == KAL_FALSE)) { USB_Host_Ms_Check_Media_State(ms_index); } } }
/* This query function should be called when first detect the lun plug in */ static void USB_Host_MS_Query_Media(kal_uint8 lun) { USB_HOST_MS_RESULT result; kal_uint8 ms_index = USB_MS_IP_Query(lun); USB_Dbg_Trace(USB_HOST_MS_QUERY_MEDIA, lun, 0); g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_READY; /* Send INQUIRY request to device */ /* Inquiry cmd's CSW is fail but request we get "NOT ready", then we still see result as OK */ result = USB_Host_Ms_Inquiry(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ /* Or request sense but fail */ if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; return; } /* Send READ FORMAT CAPACITY request to device */ /* some device always return STALL in this command result = USB_Host_Ms_Read_Format_Capacity(lun); if(result != USB_HOST_MS_RESULT_OK) { // result not OK means CBW, DATA, CSW transfer is error after its internal error handling if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; return; } */ /* Send READ CAPACITY request to device */ result = USB_Host_Ms_Read_Capacity(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; return; } }
/* Note that this is called periodically when ms is active */ void USB_Host_Ms_State_Main(kal_uint8 ms_index) { kal_bool result; // SGPT_CTRL_START_T start; if(g_UsbHostMs[ms_index].dev_attatch == KAL_TRUE) { result = USB_Host_Ms_Check_All_Media(ms_index); } else { result = KAL_FALSE; USB_Dbg_Trace(USB_HOST_MS_STATE_MAIN_FALSE, 0, 0); } drv_trace1(TRACE_FUNC, (kal_uint32)USB_HOST_MS_CHECK_MEDIA_STATE, g_UsbHostMs[ms_index].media_state_change); USB_Dbg_Trace(USB_HOST_MS_REPORT_MEDIA_STATE, g_UsbHostMs[ms_index].media_state_change, (kal_uint32)g_UsbHostMs[ms_index].b_sending_change_ilm); if(result == KAL_TRUE) { if((g_UsbHostMs[ms_index].media_state_change != 0)&&(g_UsbHostMs[ms_index].b_sending_change_ilm == KAL_FALSE)) { /* Send message to FMT task about card state change */ USB_Host_Ms_Check_Media_State(ms_index); } /* start timer to start query device state */ USB_GPTI_StartItem(g_UsbHostMs[ms_index].gpt_handle, USB_HOST_MS_QUERY_PERIOD,USB_Host_Ms_State_Timeout, &g_UsbHostMs[ms_index]); // start.u2Tick =USB_HOST_MS_QUERY_PERIOD; // start.pfCallback = USB_Host_Ms_State_Timeout; // start.vPara = &g_UsbHostMs[ms_index]; // DclSGPT_Control((DCL_HANDLE)(g_UsbHostMs[ms_index].gpt_handle), SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start); } else { drv_trace0(TRACE_FUNC, (kal_uint32)USB_HOST_MS_STATE_MAIN_FAIL); } }
/*put bytes to tx buffer, return value is the actually put out bytes*/ static kal_uint16 USB2UART_PutBytes(UART_PORT port, kal_uint8 *buffaddr, kal_uint16 length, module_type ownerid) { kal_uint16 real_count; // kal_uint16 index; kal_uint32 savedMask; kal_uint8 ep_num = 0; kal_bool setup_dma = KAL_FALSE; kal_int32 remain; BUFFER_INFO *tx_info = &(USB2UARTPort.Tx_Buffer); if(ownerid != USB2UARTPort.ownerid) { #ifdef __PRODUCTION_RELEASE__ return 0; #else /* __PRODUCTION_RELEASE__ */ EXT_ASSERT( 0, (kal_uint32) ownerid, USB2UARTPort.ownerid, 0); #endif } /* return directly if not match condition */ if ( (gUsbDevice.device_type != USB_CDC_ACM) || (USB2UARTPort.initialized == KAL_FALSE) || (gUsbDevice.nDevState!=DEVSTATE_CONFIG)) { if(((gUsbDevice.device_type == USB_CDC_ACM)||(gUsbDevice.usb_comport_boot == KAL_TRUE)) && (USB2UARTPort.initialized == KAL_TRUE)&&(gUsbDevice.nDevState != DEVSTATE_CONFIG)) { g_UsbACM.config_send_Txilm = KAL_TRUE; /* for PC set config later then can issue the first message */ } return 0; } /* The same issue as USB2UART_GetBytes() The area to determine send_Txilm must also contain in critical section. Otherwise if DMA callback activated before send_Txilm setting as true, this message will be lost */ savedMask = SaveAndSetIRQMask(); Buf_GetRoomLeft(tx_info, real_count); /* determine real sent data count */ if (real_count > length) { real_count = length; } else { g_UsbACM.send_Txilm = KAL_TRUE; /*After this time put bytes, buffer will be full */ g_UsbACM.config_send_Txilm = KAL_TRUE; /* if be reseted, then it can issue the message waited for*/ } RestoreIRQMask(savedMask); if(g_UsbACM.send_Txilm == KAL_TRUE) { if(ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_PUT_BYTES_BUF_FULL, ownerid); // kal_prompt_trace(MOD_USB, "RDY W %d", ownerid); } } if(real_count != 0) { remain = (BWrite(tx_info) + real_count) - BLength(tx_info); if(remain < 0) { /* dest, src, len */ kal_mem_cpy(BuffWrite(tx_info), buffaddr, real_count); BWrite(tx_info) += real_count; } else { kal_mem_cpy(BuffWrite(tx_info), buffaddr, real_count-remain); kal_mem_cpy(BStartAddr(tx_info), (kal_uint8 *)(buffaddr+real_count-remain), remain); BWrite(tx_info) = remain; } } /* push data from caller buffer to ring buffer */ /* for (index = 0; index < real_count; index++) { Buf_Push(&(USB2UARTPort.Tx_Buffer), *(buffaddr+index)); } */ savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section */ if(gUsbDevice.device_type == USB_CDC_ACM) { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) if(g_UsbACM.setup_dma == KAL_FALSE) { g_UsbACM.setup_dma = KAL_TRUE; setup_dma = KAL_TRUE; ep_num = g_UsbACM.txpipe->byEP; } } RestoreIRQMask(savedMask); if(setup_dma == KAL_TRUE) { USB_Dbg_Trace(USB_ACM_DMA_SETUP_1, drv_get_current_time(), ep_num, 0); USB2UART_DMATransmit(ep_num, KAL_FALSE); } #ifndef __PRODUCTION_RELEASE__ if(ownerid != USB2UARTPort.ownerid) { EXT_ASSERT( 0, (kal_uint32) ownerid, (kal_uint32)USB2UARTPort.ownerid, 0); } if(ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_PUT_BYTES, real_count); // kal_prompt_trace(MOD_USB, "Put %d", real_count); } #endif return real_count; }
static void USB2UART_CtrlDCD(UART_PORT port, IO_level SDCD, module_type ownerid) { kal_uint32 savedMask; kal_bool b_set_intr; kal_uint8 ep_num = 0; #ifdef USB_20_ENABLE kal_uint32 max_intr_pkt_size; #endif #ifndef __PRODUCTION_RELEASE__ USB_Dbg_Trace(USB_ACM_SEND_INTERRUPT, drv_get_current_time(), g_UsbACM.intr_state, 0); if(ownerid != USB2UARTPort.ownerid) { EXT_ASSERT( 0, (kal_uint32) ownerid, USB2UARTPort.ownerid, 0); } #endif savedMask = SaveAndSetIRQMask(); if((g_UsbACM.intr_state == ACM_INTR_IDLE)&&(gUsbDevice.is_configured_now == KAL_TRUE)) { b_set_intr = KAL_TRUE; g_UsbACM.is_intr_pending_pkt = KAL_FALSE; ep_num = g_UsbACM.intrpipe->byEP; } else { b_set_intr = KAL_FALSE; g_UsbACM.is_intr_pending_pkt = KAL_TRUE; } if(SDCD == io_high) g_UsbACM.intr_pkt.Data = SERIAL_STATE_BRXCARRIER; else if (SDCD == io_low) g_UsbACM.intr_pkt.Data = 0x00; else ASSERT(0); RestoreIRQMask(savedMask); if(b_set_intr == KAL_TRUE) { #ifdef USB_20_ENABLE if(USB_Is_High_Speed() == KAL_TRUE) max_intr_pkt_size = USB_EP_INTR_MAXP_HS; else max_intr_pkt_size = USB_EP_INTR_MAXP_FS; if(max_intr_pkt_size > sizeof(UsbAcm_Intr_Pkt)) #else if(USB_EP_INTR_MAXP > sizeof(UsbAcm_Intr_Pkt)) #endif { g_UsbACM.intr_state = ACM_INTR_SEND_LAST_PKT; #ifndef __PRODUCTION_RELEASE__ /* send only one short packet */ USB_Dbg_Trace(USB_ACM_SEND_INTERRUPT2, drv_get_current_time(), g_UsbACM.intr_state, 0); drv_trace1(TRACE_FUNC, USBACM_INTR, g_UsbACM.intr_pkt.Data); // kal_prompt_trace(MOD_USB, "ACM INTR %d", g_UsbACM.intr_pkt.Data); #endif USB_EPFIFOWrite(ep_num, sizeof(UsbAcm_Intr_Pkt), (kal_uint8 *)&g_UsbACM.intr_pkt); USB_EP_Bulk_Tx_Ready(ep_num); } else { g_UsbACM.intr_state = ACM_INTR_SEND_ONE_PKT; #ifndef __PRODUCTION_RELEASE__ /* send one max packet */ USB_Dbg_Trace(USB_ACM_SEND_INTERRUPT1, drv_get_current_time(), g_UsbACM.intr_state, 0); drv_trace1(TRACE_FUNC, USBACM_INTR, g_UsbACM.intr_pkt.Data); // kal_prompt_trace(MOD_USB, "ACM INTR %d", g_UsbACM.intr_pkt.Data); #endif #ifdef USB_20_ENABLE USB_EPFIFOWrite(ep_num, max_intr_pkt_size, (kal_uint8 *)&g_UsbACM.intr_pkt); #else USB_EPFIFOWrite(ep_num, USB_EP_INTR_MAXP, (kal_uint8 *)&g_UsbACM.intr_pkt); #endif USB_EP_Bulk_Tx_Ready(ep_num); } } }
/* put bytes to ISR tx buffer, handle the special character in this function(add escape character) return value is the actually put out bytes*/ static kal_uint16 USB2UART_SendISRData(UART_PORT port, kal_uint8 *buffaddr, kal_uint16 length, kal_uint8 mode, kal_uint8 escape_char, module_type ownerid) { kal_int16 real_count, index; kal_uint8 data; kal_uint32 savedMask; kal_uint8 ep_num = 0; kal_bool setup_dma = KAL_FALSE; BUFFER_INFO *tx_isr_info = &(USB2UARTPort.Tx_Buffer_ISR); if(ownerid != USB2UARTPort.ownerid) { #ifdef __PRODUCTION_RELEASE__ return 0; #else EXT_ASSERT( 0, (kal_uint32) ownerid, USB2UARTPort.ownerid, 0); #endif } if ( (gUsbDevice.device_type != USB_CDC_ACM) || (USB2UARTPort.initialized == KAL_FALSE) || (gUsbDevice.nDevState!=DEVSTATE_CONFIG)) return 0; if (mode == 0) { real_count = USB2UART_PutISRBytes(port, buffaddr, length, ownerid); } else { savedMask = SaveAndSetIRQMask(); Buf_GetRoomLeft(tx_isr_info, real_count); RestoreIRQMask(savedMask); /* determine real sent data count */ if (real_count > length) real_count = length; for (index = 0; index < real_count; index++) { kal_uint16 roomleft; savedMask = SaveAndSetIRQMask(); Buf_GetRoomLeft(tx_isr_info, roomleft); RestoreIRQMask(savedMask); data = *(buffaddr + index); /* if the character is special character, translate it. PC has the ability to distinguish it*/ if (data == USB2UARTPort.DCB.xonChar) { if ( roomleft >= 2 ) { Buf_Push(tx_isr_info, escape_char); Buf_Push(tx_isr_info, 0x01); } else { break; } } else if (data == USB2UARTPort.DCB.xoffChar) { if ( roomleft >= 2 ) { Buf_Push(tx_isr_info, escape_char); Buf_Push(tx_isr_info, 0x02); } else { break; } } else if (data == escape_char) { if ( roomleft >= 2 ) { Buf_Push(tx_isr_info, escape_char); Buf_Push(tx_isr_info, 0x03); } else { break; } } else { if (roomleft) { Buf_Push(tx_isr_info, data); } else { break; } } } real_count = index; savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section */ if(gUsbDevice.device_type == USB_CDC_ACM) { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) if(g_UsbACM.setup_dma == KAL_FALSE) { g_UsbACM.setup_dma = KAL_TRUE; setup_dma = KAL_TRUE; ep_num = g_UsbACM.txpipe->byEP; } } RestoreIRQMask(savedMask); if(setup_dma == KAL_TRUE) { USB_Dbg_Trace(USB_ACM_DMA_SETUP_3, drv_get_current_time(), ep_num, 0); USB2UART_DMATransmit(ep_num, KAL_FALSE); } } #ifndef __PRODUCTION_RELEASE__ if(ownerid != USB2UARTPort.ownerid) { EXT_ASSERT( 0, (kal_uint32) ownerid, (kal_uint32)USB2UARTPort.ownerid, 0); } #endif if(ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_SEND_ISR_DATA, real_count); // kal_prompt_trace(MOD_USB, "SendISR %d", real_count); } return real_count; }
/* put bytes to ISR tx buffer, return value is the actually put out bytes */ static kal_uint16 USB2UART_PutISRBytes(UART_PORT port, kal_uint8 *buffaddr, kal_uint16 length, module_type ownerid) { kal_uint16 real_count; // kal_uint16 index; kal_uint32 savedMask; kal_uint8 ep_num = 0; kal_bool setup_dma = KAL_FALSE; kal_int32 remain; BUFFER_INFO *tx_isr_info = &(USB2UARTPort.Tx_Buffer_ISR); if(ownerid != USB2UARTPort.ownerid) { #ifdef __PRODUCTION_RELEASE__ return 0; #else /* __PRODUCTION_RELEASE__ */ EXT_ASSERT( 0, (kal_uint32) ownerid, USB2UARTPort.ownerid, 0); #endif } if ( (gUsbDevice.device_type != USB_CDC_ACM) || (USB2UARTPort.initialized == KAL_FALSE) || (gUsbDevice.nDevState!=DEVSTATE_CONFIG)) return 0; savedMask = SaveAndSetIRQMask(); Buf_GetRoomLeft(tx_isr_info, real_count); RestoreIRQMask(savedMask); /* determine real sent data count */ if (real_count > length) real_count = length; if(real_count != 0) { remain = (BWrite(tx_isr_info) + real_count) - BLength(tx_isr_info); if(remain < 0) { /* dest, src, len */ kal_mem_cpy(BuffWrite(tx_isr_info), buffaddr, real_count); BWrite(tx_isr_info) += real_count; } else { kal_mem_cpy(BuffWrite(tx_isr_info), buffaddr, real_count-remain); kal_mem_cpy(BStartAddr(tx_isr_info), (kal_uint8 *)(buffaddr+real_count-remain), remain); BWrite(tx_isr_info) = remain; } } /* push data from caller buffer to ring buffer */ /* for (index = 0; index < real_count; index++) { Buf_Push(tx_isr_info, *(buffaddr+index)); } */ savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section */ if(gUsbDevice.device_type == USB_CDC_ACM) { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) if(g_UsbACM.setup_dma == KAL_FALSE) { g_UsbACM.setup_dma = KAL_TRUE; setup_dma = KAL_TRUE; ep_num = g_UsbACM.txpipe->byEP; } } RestoreIRQMask(savedMask); if(setup_dma == KAL_TRUE) { USB_Dbg_Trace(USB_ACM_DMA_SETUP_2, drv_get_current_time(), ep_num, 0); USB2UART_DMATransmit(ep_num, KAL_FALSE); } #ifndef __PRODUCTION_RELEASE__ if(ownerid != USB2UARTPort.ownerid) { EXT_ASSERT( 0, (kal_uint32) ownerid, (kal_uint32)USB2UARTPort.ownerid, 0); } #endif if(ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_PUT_ISR_BYTES, real_count); // kal_prompt_trace(MOD_USB, "PutISR %d", real_count); } return real_count; }
static void USB_Stdcmd(Usb_Ep0_Status *pep0state, Usb_Command *pcmd) { kal_bool bError = KAL_FALSE; switch (pcmd->bRequest) { case USB_SET_ADDRESS: USB_Dbg_Trace(USB_EP0_SET_ADDRESS, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_SetAddress(pep0state, pcmd); break; case USB_GET_DESCRIPTOR: USB_Dbg_Trace(USB_EP0_GET_DESCRIPTOR, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_GetDescriptor(pep0state, pcmd); break; case USB_SET_CONFIGURATION: USB_Dbg_Trace(USB_EP0_SET_CONFIGURATION, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_SetConfiguration(pep0state, pcmd); break; case USB_SET_INTERFACE: USB_Dbg_Trace(USB_EP0_SET_INTERFACE, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_SetInterface(pep0state, pcmd); break; case USB_GET_CONFIGURATION: USB_Dbg_Trace(USB_EP0_GET_CONFIGURATION, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_GetConfiguration(pep0state, pcmd); break; case USB_GET_INTERFACE: USB_Dbg_Trace(USB_EP0_GET_INTERFACE, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_GetInterface(pep0state, pcmd); break; case USB_SET_FEATURE: USB_Dbg_Trace(USB_EP0_SET_FEATURE, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_SetFeature(pcmd, KAL_TRUE); break; case USB_CLEAR_FEATURE: USB_Dbg_Trace(USB_EP0_CLEAR_FEATURE, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_SetFeature(pcmd, KAL_FALSE); break; case USB_GET_STATUS: USB_Dbg_Trace(USB_EP0_GET_STATUS, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = USB_Cmd_GetStatus(pep0state, pcmd); break; /* Stall the command if an unrecognized request is received */ case USB_SYNCH_FRAME: /*Only support for Isoc traffic*/ case USB_SET_DESCRIPTOR: default: USB_Dbg_Trace(USB_EP0_CMD_ERROR, drv_get_current_time(), (kal_uint32)pcmd->wValue, (kal_uint32)pcmd->wIndex); bError = KAL_TRUE; // ASSERT(0); break; } if (gUsbDevice.ep0_state == USB_EP0_IDLE) /* no data to transmit */ { gUsbDevice.ep0_state = USB_EP0_RX_STATUS; USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, bError, KAL_TRUE); /* if((gUsbDevice.ep0_class_cmd_handler.b_enable == KAL_TRUE) && (gUsbDevice.ep0_class_cmd_handler.cmd == pcmd->bRequest) ) { gUsbDevice.ep0_class_cmd_handler.ep0_cmd_hdlr(pcmd); } */ } else { USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, bError, KAL_FALSE); } }
/* DMA callback function for TX sent out data */ static void USB2UART_Tx_DMA_Callback(void) { kal_uint32 savedMask; kal_uint8 ep_num = 0; kal_bool setup_dma = KAL_FALSE; kal_bool b_force_isr_buffer = KAL_FALSE; if(USB2UARTPort.ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_DMA_CALLBACK, USB2Uart_WriteLength); // kal_prompt_trace(MOD_USB, "DMA %d", USB2Uart_WriteLength); } /* tx complete callback*/ USB2UARTPort.tx_cb(uart_port_usb); #if 0 /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ #endif /*update read pointer for previously sent out buffer */ savedMask = SaveAndSetIRQMask(); USB2UART_Update_Transmit_Data(); RestoreIRQMask(savedMask); /* USB2Uart_MemType and USB2Uart_WriteLength are updated, so clear dma running state here*/ g_UsbACM.setup_dma = KAL_FALSE; // USB_DMA_Set_Run_Status(g_UsbACM.txpipe->byEP, KAL_FALSE); if(USB2UARTPort.Tx_Buffer_ISR.Read == USB2UARTPort.Tx_Buffer_ISR.Write) { /* no more data to send */ if(USB2UARTPort.Tx_Buffer.Read == USB2UARTPort.Tx_Buffer.Write) return; } /* must send ISR buffer again */ else if(USB2Uart_MemType == USBTRX_MEM_ISR) { b_force_isr_buffer = KAL_TRUE; } /* send data again in TX buffer or TXISR buffer */ savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section */ if(gUsbDevice.device_type == USB_CDC_ACM) { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) if(g_UsbACM.setup_dma == KAL_FALSE) { g_UsbACM.setup_dma = KAL_TRUE; setup_dma = KAL_TRUE; ep_num = g_UsbACM.txpipe->byEP; } } RestoreIRQMask(savedMask); if(setup_dma == KAL_TRUE) { USB_Dbg_Trace(USB_ACM_DMA_CALLBACK, drv_get_current_time(), ep_num, 0); USB2UART_DMATransmit(ep_num, b_force_isr_buffer); } // savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section*/ // if(gUsbDevice.device_type == USB_CDC_ACM) // { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) // { // USB2UART_DMATransmit(g_UsbACM.txpipe->byEP); // } // } // RestoreIRQMask(savedMask); }
/* Note that this function should be called when first detect ms device*/ void USB_Host_Ms_State_Start(kal_uint8 ms_index) { kal_uint32 index; kal_bool result; // SGPT_CTRL_START_T start; /* Initailize the information */ if(g_UsbHostMs[ms_index].event_id == 0) g_UsbHostMs[ms_index].event_id = kal_create_event_group("USB_MS_EVEVT"); if(g_UsbHostMs[ms_index].mutex_id == 0) g_UsbHostMs[ms_index].mutex_id = kal_create_mutex("USB_MS_MUTEX"); USB_GPTI_GetHandle(&(g_UsbHostMs[ms_index].gpt_handle));//DclSGPT_Open(DCL_GPT_CB, 0);//GPTI_GetHandle(&g_UsbHostMs.gpt_handle); // if (g_UsbHostMs[ms_index].gpt_handle == 0) // g_UsbHostMs[ms_index].gpt_handle = USB_GPTI_GetHandle();//DclSGPT_Open(DCL_GPT_CB, 0);//GPTI_GetHandle(&g_UsbHostMs.gpt_handle); USB_GPTI_GetHandle(&(g_UsbHostMs[ms_index].sleep_timer_handle));//DclSGPT_Open(DCL_GPT_CB, 0);//GPTI_GetHandle(&g_UsbHostMs.gpt_handle); // if (g_UsbHostMs[ms_index].sleep_timer_handle== 0) // g_UsbHostMs[ms_index].sleep_timer_handle = USB_GPTI_GetHandle();//DclSGPT_Open(DCL_GPT_CB, 0);//GPTI_GetHandle(&g_UsbHostMs.gpt_handle); /* Get LUN, it contains the error handling */ result = USB_Host_Ms_Comp_Get_LUN(ms_index); if(result == KAL_TRUE) { /* The got LUN is total lun - 1 */ g_UsbHostMs[ms_index].total_lun++; /* If LUN number is larger than we can support, onlt the first N can be detected */ if(g_UsbHostMs[ms_index].total_lun > USB_HOST_MS_SUPPORT_LUN) g_UsbHostMs[ms_index].total_lun = USB_HOST_MS_SUPPORT_LUN; } else { /* when device not implement this command, it is only one LUN */ g_UsbHostMs[ms_index].dev_error_count = 0; g_UsbHostMs[ms_index].total_lun = 1; } /* Reset all the LUN state to absent state */ for(index = 0; index < g_UsbHostMs[ms_index].total_lun; index++) { g_UsbHostMs[ms_index].media_info[index].state = USB_HOST_MS_MEDIA_STATE_ABSENT; } /* Get LUN is success, continue to query each LUN info */ result = USB_Host_Ms_Query_All_Media(ms_index); /* If result is fail, ms has been detached */ if(result == KAL_TRUE) { /* Query each LUN is success, continue to check whether each LUN is in card slot or not */ result = USB_Host_Ms_Check_All_Media(ms_index); /* If result is fail, ms has been detached */ } drv_trace1(TRACE_FUNC, (kal_uint32)USB_HOST_MS_CHECK_MEDIA_STATE, g_UsbHostMs[ms_index].media_state_change); USB_Dbg_Trace(USB_HOST_MS_REPORT_MEDIA_STATE, g_UsbHostMs[ms_index].media_state_change, (kal_uint32)g_UsbHostMs[ms_index].b_sending_change_ilm); if(result == KAL_TRUE) { /* To prevent USB disconn intr coming during this moment */ IRQMask(USB_IRQ_MAP[g_UsbHostMs[ms_index].common_info.usb_ip_port]); if((g_UsbHostMs[ms_index].media_state_change != 0)&&(g_UsbHostMs[ms_index].b_sending_change_ilm == KAL_FALSE)) { USB_Host_Ms_Check_Media_State(ms_index); } /* If device is plugged out, do not send this message */ if(g_UsbHostMs[ms_index].dev_attatch == KAL_TRUE) { /* Start timer to query device state */ USB_GPTI_StartItem(g_UsbHostMs[ms_index].gpt_handle, USB_HOST_MS_QUERY_PERIOD,USB_Host_Ms_State_Timeout, &g_UsbHostMs); // start.u2Tick =USB_HOST_MS_QUERY_PERIOD; // start.pfCallback = USB_Host_Ms_State_Timeout; // start.vPara = &g_UsbHostMs[ms_index]; // DclSGPT_Control((DCL_HANDLE)(g_UsbHostMs[ms_index].gpt_handle), SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start); } if(USBD_Get_UnMask_Irq(g_UsbHostMs[ms_index].common_info) == KAL_TRUE) IRQUnmask(USB_IRQ_MAP[g_UsbHostMs[ms_index].common_info.usb_ip_port]); } else { drv_trace0(TRACE_FUNC, (kal_uint32)USB_HOST_MS_STATE_START_FAIL); } }
/* This check function should be called periodically when slot is still attched */ static void USB_Host_MS_Check_Media(kal_uint8 lun) { USB_HOST_MS_RESULT result; kal_bool b_state_change = KAL_FALSE; kal_uint8 ms_index = USB_MS_IP_Query(lun); USB_HOST_MS_MEDIA_STATE media_state = g_UsbHostMs[ms_index].media_info[lun].state; USB_Dbg_Trace(USB_HOST_MS_CHECK_MEDIA, lun, 0); g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_READY; /* Send TEST UNIT READY request to device */ result = USB_Host_Ms_Test_Unit_Ready(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; return; } /* state may change from READY->CHANGED at this step, and CHANGED->READY at next step */ if(media_state != g_UsbHostMs[ms_index].media_info[lun].state) b_state_change = KAL_TRUE; if(g_UsbHostMs[ms_index].media_info[lun].state == USB_HOST_MS_MEDIA_STATE_CHANGED) { /* If card is plugged in to card reader, the previous state would be state changed, so query state again */ /* If this request finds media state cahnge to READY, then capacity can be queried in the following step directly */ result = USB_Host_Ms_Test_Unit_Ready(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; return; } } if(media_state != g_UsbHostMs[ms_index].media_info[lun].state) b_state_change = KAL_TRUE; if((b_state_change == KAL_TRUE)&&(g_UsbHostMs[ms_index].media_info[lun].state == USB_HOST_MS_MEDIA_STATE_READY)) { /* state change from NOT_READY to READY*/ /* Send READ CAPACITY request to device */ result = USB_Host_Ms_Read_Capacity(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ if(result != USB_HOST_MS_RESULT_FORMAT_ERROR) { /* FORMAT_ERROR means that we receive a large size because card reader is not plugged in card yet */ if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; } return; } /* Send MODE SENSE6 request to device. Query whether the device is write protected or not */ result = USB_Host_Ms_Mode_Sense6(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; return; } if(g_UsbHostMs[ms_index].media_info[lun].state == USB_HOST_MS_MEDIA_STATE_ERROR) { /* Send READ CAPACITY request to device */ result = USB_Host_Ms_Read_Capacity(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ if(result != USB_HOST_MS_RESULT_FORMAT_ERROR) { if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; } return; } /* Try all mode again */ result = USB_Host_Ms_Mode_Sense6_All_Mode(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; return; } } if(g_UsbHostMs[ms_index].media_info[lun].state == USB_HOST_MS_MEDIA_STATE_ERROR) { /* Try mode sense 10 again */ result = USB_Host_Ms_Mode_Sense10_All_Mode(lun); if(result != USB_HOST_MS_RESULT_OK) { /* result not OK means CBW, DATA, CSW transfer is error after its internal error handling */ if(result == USB_HOST_MS_RESULT_TIMEOUT) g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_FATAL_ERROR; else g_UsbHostMs[ms_index].dev_state = USB_HOST_MS_DEV_STATE_ERROR; return; } } } }