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

📄 usbacm_drv.c

📁 mtk 6225平台的usb程序! 对想了解mtk平台usb的朋友会有帮助!
💻 C
📖 第 1 页 / 共 3 页
字号:
	return USB2Uart_WriteLength;
}

/* 
    Update the buffer information after transmit done
    Note that "USB2Uart_WriteLength" will be reset to 0.
    This function and "USB2UART_Check_Transmit_Data" function must be pair.
*/
static void USB2UART_Update_Transmit_Data(void)
{
	/* update buffer information */
	if (USB2Uart_MemType == USBTRX_MEM_ISR)
	{
		USB2UARTPort.Tx_Buffer_ISR.Read += USB2Uart_WriteLength;
		ASSERT(USB2UARTPort.Tx_Buffer_ISR.Read <= USB2UARTPort.Tx_Buffer_ISR.Length);
		if (USB2UARTPort.Tx_Buffer_ISR.Read == USB2UARTPort.Tx_Buffer_ISR.Length)
			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, KAL_FALSE);
	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, KAL_FALSE);
	}
}

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

	if(g_UsbACM.force_ISR_buffer == KAL_TRUE)
		length = USB2UART_Check_Transmit_Data(&addr, KAL_FALSE);
	else
		length = USB2UART_Check_Transmit_Data(&addr, g_UsbACM.threshold_enable);

	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;
#ifdef __INTERRUPT_TEST__
	static kal_uint8  number = 1;
	kal_uint32 index;
	kal_uint8 data[8];
#endif

	/* tx complete callback*/
	USB2UARTPort.tx_cb(uart_port_usb);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
	
#ifdef __INTERRUPT_TEST__
	for (index = 0; index < 8 ; index++)
	{
		data[index] = number;
		number++;
	}

	if (g_usb_intr_enable == KAL_TRUE)
	{
		g_usb_intr_enable = KAL_FALSE;
		USB_EPFIFOWrite(g_UsbACM.intrpipe->byEP, 8, data);
		USB_EP_Bulk_In_Ready(g_UsbACM.intrpipe->byEP);
	}
#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);

	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)
		g_UsbACM.force_ISR_buffer = KAL_TRUE;

	/* 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*/
#ifdef __INTERRUPT_TEST__
	USB_Register_Drv_Info(USB_DRV_HDLR_EP_IN, ep_id, USB_Acm_IntrIn_Hdlr);
	g_UsbACM.comm_ep_intr_info->ep_reset = NULL;
#else
	USB_Register_Drv_Info(USB_DRV_HDLR_EP_IN, ep_id, NULL);
	g_UsbACM.comm_ep_intr_info->ep_reset = NULL;
#endif
	
	/* 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!!*/

	if (g_UsbACM.ring_buffer_handle == 0)
		GPTI_GetHandle(&g_UsbACM.ring_buffer_handle);   /* for ring buffer time out 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;

#ifdef __INTERRUPT_TEST__
	/*Non-DMA*/
	USB_InEPEn(g_UsbACM.comm_ep_intr_info->ep_status.epin_status.byEP, KAL_FALSE);
#endif
}

/* 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.ring_buffer_timer_counting = KAL_FALSE;
}

/* release global variable g_UsbACM */
void USB_Release_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;

⌨️ 快捷键说明

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