#include "drv_comm.h"
#include "stack_common.h"
#include "stack_msgs.h"
#include "app_ltlcom.h" /* Task message communiction */
#include "syscomp_config.h"
#include "task_config.h"
#include "stacklib.h"
#include "reg_base.h"
#include "drvsignals.h"
#include "app_buff_alloc.h"
#include "drvpdn.h"
#include "intrCtrl.h"
#include "gpio_sw.h"
#include "usb_comm.h"
#include "usb_drv.h"
#include "usb.h"
#include "usb_resource.h"
#include "usbms_drv.h"
#include "usbacm_drv.h"
#include "usbvideo_drv.h"
#include "usb_custom.h"
#include "fs_type.h"
#include "fs_func.h"
#ifdef __OTG_ENABLE__
#include "otg_drv.h"
#endif
#ifdef __MULTI_BOOT__
#include "multiboot_config.h"
#include "fctycomp_config.h"
#endif /* __MULTI_BOOT__ */
/* Device structure, handle usb level data */
Usb_Device gUsbDevice;
#ifndef __PRODUCTION_RELEASE__
kal_uint32 g_usb_reset_times; /* for debug information */
#endif
/* static fuctions */
static void USB_Reset(void);
static void USB_Initialize(void);
static kal_bool USB_Cmd_SetAddress(Usb_Ep0_Status *pep0state, Usb_Command *pcmd);
static kal_bool USB_Cmd_GetDescriptor(Usb_Ep0_Status *pep0state, Usb_Command *pcmd);
static kal_bool USB_Cmd_SetConfiguration(Usb_Ep0_Status *pep0state, Usb_Command *pcmd);
static kal_bool USB_Cmd_GetConfiguration(Usb_Ep0_Status *pep0state, Usb_Command *pcmd);
static kal_bool USB_Cmd_SetFeature(Usb_Command *pcmd, kal_bool bset);
static kal_bool USB_Cmd_GetStatus(Usb_Ep0_Status *pep0state, Usb_Command *pcmd);
static void USB_Stdcmd(Usb_Ep0_Status *pep0state, Usb_Command *pcmd);
static void USB_Endpoint0_Idle (void);
static void USB_Endpoint0_Rx(void);
static void USB_Endpoint0_Tx(void);
static void USB_Endpoint0_Hdlr(void);
/************************************************************
gUsbDevice initialize and release functions
*************************************************************/
/* initialize the global variable gUsbDevice */
void USB_Init_Device_Status(void)
{
kal_uint8 index = 0;
kal_mem_set(&gUsbDevice.cfg_info, 0, sizeof(Usb_Config_Info));
for( index = 0; index < USB_MAX_INTERFACE; index++)
{
kal_mem_set(&gUsbDevice.if_info[index], 0, sizeof(Usb_Interface_Info));
}
for( index = 0; index < USB_MAX_EP_BULK_IN; index++)
{
kal_mem_set(&gUsbDevice.ep_bulkin_info[index], 0, sizeof(Usb_Ep_Info));
}
for( index = 0; index < USB_MAX_EP_BULK_OUT; index++)
{
kal_mem_set(&gUsbDevice.ep_bulkout_info[index], 0, sizeof(Usb_Ep_Info));
}
for( index = 0; index < USB_MAX_EP_INTR; index++)
{
kal_mem_set(&gUsbDevice.ep_intr_info[index], 0, sizeof(Usb_Ep_Info));
}
for( index = 0; index < USB_MAX_STRING; index++)
{
gUsbDevice.resource_string[index] = NULL;
}
gUsbDevice.conf = NULL;
gUsbDevice.device_type = USB_UNKOWN;
gUsbDevice.nDevState = DEVSTATE_DEFAULT;
gUsbDevice.remoteWk = KAL_FALSE;
gUsbDevice.self_powered = KAL_FALSE;
gUsbDevice.config_num = 0;
gUsbDevice.interface_num = 0;
gUsbDevice.ep0_rx_handler = NULL;
gUsbDevice.ep0_class_cmd_handler.b_enable = KAL_FALSE;
gUsbDevice.resource_ep_bulkin_number = 0;
gUsbDevice.resource_ep_bulkout_number = 0;
gUsbDevice.resource_ep_intr_number = 0;
gUsbDevice.resource_interface_number = 0;
gUsbDevice.resource_string_number = 0;
}
/* release the already get memory, and reset some parameter,
note that hisr should not be reset to NULL since it may already be created*/
void USB_Release_Device_Status(void)
{
kal_uint8 index = 0;
kal_mem_set(&gUsbDevice.cfg_info, 0, sizeof(Usb_Config_Info));
for( index = 0; index < USB_MAX_INTERFACE; index++)
{
kal_mem_set(&gUsbDevice.if_info[index], 0, sizeof(Usb_Interface_Info));
}
for( index = 0; index < USB_MAX_EP_BULK_IN; index++)
{
kal_mem_set(&gUsbDevice.ep_bulkin_info[index], 0, sizeof(Usb_Ep_Info));
}
for( index = 0; index < USB_MAX_EP_BULK_OUT; index++)
{
kal_mem_set(&gUsbDevice.ep_bulkout_info[index], 0, sizeof(Usb_Ep_Info));
}
for( index = 0; index < USB_MAX_EP_INTR; index++)
{
kal_mem_set(&gUsbDevice.ep_intr_info[index], 0, sizeof(Usb_Ep_Info));
}
for( index = 0; index < USB_MAX_STRING; index++)
{
gUsbDevice.resource_string[index] = NULL;
}
if(gUsbDevice.conf != NULL)
free_ctrl_buffer(gUsbDevice.conf);
gUsbDevice.conf = NULL;
gUsbDevice.nDevState = DEVSTATE_DEFAULT;
gUsbDevice.remoteWk = KAL_FALSE;
gUsbDevice.self_powered = KAL_FALSE;
gUsbDevice.config_num = 0;
gUsbDevice.interface_num = 0;
gUsbDevice.device_type = USB_UNKOWN;
gUsbDevice.ep0_rx_handler = NULL;
gUsbDevice.ep0_class_cmd_handler.b_enable = KAL_FALSE;
gUsbDevice.resource_ep_bulkin_number = 0;
gUsbDevice.resource_ep_bulkout_number = 0;
gUsbDevice.resource_ep_intr_number = 0;
gUsbDevice.resource_interface_number = 0;
gUsbDevice.resource_string_number = 0;
}
/************************************************************
EP0 functions
*************************************************************/
/* register EP0 rx OUT token data handler */
void USB_Register_EP0_RxHdlr(usb_ep0_rx_ptr handler)
{
gUsbDevice.ep0_rx_handler = handler;
}
void USB_Register_EP0_Class_CmdHdlr(kal_uint8 cmd, usb_ep0_cmd_ptr handler)
{
gUsbDevice.ep0_class_cmd_handler.cmd = cmd;
gUsbDevice.ep0_class_cmd_handler.ep0_cmd_hdlr = handler;
gUsbDevice.ep0_class_cmd_handler.b_enable = KAL_TRUE;
}
/* prepare TX data infomration for pep0state, data is actually sent out in TX state handler */
void USB_Generate_EP0Data(Usb_Ep0_Status*pep0state, Usb_Command*pcmd, void *data, kal_int32 len)
{
pep0state->nBytesLeft = len;
pep0state->pData = (void*)data;
/* only transmit at most command request */
if (pcmd->wLength < pep0state->nBytesLeft)
pep0state->nBytesLeft = pcmd->wLength;
/* EP0 go to TX state */
gUsbDevice.ep0_state = USB_EP0_TX;
}
/************************************************************
system ctrl functions
*************************************************************/
/* init function, called when user select usb type,
entry function for task , B_eanble is D+ detection enable */
void USB_Init(USB_DEVICE_TYPE type, kal_bool b_enable)
{
#ifndef __USB_ENABLE__
EXT_ASSERT(0, 0, 0, 0);
#endif
#if ( defined(MT6218) || defined(MT6218B) || defined(MT6219) )
#ifndef MCU_52M
EXT_ASSERT(0, 0, 0, 0); /* Must 52M */
#endif /* MCU_52M */
#endif /* MT6218||MT6218B||MT6219 */
USB_Init_Drv_Info(); /*initialize driver parameters*/
USB_Init_Device_Status(); /*initialize global variable gUsbDevice*/
if(type == USB_MASS_STORAGE)
{
USB_Init_Ms_Status();
}
else if(type == USB_CDC_ACM)
{
USB_Init_Acm_Status();
}
#ifdef WEBCAM_SUPPORT
else if(type == USB_VIDEO)
{
USB_Init_Video_Status();
}
#endif
else if(type == USB_COMPOSITE)
{
USB_Init_Ms_Status();
USB_Init_Acm_Status();
}
else
{
EXT_ASSERT(0, type, 0, 0);
}
gUsbDevice.device_type = type;
/* register reset and ep0 interrupt handler to driver info*/
USB_Register_Drv_Info(USB_DRV_HDLR_RESET, 0, USB_Reset);
USB_Register_Drv_Info(USB_DRV_HDLR_EP0, 0, USB_Endpoint0_Hdlr);
/* create descriptors */
USB_Software_Create();
#ifdef __USB_RAMDISK__
if (type != USB_CDC_ACM)
{
FAT_Init();
}
#endif /*__USB_RAMDISK__*/
if(b_enable == KAL_TRUE)
{
/* enable USB power, host can detect USB device*/
USB_PDNmode(KAL_FALSE);
}
/* reset and initialize system initial value and registers*/
USB_Reset_Drv(); /* reset hw power register */
USB_Initialize_Drv();
/* initailize according to application*/
USB_Initialize();
/* if __OTG_ENABLE__, only activate OTG ISR*/
#ifdef __OTG_ENABLE__
OTG_Drv_Activate_ISR();
if(b_enable == KAL_TRUE)
OTG_Enable_Device();
#else
/* LISR should be unmask after all initialize and enable any USB interrupt */
USB_Drv_Activate_ISR();
#endif /*