📄 usbacm_drv.c
字号:
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 + -