📄 usbio.c
字号:
/********************************************/
USB_FlushTxFIFO( Ep );
ep -> send_total_len = 0;
ep -> send_actual_len = 0;
ep -> send_zero_byte = FALSE;
/********************************************/
/* Decode setup message. */
/********************************************/
Dev_Request = (USB_DEV_REQUEST *)ep -> recv_data;
switch( Dev_Request -> bmRequestType & USB_REQ_TYPE_MASK )
{
case USB_REQ_STANDARD:
switch( Dev_Request -> bRequest )
{
case USB_GET_DESCRIPTOR:
error = ( PASS != USBDESC_SendDescriptor( Ep, Dev_Request,
ep -> IN_max_pkt, USB_Mode ));
break;
case USB_SET_DESCRIPTOR: /*Not supported in this application*/
case USB_SYNCH_FRAME:
error = TRUE;
break;
default:
error = TRUE;
break;
};
break;
case USB_REQ_CLASS:
switch( Dev_Request -> bRequest )
{
case USB_HID_GET_REPORT:
dbmsg_trace( DBM_USB, "USB_HID_GET_REPORT\r\n" );
if( USB_Mode == USBMAIN_FACTORYMODE )
{
/********************************************/
/* Will return currnt mouse data. Since */
/* this is control EP0, the DataRequested */
/* flags do not need to be set or checked. */
/********************************************/
USB_WriteData( Ep, (uint32 *)(Ep_MouseData.send_data), 3 );
}
break;
case USB_HID_SET_REPORT:
/********************************************/
/* This request will be ignored, so just */
/* wait for OUT and dump the data. */
/* */
/* The host will send an IN token to ask */
/* for the status of this three-stage setup */
/* transfer with OUT data. */
/* */
/* The USB device should send a zero length */
/* packet for this. */
/********************************************/
USB_WriteData(Ep, &zero_buffer, 0);
break;
case USB_HID_SET_IDLE:
/********************************************/
/* Mouse interface. */
/* */
/* Calculate the requested rate in milli- */
/* seconds and set up interval timer if the */
/* interval is non-zero. */
/********************************************/
if( Dev_Request -> wIndex == (uint16)Ep_MouseData.interface )
{
MOUSE_HID_Idle_Rate =
(( Dev_Request -> wValue & 0xFF00 ) >> 8 ) * 4; /* ms*/
dbmsg_ftrace( DBM_USB, "mouse USB_HID_SET_IDLE: %d\r\n",
MOUSE_HID_Idle_Rate );
if( MOUSE_HID_Idle_Rate != 0 )
{
result = TMR_Create( (TMR_ISR_Func)USBMAIN_MouseIdleISR,
MOUSE_HID_Idle_Rate * 1000,
FALSE, &MOUSE_HID_Timer_Id );
if( result == TMR_UNAVAIL )
MOUSE_HID_Timer_Id = NULL;
}
}
/********************************************/
/* Keyboard interface. */
/* */
/* Calculate the requested rate in milli- */
/* seconds and set up interval timer if the */
/* interval is non-zero. */
/********************************************/
if(Dev_Request->wIndex == (uint16)Ep_KeyboardData.interface)
{
KEYBOARD_HID_Idle_Rate =
(( Dev_Request -> wValue & 0xFF00 ) >> 8 ) * 4;
dbmsg_ftrace( DBM_USB, "key USB_HID_SET_IDLE: %d\r\n",
KEYBOARD_HID_Idle_Rate );
if( KEYBOARD_HID_Idle_Rate != 0 )
{
result = TMR_Create((TMR_ISR_Func)USBMAIN_KeyboardIdleISR,
KEYBOARD_HID_Idle_Rate * 1000,
FALSE, &KEYBOARD_HID_Timer_Id);
if (result == TMR_UNAVAIL)
KEYBOARD_HID_Timer_Id = NULL;
}
}
/********************************************/
/* The host will send an IN token to ask */
/* for the status of this two-stage setup */
/* transfer. The USB device should send a */
/* zero length packet for this. */
/********************************************/
USB_WriteData( Ep, &zero_buffer, 0 );
break;
case USB_HID_GET_IDLE:
USBMAIN_HidGetIdleRecv( Ep, Dev_Request -> wIndex );
break;
default:
error = TRUE;
};
break;
case USB_REQ_VENDOR:
error = TRUE;
break;
default:
error = TRUE;
break;
};
if (error) /* if non-supported setup request */
{
USB_FlushRxFIFO( Ep );
USB_SetSTALL( Ep, USB_EP_OUT, TRUE );
USB_SetSTALL( Ep, USB_EP_IN, TRUE );
}
/********************************************/
/* Clear NAK bits that are automatically */
/* set whenever a setup request is received */
/********************************************/
USB_SetNAK( Ep, USB_EP_OUT, FALSE );
USB_SetNAK( Ep, USB_EP_IN, FALSE );
return result;
}
/****************************************************************************/
/* Receive data handler. */
/****************************************************************************/
int08 USBMAIN_RecvDataHandler( uint08 Ep, uint08 Data_Len )
{
volatile int08 result = PASS;
USBMAIN_EP_DATA *ep = &Ep_Data[Ep];
result = USB_ReadData(Ep, (uint32 *)ep -> recv_data, Data_Len );
ep -> recv_total_len = Data_Len;
ep -> recv_actual_len = Data_Len;
return result;
}
/****************************************************************************/
/* Send data handler. */
/* */
/* This function writes data stored in the Ep_Data data buffer to the USB */
/* host for the specified endpoint. It should be called whenever an IN */
/* event is received by the USBMAIN_Task. If there are no data loaded in */
/* the Ep_Data buffer to written, or if the USB_WriteData call fails, then */
/* this function will return FAIL. If data are successfully written to the */
/* TxFIFO, then this function will return PASS. */
/* */
/* NOTE: The return value of this function should be used to determine */
/* whether to clear the IN event for the endpoint in the USBMAIN_Task. If */
/* the return value is PASS, then the requested data have been written and */
/* the IN event should be cleared. If the return value is FAIL, then no */
/* data have been sent to the host. The IN event should NOT be cleared so */
/* that the USBMAIN_Task can be woken up to send the requested data at a */
/* later time. */
/****************************************************************************/
int08 USBMAIN_SendDataHandler( uint08 Ep )
{
int08 result = PASS;
uint08 remBytes; /* count of remaining bytes to send */
uint08 send_size_in_bytes;
USBMAIN_EP_DATA *ep = &Ep_Data[Ep];
USBMAIN_MOUSE_DATA *m_ep; /* used for mouse and keyboard */
uint16 Buffer_Size;
uint32 zero_buffer; /* dummy zero-length buffer */
/********************************************/
/* Mouse/keyboard endpoint. */
/* */
/* Messages to these endpoints are known to */
/* have a length <= FIFO size. */
/********************************************/
if( Ep == USB_MouseEP || Ep == USB_KeyBoardEP )
{
m_ep = ( Ep == USB_MouseEP ) ? &Ep_MouseData : &Ep_KeyboardData;
if( m_ep->send_total_len > 0 ) /* if data to be sent */
{
send_size_in_bytes = m_ep->send_total_len - m_ep->send_actual_len;
result = USB_WriteData( Ep, (uint32 *)m_ep -> send_data, m_ep -> send_total_len );
if( result != PASS )
return result;
m_ep -> send_total_len = 0;
m_ep -> send_actual_len = 0;
if( m_ep -> send_zero_byte == TRUE )/* zero byte IN data needed */
{
result = USB_WriteData( Ep, &zero_buffer, 0 );
m_ep->send_zero_byte = FALSE;
}
}
}
/********************************************/
/* Control/Projector control/RFC endpoint. */
/********************************************/
else if (Ep < USB_MouseEP)
{
if(( ep -> send_total_len - ep -> send_actual_len ) > 0 )
{
remBytes = ep->send_total_len - ep->send_actual_len;
/********************************************/
/* Determine data length: lesser of FIFO */
/* size or remaining bytes to send. */
/********************************************/
if( PASS != ( result = USB_GetEpTxFIFOSize( Ep, &Buffer_Size )))
return result;
if ( remBytes <= ( Buffer_Size * 4 ))
send_size_in_bytes = remBytes;
else
send_size_in_bytes = Buffer_Size * 4;
/********************************************/
/* Write data to FIFO. This may be an en- */
/* tire message or a message segment if the */
/* message length is greater than the FIFO */
/* size. */
/********************************************/
dbmsg_ftrace( DBM_USB, "USB_WriteData ep=%d send=%08x total=%d actual=%d size=%d\r\n",
Ep, ep->send_data, ep->send_total_len, ep->send_actual_len, send_size_in_bytes );
if( PASS != ( result = USB_WriteData(Ep, (uint32 *)(ep -> send_data + ep -> send_actual_len),
send_size_in_bytes )))
return result;
/********************************************/
/* Calculate remaining byte count and */
/* finish message handling if all data are */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -