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

📄 usb_class_requests.c

📁 USB CDC using C8051F320/340, virtual COM port thru usb connection
💻 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 + -