📄 usb_class_requests.c
字号:
//-----------------------------------------------------------------------------
// USB_Class_Requests.c
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "USB_Type.h"
#include "USB_Configuration.h"
#include "USB_Descriptor.h"
#include "USB_Standard_Requests.h"
#include "USB_ISR.h"
#include "USB_CDC_UART.h"
#include "USB_Main.h"
#include "USB_Class_Requests.h"
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
#define CS_TEMPBUF_SIZE sizeof(TLine_Coding) // size of temporary buffer
// must be greater than sizeof(TLine_Coding) (= 7 bytes)
BYTE idata cs_temp_buffer[ CS_TEMPBUF_SIZE ]; // temporary buffer for
// CS_Get_Encapsulated_Command
// CS_Send_Encapsulated_Command
// CS_Set_Line_Coding and CS_Get_Line_Coding
//-----------------------------------------------------------------------------
// Static Variables in this file
//-----------------------------------------------------------------------------
/*
#define CS_TEMP_BUF_SIZE 0x10
static BYTE cs_temp_buffer[ CS_TEMP_BUF_SIZE ];
*/
//-----------------------------------------------------------------------------
// Local function prototypes
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Local Function prototypes
//-----------------------------------------------------------------------------
// for CDC
static void CS_Send_Encapsulated_Command(void);
static void CS_Get_Encapsulated_Command(void);
static void CS_Set_Line_Coding(void);
static bit CS_Set_Line_Coding_Complete(void);
static void CS_Get_Line_Coding(void);
static void CS_Set_ControlLine_State(void);
static void CS_Send_Break(void);
#if defined BIG_ENDIAN
void swap_endian_long( ULONG idata *lptr );
#endif // end of BIG_ENDIAN
//-----------------------------------------------------------------------------
// SDCC suport
//-----------------------------------------------------------------------------
#if defined SDCC
#pragma nooverlay
#endif // SDCC
//-----------------------------------------------------------------------------
// class specific request dispatcher
//-----------------------------------------------------------------------------
void Class_Request( void )
{
// CDC class request dispatcher
if ( Setup.wIndex.i == DSC_INTERFACE_CDC_comm )
{
switch(Setup.bRequest)
{
case SEND_ENCAPSULATED_COMMAND: CS_Send_Encapsulated_Command(); break;
case GET_ENCAPSULATED_RESPONSE: CS_Get_Encapsulated_Command(); break;
case SET_LINE_CODING: CS_Set_Line_Coding(); break;
case GET_LINE_CODING: CS_Get_Line_Coding(); break;
case SET_CONTROL_LINE_STATE: CS_Set_ControlLine_State(); break;
case SEND_BREAK: CS_Send_Break(); break;
default: break;
}
}
}
//-----------------------------------------------------------------------------
// CDC class request handlers
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Send_Encapsulated_Command
//-----------------------------------------------------------------------------
//
// Nothing to do other than unloading the data sent in the data stage.
//
//-----------------------------------------------------------------------------
void CS_Send_Encapsulated_Command(void)
{
if ( (Setup.bmRequestType == OUT_CL_INTERFACE)
&& (Setup.wValue.i == 0 )
&& (Setup.wLength.i <= CS_TEMPBUF_SIZE) ) // less than the buffer size
{
Ep_Status0 = EP_RX; // Put endpoint in recieve mode
DataPtr = (BYTE *)cs_temp_buffer;
DataSize = Setup.wLength.i; // Read out the command sent
setup_handled = TRUE;
}
}
//-----------------------------------------------------------------------------
// Get_Encapsulated_Command
//-----------------------------------------------------------------------------
//
// Return a zero-length packet
//
//-----------------------------------------------------------------------------
void CS_Get_Encapsulated_Command(void)
{
if ( (Setup.bmRequestType == IN_CL_INTERFACE)
&& (Setup.wValue.i == 0) )
{
Ep_Status0 = EP_TX; // Put endpoint in transmit mode
DataPtr = (BYTE *)cs_temp_buffer;
DataSize = 0; // Send ZLP
setup_handled = TRUE;
}
}
//-----------------------------------------------------------------------------
// Set_Line_Coding
//-----------------------------------------------------------------------------
//
// Unload the line coding structure (7 bytes) sent in the data stage.
// Apply this setting to the UART
// Flush the communication buffer
//
// Line Coding Structure (7 bytes)
// 0-3 dwDTERate Data terminal rate (baudrate), in bits per second (LSB first)
// 4 bCharFormat Stop bits: 0 - 1 Stop bit, 1 - 1.5 Stop bits, 2 - 2 Stop bits
// 5 bParityType Parity: 0 - None, 1 - Odd, 2 - Even, 3 - Mark, 4 - Space
// 6 bDataBits Data bits: 5, 6, 7, 8, 16
//
//-----------------------------------------------------------------------------
void CS_Set_Line_Coding(void)
{
if ( (Setup.bmRequestType == OUT_CL_INTERFACE)
&& (Setup.wValue.i == 0)
&& (Setup.wLength.i == sizeof(TLine_Coding)) )
{
Ep_Status0 = EP_RX; // Put endpoint in recieve mode
DataPtr = (BYTE *)cs_temp_buffer;
DataSize = sizeof(TLine_Coding); // Read out the command sent
USB_request_callback = CS_Set_Line_Coding_Complete;
setup_handled = TRUE;
}
}
// called at the end of data stage
bit CS_Set_Line_Coding_Complete(void)
{
#if defined BIG_ENDIAN
// swap baudrate field LSB first --> MSB first
swap_endian_long( (ULONG idata *)cs_temp_buffer );
#endif // end of BIG_ENDIAN
return Set_Line_Coding( (TLine_Coding idata *)cs_temp_buffer );
}
//-----------------------------------------------------------------------------
// Get_Line_Coding
//-----------------------------------------------------------------------------
//
// Return the line coding structure
//
//-----------------------------------------------------------------------------
void CS_Get_Line_Coding(void)
{
if ( (Setup.bmRequestType == IN_CL_INTERFACE)
&& (Setup.wValue.i == 0)
&& (Setup.wLength.i == sizeof(TLine_Coding)) )
{
#if defined BIG_ENDIAN
BYTE cnt;
BYTE idata * dst;
BYTE idata * src;
dst = cs_temp_buffer; // copy line coding structure
src = (BYTE idata *)&uart_line_coding;
for (cnt = sizeof( TLine_Coding ); cnt > 0; cnt--)
*dst++ = *src++;
swap_endian_long( (ULONG idata *)cs_temp_buffer );
DataPtr = (BYTE *)cs_temp_buffer;
#else
DataPtr = (BYTE *)(&uart_line_coding); // send it directly
#endif // end of BIG_ENDIAN
Ep_Status0 = EP_TX; // Put endpoint in transmit mode
DataSize = sizeof(TLine_Coding); // Send Line coding
setup_handled = TRUE;
}
}
//-----------------------------------------------------------------------------
// Set_ControlLine_State
//-----------------------------------------------------------------------------
//
// Set/reset RTS/DTR according to wValue
// wValue
// bit 1 RTS
// bit 0 DTR
//
//-----------------------------------------------------------------------------
void CS_Set_ControlLine_State(void)
{
if ( (Setup.bmRequestType == OUT_CL_INTERFACE)
&& (Setup.wLength.i == 0) )
{
Set_Line_State( Setup.wValue.c[LSB] & (CDC_RTS | CDC_DTR ) );
setup_handled = TRUE;
}
}
//-----------------------------------------------------------------------------
// Send_Break
//-----------------------------------------------------------------------------
//
// Send break from UART TX port, for wValue (msec) duration.
// wValue
// 0xFFFF: continuous break
// 0x0000: stop break
//
//-----------------------------------------------------------------------------
void CS_Send_Break(void)
{
if ( (Setup.bmRequestType == OUT_CL_INTERFACE)
&& (Setup.wLength.i == 0) )
{
Send_Break( Setup.wValue.i );
setup_handled = TRUE;
}
}
//-----------------------------------------------------------------------------
// swap_endian_long
//-----------------------------------------------------------------------------
// swap endian for long varialbe
//-----------------------------------------------------------------------------
#if defined BIG_ENDIAN
void swap_endian_long( ULONG idata *lptr )
{
BYTE tmp[4];
BYTE idata * ptr = (BYTE idata *)lptr;
tmp[3] = ptr[0];
tmp[2] = ptr[1];
tmp[1] = ptr[2];
tmp[0] = ptr[3];
ptr[0] = tmp[0];
ptr[1] = tmp[1];
ptr[2] = tmp[2];
ptr[3] = tmp[3];
}
#endif // end of BIG_ENDIAN
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -