⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbacm_drv.c

📁 MTK平台绝密核心代码之 USB驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
			USB2UARTPort.Tx_Buffer_ISR.Read = 0;
	}
	else if (USB2Uart_MemType == USBTRX_MEM_TASK)
	{
		USB2UARTPort.Tx_Buffer.Read += USB2Uart_WriteLength;
		ASSERT(USB2UARTPort.Tx_Buffer.Read <= USB2UARTPort.Tx_Buffer.Length);
		if (USB2UARTPort.Tx_Buffer.Read == USB2UARTPort.Tx_Buffer.Length)
			USB2UARTPort.Tx_Buffer.Read = 0;
	}
	else
	{
		EXT_ASSERT(0, 0, 0, 0); 
	}

	/* reset to 0*/
	USB2Uart_WriteLength = 0;
}

/* 
    Flush all data in TX ring buffer, use polling method
    Note that this is special for sending exception log since interrupt is disabled when exception occurs
    It must not be used in normal time 
*/
void USB2UART_Polling_Flush_Transmit_Data(void)
{
	kal_uint32 addr;
	kal_uint32 length=0;

	/* avoid sending ilm to UART owner*/
	g_UsbACM.send_Txilm = KAL_FALSE;
	g_UsbACM.send_Rxilm = KAL_FALSE;

	/* wait for the running DMA done */
	USB_Polling_Transmit_Done(g_UsbACM.txpipe->byEP);
	if (USB2Uart_MemType != USBTRX_MEM_UNKOWN) /* make sure that SW buffer have data */
	USB2UART_Update_Transmit_Data();

	/* flush the data in TX buffer*/
	length = USB2UART_Check_Transmit_Data(&addr);
	while(length)
	{
		/* used for callback function to know sent bytes */
		USB_Polling_Transmit_Data(g_UsbACM.txpipe->byEP, USB_IN_EP_TYPE, addr, length, NULL, KAL_FALSE);
		USB2UART_Update_Transmit_Data();
		length = USB2UART_Check_Transmit_Data(&addr);  /* because there are two Tx buffers */
	}
}

/* determine what buffer has data to send and call DMA setup function*/
void USB2UART_DMATransmit(void)
{
	kal_uint32 addr;
	kal_uint32 length=0;

	length = USB2UART_Check_Transmit_Data(&addr);

	if (length)
	{	
		/* dma running state is cleared by USB2UART_Tx_DMA_Callback */
		USB_DMA_Setup(g_UsbACM.txpipe->byEP, USB_IN_EP_TYPE, addr, length, USB2UART_Tx_DMA_Callback, KAL_TRUE);
	}
}

/* DMA callback function for TX sent out data */
static void USB2UART_Tx_DMA_Callback(void)
{
	kal_uint32 savedMask;

	/* tx complete callback*/
	USB2UARTPort.tx_cb(0);
#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*/
	USB_DMA_Set_Run_Status(g_UsbACM.txpipe->byEP, KAL_FALSE);


	/* no more data to send */
	if ( (USB2UARTPort.Tx_Buffer.Read == USB2UARTPort.Tx_Buffer.Write) && 
		(USB2UARTPort.Tx_Buffer_ISR.Read == USB2UARTPort.Tx_Buffer_ISR.Write) )
	{
		return;
	}

	/* send more data in tx buffer or tx isr buffer */
	savedMask = SaveAndSetIRQMask();
	/* in case usb is plug 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();
	   }
	}   
	RestoreIRQMask(savedMask);
	
}

/************************************************************
	Bulk EP OUT handle functions (clear rx fifo data, read them out and drop)
*************************************************************/
void USB_Acm_Rx_ClrFifo(void)
{
	kal_uint32        nCount;	
	kal_uint8         data[USB_EP_BULK_MAXP];
	
	/* check if data received */
	nCount = USB_EP_Out_Pkt_Len(g_UsbACM.rxpipe->byEP);

#ifdef  __PRODUCTION_RELEASE__	
	if(nCount > USB_EP_BULK_MAXP)
	{
		nCount = USB_EP_BULK_MAXP;
	}
#else
	EXT_ASSERT((nCount<=USB_EP_BULK_MAXP), nCount, USB_EP_BULK_MAXP, 0);
#endif

	if(nCount>0)
	{
		/* get the data from fifo */
		USB_EPFIFORead(g_UsbACM.rxpipe->byEP, nCount, data);

		/* Clear OutPktRdy */
		USB_EP_Bulk_Out_Ready(g_UsbACM.rxpipe->byEP);
	}
}


/************************************************************
	interface initialization functions
*************************************************************/

/* communication interface create function, prepare descriptor */
void USB_Acm_CommIf_Create(void *ifname)
{
	kal_uint8 ep_id;
	kal_uint8 if_id;

	/* get resource number and register to gUsbDevice */
	g_UsbACM.comm_if_info = USB_Get_Interface_Number(&if_id);
	g_UsbACM.comm_ep_intr_info = USB_Get_Intr_Ep(&ep_id); /* number is 3  */

	/* record interface name and interface descriptor length */
	g_UsbACM.comm_if_info->interface_name_ptr = (kal_char *)ifname;
	g_UsbACM.comm_if_info->ifdscr_size = USB_CDC_IF_LENGTH;
	g_UsbACM.comm_ep_intr_info->epdscr_size = USB_EPDSC_LENGTH;

	/* related endpoint info and class specific command handler*/
	g_UsbACM.comm_if_info->ep_info[0] = (Usb_Ep_Info*)g_UsbACM.comm_ep_intr_info;
	g_UsbACM.comm_if_info->if_class_specific_hdlr = USB_Acm_Ep0_Command;

	/* standard interface descriptor */
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bLength = USB_CDC_IF_LENGTH;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bDescriptorType = USB_INTERFACE;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bInterfaceNumber = if_id;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bAlternateSetting = 0;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bNumEndpoints = USB_CDC_ACM_COMM_EP_NUMBER;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bInterfaceClass = USB_ACM_COMM_INTERFACE_CLASS_CODE;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bInterfaceSubClass = USB_ACM_COMM_INTERFACE_SUBCLASS_CODE;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bInterfaceProtocol = USB_ACM_COMM_INTERFACE_PROTOCOL_CODE;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->iInterface = 
		USB_Get_String_Number((void *)g_UsbACM.acm_param->comm_interface_string);   
	/*Header Functional Descriptor*/
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->HFbFunctionLength = 0x05;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->HFbDescriptorType = 0x24;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->HFbDescriptorSubtype = 0x00;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bcdCDC = 0x0110;
	/*Abstract Control Management Functional Descriptor*/
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->ACMFbFunctionLength = 0x04;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->ACMFbDescriptorType = 0x24;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->ACMFbDescriptorSubtype = 0x02;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->ACMFbmCapabilities = 0x0f;
	/*Union Functional Descriptor*/
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->UFbFunctionLength = 0x05;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->UFbDescriptorType = 0x24;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->UFbDescriptorSubtype = 0x06;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bMasterInterface = if_id;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bSlaveInterface0 = g_UsbACM.data_interface_id;
	/*Call Management Descriptor*/
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->CMFbFunctionLength = 0x05;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->CMFbDescriptorType = 0x24;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->CMFbDescriptorSubtype = 0x01;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->CMFbmCapabilities = 0x03;
	((Usb_Cdc_If_Dscr*)&g_UsbACM.comm_if_info->ifdscr.classif)->bDataInterface = g_UsbACM.data_interface_id;

	/* endpoint handler*/
	USB_Register_Drv_Info(USB_DRV_HDLR_EP_IN, ep_id, NULL);
	g_UsbACM.comm_ep_intr_info->ep_reset = NULL;
	
	/* endpoint descriptor */
	g_UsbACM.comm_ep_intr_info->epdesc.stdep.bLength = USB_EPDSC_LENGTH;
	g_UsbACM.comm_ep_intr_info->epdesc.stdep.bDescriptorType = USB_ENDPOINT;
	g_UsbACM.comm_ep_intr_info->epdesc.stdep.bEndpointAddress = (USB_EP_DIR_IN | ep_id);	/*InPipe*/
	g_UsbACM.comm_ep_intr_info->epdesc.stdep.bmAttributes = USB_EP_INTR;
	g_UsbACM.comm_ep_intr_info->epdesc.stdep.wMaxPacketSize[0] = USB_EP_INTR_MAXP&0xff; 		/*HW-dependent*/
	g_UsbACM.comm_ep_intr_info->epdesc.stdep.wMaxPacketSize[1] = (USB_EP_INTR_MAXP>>8)&0xff; 
	g_UsbACM.comm_ep_intr_info->epdesc.stdep.bInterval = 1;
	g_UsbACM.comm_ep_intr_info->ep_status.epin_status.byEP = ep_id;
	g_UsbACM.comm_ep_intr_info->ep_status.epin_status.nBytesLeft = USB_EP_NODATA;

	if (g_UsbACM.handle == 0)
		GPTI_GetHandle(&g_UsbACM.handle);   /*for break use!!*/
}

/* communication interface reset function, should enable EP, but we do not use this interrupt EP so not enable it */
void USB_Acm_CommIf_Reset(void)
{
	g_UsbACM.intrpipe = &g_UsbACM.comm_ep_intr_info->ep_status.epin_status;
}

/* data interface create function, prepare descriptor */
void USB_Acm_DataIf_Create(void *ifname)
{
	kal_uint8 ep_in_id;
	kal_uint8 ep_out_id;
	kal_uint8 if_id;
	
	/* get resource number and register to gUsbDevice */
	g_UsbACM.data_if_info = USB_Get_Interface_Number(&if_id);
	g_UsbACM.data_interface_id = if_id;
	g_UsbACM.data_ep_in_info = USB_Get_BulkIn_Ep(&ep_in_id);
	g_UsbACM.data_ep_out_info = USB_Get_BulkOut_Ep(&ep_out_id);

	/* record interface name and interface descriptor length */
	g_UsbACM.data_if_info->interface_name_ptr = (kal_char *)ifname;
	g_UsbACM.data_if_info->ifdscr_size = USB_IFDSC_LENGTH;
	g_UsbACM.data_ep_in_info->epdscr_size = USB_EPDSC_LENGTH;
	g_UsbACM.data_ep_out_info->epdscr_size = USB_EPDSC_LENGTH;

	/* related endpoint info and class specific command handler*/
	g_UsbACM.data_if_info->ep_info[0] = g_UsbACM.data_ep_in_info;
	g_UsbACM.data_if_info->ep_info[1] = (Usb_Ep_Info*)g_UsbACM.data_ep_out_info;
	g_UsbACM.data_if_info->if_class_specific_hdlr = NULL;

	/* standard interface descriptor */
	g_UsbACM.data_if_info->ifdscr.stdif.bLength = USB_IFDSC_LENGTH;
	g_UsbACM.data_if_info->ifdscr.stdif.bDescriptorType = USB_INTERFACE;
	g_UsbACM.data_if_info->ifdscr.stdif.bInterfaceNumber = if_id;
	g_UsbACM.data_if_info->ifdscr.stdif.bAlternateSetting = 0;
	g_UsbACM.data_if_info->ifdscr.stdif.bNumEndpoints = USB_CDC_ACM_DATA_EP_NUMBER;
	g_UsbACM.data_if_info->ifdscr.stdif.bInterfaceClass = USB_ACM_DATA_INTERFACE_CLASS_CODE;
	g_UsbACM.data_if_info->ifdscr.stdif.bInterfaceSubClass = USB_ACM_DATA_INTERFACE_SUBCLASS_CODE;
	g_UsbACM.data_if_info->ifdscr.stdif.bInterfaceProtocol = USB_ACM_DATA_INTERFACE_PROTOCOL_CODE; 
	g_UsbACM.data_if_info->ifdscr.stdif.iInterface = USB_Get_String_Number((void *)g_UsbACM.acm_param->data_interface_string);   

	/* endpoint handler */
	USB_Register_Drv_Info(USB_DRV_HDLR_EP_IN, ep_in_id, NULL);
	g_UsbACM.data_ep_in_info->ep_reset = USB_Acm_BulkIn_Reset;
	
	if(g_UsbACM.acm_owner==USB_ACM_OWNER_DSP)
	{
	#ifdef __DSPIRDBG__	
		USB_Register_Drv_Info(USB_DRV_HDLR_EP_OUT, ep_out_id, NULL);
	#else
		EXT_ASSERT(0, g_UsbACM.acm_owner, 0, 0);
	#endif
	}
	else if(g_UsbACM.acm_owner==USB_ACM_OWNER_FT)
	{
		USB_Register_Drv_Info(USB_DRV_HDLR_EP_OUT, ep_out_id, USB_Acm_FT_BulkOut_Hdr);
	}
	else
	{
		USB_Register_Drv_Info(USB_DRV_HDLR_EP_OUT, ep_out_id, USB_Acm_BulkOut_Hdr);
	}
	g_UsbACM.data_ep_out_info->ep_reset = USB_Acm_BulkOut_Reset;
	/* endpoint descriptor */
	g_UsbACM.data_ep_in_info->epdesc.stdep.bLength = USB_EPDSC_LENGTH;
	g_UsbACM.data_ep_in_info->epdesc.stdep.bDescriptorType = USB_ENDPOINT;
	g_UsbACM.data_ep_in_info->epdesc.stdep.bEndpointAddress = (USB_EP_DIR_IN | ep_in_id);   /*InPipe*/
	g_UsbACM.data_ep_in_info->epdesc.stdep.bmAttributes = USB_EP_BULK;
	g_UsbACM.data_ep_in_info->epdesc.stdep.wMaxPacketSize[0] = USB_EP_BULK_MAXP&0xff;
	g_UsbACM.data_ep_in_info->epdesc.stdep.wMaxPacketSize[1] = (USB_EP_BULK_MAXP>>8)&0xff;
	g_UsbACM.data_ep_in_info->epdesc.stdep.bInterval = 0;
	g_UsbACM.data_ep_in_info->ep_status.epin_status.byEP = ep_in_id;
	g_UsbACM.data_ep_in_info->ep_status.epin_status.nBytesLeft = USB_EP_NODATA;
	g_UsbACM.data_ep_out_info->epdesc.stdep.bLength = USB_EPDSC_LENGTH;
	g_UsbACM.data_ep_out_info->epdesc.stdep.bDescriptorType = USB_ENDPOINT;
	g_UsbACM.data_ep_out_info->epdesc.stdep.bEndpointAddress = (USB_EP_DIR_OUT | ep_out_id);   /*OutPipe*/
	g_UsbACM.data_ep_out_info->epdesc.stdep.bmAttributes = USB_EP_BULK;
	g_UsbACM.data_ep_out_info->epdesc.stdep.wMaxPacketSize[0] = USB_EP_BULK_MAXP&0xff;
	g_UsbACM.data_ep_out_info->epdesc.stdep.wMaxPacketSize[1] = (USB_EP_BULK_MAXP>>8)&0xff;
	g_UsbACM.data_ep_out_info->epdesc.stdep.bInterval = 0;
	g_UsbACM.data_ep_out_info->ep_status.epout_status.byEP = ep_out_id;

	USB_Get_DMA_Channel(ep_in_id);
}

/* data interface reset function, enable EP*/
void USB_Acm_DataIf_Reset(void)
{
	g_UsbACM.txpipe = &g_UsbACM.data_ep_in_info->ep_status.epin_status;
	g_UsbACM.rxpipe = &g_UsbACM.data_ep_out_info->ep_status.epout_status;

	/*DMA*/
	USB_InEPEn(g_UsbACM.data_ep_in_info->ep_status.epin_status.byEP, KAL_TRUE);
	/*Non-DMA*/
	USB_OutEPEn(g_UsbACM.data_ep_out_info->ep_status.epout_status.byEP, KAL_FALSE);
}



/************************************************************
	global variable g_UsbACM initialize and release functions
*************************************************************/

/* initialize global variable g_UsbACM */
void USB_Init_Acm_Status(void)
{
	g_UsbACM.txpipe = NULL;
	g_UsbACM.rxpipe = NULL;
	g_UsbACM.intrpipe = NULL;
	g_UsbACM.data_interface_id = 0;
	g_UsbACM.break_detect = KAL_FALSE;
	g_UsbACM.break_number = 0;
	g_UsbACM.out_pipe_race = KAL_FALSE;
	g_UsbACM.send_Txilm = KAL_FALSE;
	g_UsbACM.send_Rxilm = KAL_TRUE;
	g_UsbACM.send_UARTilm = KAL_FALSE;
	g_UsbACM.config_send_Txilm = KAL_FALSE;
}

/* release global variable g_UsbACM */
void USB_Release_Acm_Status(void)
{
	g_UsbACM.txpipe = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -