📄 usbacm_drv.c
字号:
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;
if(g_UsbACM.ring_buffer_timer_counting == KAL_TRUE)
{
GPTI_StopItem(g_UsbACM.ring_buffer_handle);
g_UsbACM.ring_buffer_timer_counting = KAL_FALSE;
}
}
/***********************************************************
GPT timer handle break signal
************************************************************/
/* GPT timer handler for break signal */
static void USB_Acm_Break_Timeout(void *parameter)
{
GPTI_StopItem(g_UsbACM.handle);
g_UsbACM.break_detect = KAL_FALSE;
g_UsbACM.break_number++;
USB2UARTPort.breakDet = KAL_TRUE;
}
/************************************************************
Ring buffer threshold and time out mechanism APIs
************************************************************/
/* GPT timer handler for ring buffer time out */
static void USB_Acm_Ring_Buffer_Timeout(void *parameter)
{
kal_uint32 addr;
kal_uint32 length = 0;
kal_uint32 savedMask;
if(INT_Exception_Enter == 0)
{
savedMask = SaveAndSetIRQMask();
length = USB2UART_Check_Transmit_Data(&addr, KAL_FALSE);
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);
}
RestoreIRQMask(savedMask);
}
else
ASSERT(0);
}
void USB_Acm_Ring_Buffer_Threshold_Enable(kal_bool bset, module_type ownerid)
{
#ifndef __PRODUCTION_RELEASE__
if(ownerid != USB2UARTPort.ownerid)
{
EXT_ASSERT( 0, (kal_uint32) ownerid, (kal_uint32)USB2UARTPort.ownerid, 0);
}
#endif /* __PRODUCTION_RELEASE__ */
g_UsbACM.threshold_enable = bset;
#ifndef __PRODUCTION_RELEASE__
if(bset == KAL_TRUE)
kal_prompt_trace(MOD_USB, "Threshold is ON");
else
kal_prompt_trace(MOD_USB, "Threshold is OFF");
#endif
}
/************************************************************
EP0 handle functions
************************************************************/
/* set USB request line coding to UART DCB structure */
static void USB_Acm_Ep0_SetLineCoding(void *data)
{
kal_uint32 nCount;
/* read setting and set to UART structure*/
nCount = USB_EP0_Pkt_Len();
if(nCount > 0)
{
USB_EPFIFORead(0, nCount, &g_UsbACM.line_coding);
USB2UART_LineCoding2DCB(&g_UsbACM.line_coding, &USB2UARTPort.DCB);
gUsbDevice.ep0_state = USB_EP0_RX_STATUS;
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_FALSE, KAL_TRUE);
}
}
/* parse class specific request */
static void USB_Acm_Ep0_Command(Usb_Ep0_Status* pep0state,Usb_Command* pcmd)
{
kal_uint8 bError = KAL_FALSE;
switch (pcmd->bRequest)
{
case USB_ACM_SEND_ENCAPSULATED_COMMAND:
/* not support */
ASSERT(0);
bError = KAL_TRUE;
break;
case USB_ACM_GET_ENCAPSULATED_RESPONSE:
/* not support */
ASSERT(0);
bError = KAL_TRUE;
break;
case USB_ACM_SET_LINE_CODING:
/* register handler to handle the get data*/
USB_Register_EP0_RxHdlr(USB_Acm_Ep0_SetLineCoding);
gUsbDevice.ep0_state =USB_EP0_RX;
break;
case USB_ACM_GET_LINE_CODING:
/* tell host the current setting */
USB_Generate_EP0Data(pep0state, pcmd, &g_UsbACM.line_coding, 7);
break;
case USB_ACM_SET_CONTROL_LINE_STATE:
/* do not need to do anything */
break;
case USB_ACM_SEND_BREAK:
/* break behavior */
switch(pcmd->wValue)
{
case 0xffff:
g_UsbACM.break_detect = KAL_TRUE;
break;
case 0x0:
g_UsbACM.break_detect = KAL_FALSE;
g_UsbACM.break_number++;
USB2UARTPort.breakDet = KAL_TRUE;
break;
default:
GPTI_StopItem(g_UsbACM.handle);
g_UsbACM.break_detect = KAL_TRUE;
GPTI_StartItem(g_UsbACM.handle, (pcmd->wValue/10),
USB_Acm_Break_Timeout, NULL);
break;
}
break;
case USB_ACM_SET_COMM_FEATURE:
/* not support */
ASSERT(0);
bError = KAL_TRUE;
break;
case USB_ACM_GET_COMM_FEATURE:
ASSERT(0);
bError = KAL_TRUE;
break;
case USB_ACM_CLEAR_COMM_FEATURE:
ASSERT(0);
bError = KAL_TRUE;
break;
default:
ASSERT(0);
bError = KAL_TRUE;
break;
}
/* Stall command if an error occured */
if (gUsbDevice.ep0_state == USB_EP0_IDLE)
{
gUsbDevice.ep0_state = USB_EP0_RX_STATUS;
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, bError, KAL_TRUE);
}
else
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, bError, KAL_FALSE);
}
/************************************************************
Bulk EP OUT handle functions
*************************************************************/
/*
Used to retreive exception log, all interrupts are disabled
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_Recv_Data(void)
{
/* avoid sending ilm to UART owner*/
g_UsbACM.send_Txilm = KAL_FALSE;
g_UsbACM.send_Rxilm = KAL_FALSE;
USB_Polling_Recv_Data(g_UsbACM.rxpipe->byEP);
}
/* EP Bulk Out interrupt handler, called by EP interrupt */
static void USB_Acm_BulkOut_Hdr(void )
{
kal_int32 RoomLeft;
kal_uint32 nCount;
kal_uint32 index;
kal_uint8 data[USB_EP_BULK_MAXP];
/* check that this function can not be re-entry */
ASSERT(g_UsbACM.out_pipe_race == KAL_FALSE);
g_UsbACM.out_pipe_race = KAL_TRUE;
/* stop escape GPT timer */
if (USB2UARTPort.ESCDet.GuardTime != 0)
GPTI_StopItem(USB2UARTPort.handle);
/* check data length and ring buffer empty length*/
nCount = USB_EP_Out_Pkt_Len(g_UsbACM.rxpipe->byEP);
#ifndef __PRODUCTION_RELEASE__
/* This log cannot be executed when assertion because the system stack will overrun */
if(INT_Exception_Enter == 0)
kal_prompt_trace(MOD_USB, "PC send %d", nCount);
#endif /* __PRODUCTION_RELEASE__ */
Buf_GetRoomLeft(&(USB2UARTPort.Rx_Buffer),RoomLeft);
if(nCount > 0)
{
/* rx complete callback*/
USB2UARTPort.rx_cb(uart_port_usb);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
#ifdef __PRODUCTION_RELEASE__
if(nCount > USB_EP_BULK_MAXP)
{
nCount = USB_EP_BULK_MAXP;
}
if(RoomLeft < nCount)
{
nCount = RoomLeft;
}
#else
EXT_ASSERT((nCount<=USB_EP_BULK_MAXP), nCount, USB_EP_BULK_MAXP, 0);
EXT_ASSERT((RoomLeft >= nCount), RoomLeft, nCount, 0);
#endif
/* read the data out and update roomleft parameter*/
RoomLeft-= nCount;
USB_EPFIFORead(g_UsbACM.rxpipe->byEP, nCount, data);
/* check escape character*/
if((nCount <= 3) && (USB2UARTPort.ESCDet.GuardTime != 0))
{
/* need to check escape charater */
for(index=0; index<nCount; index++)
{
/* detect escape sequence */
if (USB2UARTPort.Rec_state != UART_RecNormal)
{
if (data[index] == USB2UARTPort.ESCDet.EscChar)
{
USB2UARTPort.EscCount++;
if(USB2UARTPort.EscCount == 3)
{
USB2UARTPort.Rec_state = UART_Get3EscChar;
}
else if(USB2UARTPort.EscCount > 3)
{
USB2UARTPort.Rec_state = UART_RecNormal;
USB2UARTPort.EscCount = 0;
}
}
else
{
USB2UARTPort.Rec_state = UART_RecNormal;
USB2UARTPort.EscCount = 0;
}
}
}
}
/* push all the received data into rx ring buffer*/
for(index = 0; index < nCount; index++)
{
Buf_Push(&(USB2UARTPort.Rx_Buffer), data[index]);
}
/* Clear OutPktRdy */
USB_EP_Bulk_Out_Ready(g_UsbACM.rxpipe->byEP);
}
if(RoomLeft < USB_EP_BULK_MAXP)
{
/* rx buffer is less than one max packet size, so mask the IRQ until UART owner get bytes,
and than enough room to put a complete packet */
USB_Set_UnMask_Irq(KAL_FALSE);
}
else
{
/* make sure that buffer left more than 64 bytes so that next receive it can push to buffer at a time */
USB_Set_UnMask_Irq(KAL_TRUE);
}
/* re-start escape GPT timer */
if (USB2UARTPort.ESCDet.GuardTime != 0)
GPTI_StartItem(USB2UARTPort.handle, (USB2UARTPort.ESCDet.GuardTime/10),
USB2UART_Timeout, &USB2UARTPort);
g_UsbACM.out_pipe_race = KAL_FALSE;
}
/* EP Bulk In reset handler */
static void USB_Acm_BulkIn_Reset(void)
{
g_UsbACM.txpipe = &g_UsbACM.data_ep_in_info->ep_status.epin_status;
USB2UART_Clear_Tx_Buffer(); /* set g_UsbACM.send_Txilm = KAL_TRUE here*/
USB2UART_Clear_Tx_ISR_Buffer();
/*
if(g_UsbACM.send_Txilm == KAL_TRUE)
{
USB2UART_Sendilm(MSG_ID_UART_READY_TO_WRITE_IND);
g_UsbACM.send_Txilm = KAL_FALSE;
}*/
}
/* EP Bulk Out reset handler */
static void USB_Acm_BulkOut_Reset(void)
{
g_UsbACM.rxpipe = &g_UsbACM.data_ep_out_info->ep_status.epout_status;
g_UsbACM.send_Rxilm = KAL_TRUE;
USB2UART_Clear_Rx_Buffer();
}
#ifdef __INTERRUPT_TEST__
/* When PC return ACK, reset it to TRUE */
static void USB_Acm_IntrIn_Hdlr(void)
{
g_usb_intr_enable = KAL_TRUE;
}
#endif
/************************************************************
FT mode rx functions
************************************************************/
/* register callback function for rx data */
void USB_Acm_FT_Register_Rx_Cb(usb_acm_rx_ptr cb)
{
g_UsbACM.ft_rx_cb = cb;
}
/* EP Bulk Out interrupt handler, called by EP interrupt */
static void USB_Acm_FT_BulkOut_Hdr(void )
{
kal_uint32 nCount;
/* check that this function can not be re-entry */
ASSERT((g_UsbACM.out_pipe_race==KAL_FALSE));
g_UsbACM.out_pipe_race = KAL_TRUE;
/* check data lendth and ring buffer empty length*/
nCount = USB_EP_Out_Pkt_Len(g_UsbACM.rxpipe->byEP);
if(nCount > 0)
{
USB_EPFIFORead(g_UsbACM.rxpipe->byEP, nCount, g_UsbACM.ft_data);
g_UsbACM.ft_data_len = nCount;
/* Clear OutPktRdy */
USB_EP_Bulk_Out_Ready(g_UsbACM.rxpipe->byEP);
/* notify FT task */
if(g_UsbACM.ft_rx_cb==NULL)
EXT_ASSERT(0, 0, 0, 0);
g_UsbACM.ft_rx_cb();
/* rx buffer is less than one max packet size, so unmask the IRQ until UART owner get bytes,
and enough room to put a complete packet */
USB_Set_UnMask_Irq(KAL_FALSE);
}
g_UsbACM.out_pipe_race = KAL_FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -