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

📄 usbstd.c

📁 usb driver, sample for usb driver develop. rised for reference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
* C Source File:  USBStd.C
*
* Copyright 2001 DeVaSys
* All rights are reserved.
* No part of this document may be reproduced, stored, or transmitted in any
* form or by any means without the prior written permission of DeVaSys
*
* Description:
*
* This module provides support for handling standard USB requests.
*
* ........................ Revision History ................................
*
* Creation date: 02/22/2001 - Michael A. DeVault, DeVaSys
*
* Revision History Summary:
*
* Rev 1.0   22 February 2001 12:00:00   mad
*   Initial revision.
*
***************************************************************************/
#include "usbstd.h"
#include "usbdesc.h"
#include "usbrpt.h"
#include "usbd11.h"
#include "i2c.h"
#include <stdio.h>

#define USB_UNUSED_IRQ_MASK								0xF37F

#define USB_HID_REQUEST_GET_REPORT		0x01
#define USB_HID_REQUEST_GET_IDLE			0x02
#define USB_HID_REQUEST_GET_PROTOCOL	0x03
#define USB_HID_REQUEST_SET_REPORT		0x09
#define USB_HID_REQUEST_SET_IDLE			0x0A
#define USB_HID_REQUEST_SET_PROTOCOL	0x0B

BYTE CtlDataRdBuf[8];

BYTE byUsbAddress = 0x00;
BYTE byUsbConfig = 0x00;
BYTE byUsbInterface = 0x00;
BYTE byUsbAltInterface = 0x00;
BOOL bProtocol = 0x01;

BYTE byTxCtl = 0;
BYTE byTxCtlCnt = 0;
BYTE * pbyTxCtl;

BOOL bRxCtl = 0;
BYTE byRxCtlCnt = 0;
BYTE * pbyRxCtl;

// local functions
void USB_ProcIrq(WORD wIrq);
void USB_CtlRxSetup(void);
void USB_CtlRxData(void);
void USB_CtlTx(WORD byReqCnt, WORD wActCnt);

// request handler functons
void StdDevReqHdlr(PUSB_REQUEST pSetupPkt);
void StdIntReqHdlr(PUSB_REQUEST pSetupPkt);
void StdEndReqHdlr(PUSB_REQUEST pSetupPkt);
void ClsIntReqHdlr(PUSB_REQUEST pSetupPkt);
void UsbUnspReqHdlr(PUSB_REQUEST pSetupPkt);
void StdDev_GetStatus(void);
void StdDev_GetDescr(PUSB_REQUEST pSetupPkt);
void StdDev_SetAddress(PUSB_REQUEST pSetupPkt);
void StdDev_SetConfig(PUSB_REQUEST pSetupPkt);
void StdInt_GetStatus(void);
void StdInt_GetDescr(PUSB_REQUEST pSetupPkt);
void StdInt_GetInt(PUSB_REQUEST pSetupPkt);
void StdInt_SetInterface(PUSB_REQUEST pSetupPkt);
void StdEnd_GetStatus(PUSB_REQUEST pSetupPkt);
void StdEnd_ClrFeature(PUSB_REQUEST pSetupPkt);
void StdEnd_SetFeature(PUSB_REQUEST pSetupPkt);
void ClsInt_GetReport(PUSB_REQUEST pSetupPkt);
void ClsInt_GetIdle(PUSB_REQUEST pSetupPkt);
void ClsInt_GetProtocol(void);
void ClsInt_SetReport(PUSB_REQUEST pSetupPkt);
void ClsInt_SetIdle(PUSB_REQUEST pSetupPkt);

void USB_Init(void) {

	// zero variables
	byTxCtl = 0;
	byTxCtlCnt = 0;
	byUsbAddress = 0x80;
	byUsbConfig = 0x00;
	byUsbInterface = 0x00;
	byUsbAltInterface = 0x00;

	D11_CfgInit();

	D11_WrEp(D11_EP1IN_IDX, (BYTE*)&RptMouse, sizeof(RptMouse));	// write report
}

void USB_Clear(void) {
	D11_CfgClr();
}

BYTE USB_ChkIrq(void) {

	WORD wIrq;
	BYTE byRetVal = 0;

   WaitForInterrupt();

	wIrq = D11_GetIrq();
	while(wIrq) {    								/* Keep reading and processing IRQs in queue */
    	printf("\n wIrq = 0x%04x ",wIrq);    /* until all have been processed */
		USB_ProcIrq(wIrq);
		wIrq = D11_GetIrq();
		byRetVal++;
	}
	return byRetVal;
}

void USB_ProcIrq(WORD wIrq) {

	BYTE byLtStat;

	if(wIrq & D11_INT_BUSRESET) {
		/* Bus Reset Occured - Highest Priority */
		printf(" A bus reset occured - Reinitalising PDIUSBD11\n\n");
		USB_Init();
	}
	else {

		if(wIrq & D11_INT_EP0OUT) {
			printf(" Irq - Ep0_Out (EpIdx2)");
         /* Endpoint Zero - Check if packet is Setup or Data */
			byLtStat = D11_GetLtStat(D11_EP0OUT_IDX);
			if(byLtStat & D11_LTSTAT_SETUP) USB_CtlRxSetup();
			else                            USB_CtlRxData();
		}

		if(wIrq & D11_INT_EP0IN) {
			// Ep0 In
			printf(" Irq - Ep0_In  (EpIdx3)");
			if(byTxCtl==2) { /* Interrupt Set Address */
				D11_CmdDataI2C(D11_CMD_SET_ADDRESS, &byUsbAddress, 1, WR_DATA);
				byLtStat = D11_GetLtStat(D11_EP0IN_IDX);
				printf(" Set Device Address %x", byUsbAddress);
				byTxCtl = 0;
			}
			else if(byTxCtl) {
				byLtStat = D11_GetLtStat(D11_EP0IN_IDX);
					if(byTxCtlCnt >= 8) {
               printf(" %d Sending packet of 8 bytes p=0x%X",byTxCtlCnt, pbyTxCtl);
					// Tx Next 8 bytes
					D11_WrEp(D11_EP0IN_IDX, pbyTxCtl, 8);
					pbyTxCtl+=8;
					byTxCtlCnt-=8;
				}
				else if(byTxCtlCnt == 0) {
					// Tx Null Termination packet
               printf(" Sending Null Termination Packet ");
					D11_TxNull(D11_EP0IN_IDX);
					byTxCtl = 0;
				}
				else {
					// Tx byTxCnt bytes (less than 8, more than 0)
               printf(" Sending last %d bytes at p=0x%x",byTxCtlCnt, pbyTxCtl);
					D11_WrEp(D11_EP0IN_IDX, pbyTxCtl, byTxCtlCnt);
					byTxCtl = 0;
				}
			}
			else {
				// end of transmission, status cycle
            byLtStat = D11_GetLtStat(D11_EP0IN_IDX);
            printf(" End of Transmission, Getting Status Byte %x",byLtStat);
			}
		}

		if(wIrq & USB_UNUSED_IRQ_MASK) {
			// activity on unused endpoint, clear irq
			if(wIrq & D11_INT_EP1IN) {
				// Ep1 In
				printf(" Irq - Ep1_In  (EpIdx4)");
				D11_CmdDataI2C(D11_CMD_GET_LTSTAT+D11_EP1IN_IDX,
				 &byLtStat, 1, RD_DATA);
				bLastReportRead = 1; // hid report last read
			}
			if(wIrq & D11_INT_EP1OUT) {
				// Ep1 Out
				printf(" Irq - Ep1_Out (EpIdx5)");
				D11_CmdDataI2C(D11_CMD_GET_LTSTAT+D11_EP1OUT_IDX,
				 &byLtStat, 1, RD_DATA);
			}
			if(wIrq & D11_INT_EP2IN) {
				// Ep2 In
				printf(" Irq - Ep2_In  (EpIdx7)");
				D11_CmdDataI2C(D11_CMD_GET_LTSTAT+D11_EP2IN_IDX,
				 &byLtStat, 1, RD_DATA);
			}
			if(wIrq & D11_INT_EP2OUT) {
				// Ep2 Out
				printf(" Irq - Ep2_Out (EpIdx6)");
				D11_CmdDataI2C(D11_CMD_GET_LTSTAT+D11_EP2OUT_IDX,
				 &byLtStat, 1, RD_DATA);
			}
			if(wIrq & D11_INT_EP3IN) {
				// Ep3 In
				printf(" Irq - Ep3_In  (EpIdx9)");
				D11_CmdDataI2C(D11_CMD_GET_LTSTAT+D11_EP3IN_IDX,
             &byLtStat, 1, RD_DATA);
			}
			if(wIrq & D11_INT_EP3OUT) {
				// Ep3 Out
				printf(" Irq - Ep3_Out (EpIdx8)");
				D11_CmdDataI2C(D11_CMD_GET_LTSTAT+D11_EP3OUT_IDX,
             &byLtStat, 1, RD_DATA);
			}
		}
	}
}

void USB_CtlRxSetup(void) {
	// Processes a received setup packet

	USB_REQUEST SetupPkt;
	BYTE bySelector;

	// abort any control transfers on receipt of setup packet
	byTxCtl = 0;
	byTxCtlCnt = 0;
	bRxCtl = 0;
	byRxCtlCnt = 0;

	// transfer the 8 byte Setup packet from the Control OUT endpoint to memory
	D11_RdEp((BYTE*)&SetupPkt, D11_EP0OUT_IDX);

	D11_AckSetup();						// special ACK required for setup

#ifdef __BIGENDIAN__
	SetupPkt.wValue = SWAPWORD(SetupPkt.wValue);
	SetupPkt.wIndex = SWAPWORD(SetupPkt.wIndex);
	SetupPkt.wLength = SWAPWORD(SetupPkt.wLength);
#endif

	//	x00x xxXX		valid Standard request type and recepients
	//	x01x xx01		valid Class request type and recepient for HID class
	//	x10x xxuu		valid Vendor request type and recepient
	//
	// we can use certain bits of the bmRequestType to construct a nice
	// selector value for processing the request
	bySelector = ( (SetupPkt.byReqType & 0x60) >>3 );
	bySelector |= ( SetupPkt.byReqType & 0x03);

	// analyze request using fast selector
	// good compilers will turn this into a jump table
	switch(bySelector) {
		case 0x00:
			// Standard Device request
			StdDevReqHdlr(&SetupPkt);
			break;
		case 0x01:
			// Standard Interface request
			StdIntReqHdlr(&SetupPkt);
			break;
		case 0x02:
			// Standard Endpoint request
			StdEndReqHdlr(&SetupPkt);
			break;
		case 0x03:
			// Standard Other or Reserved requests (unsupported)
			// fall through on purpose
		case 0x04:
			// Class Device request (unsupported)
			UsbUnspReqHdlr(&SetupPkt);
			break;
		case 0x05:
			// Class Interface request
			ClsIntReqHdlr(&SetupPkt);
			break;
		default:
			UsbUnspReqHdlr(&SetupPkt);
			// Class endpoint or other request
			// or Vendor requests
			// or Reserved requests (unsupported)
	}
}

void StdDevReqHdlr(PUSB_REQUEST pSetupPkt) {
	// Standard Device request

	printf(" Standard Device request - ");

	// call correct handler using jumptable and 4 bit selector

	// determine request
	switch(pSetupPkt->byRequest) {
		case USB_REQUEST_GET_STATUS:
			printf("Get Status ");
			StdDev_GetStatus();
			break;
		case USB_REQUEST_GET_DESCRIPTOR:
			printf("Get Descriptor ");
			StdDev_GetDescr(pSetupPkt);
			break;
		case USB_REQUEST_GET_CONFIGURATION:
			printf("Get Configuration ");
			D11_WrEp(D11_EP0IN_IDX, &byUsbConfig, 1);
			break;
		/* case USB_REQUEST_CLEAR_FEATURE:
			DbgWrStr("Clear Feature\n",1);
			StdDev_ClrFeature(pSetupPkt);
			break; */
		case USB_REQUEST_SET_FEATURE:
			printf("Set Feature ");
			D11_TxNull(D11_EP0IN_IDX);			// Send TxNull Packet
			break;
		case USB_REQUEST_SET_ADDRESS:
			printf("Set Address ");
			byUsbAddress = (LOBYTE(pSetupPkt->wValue) | 0x80);
			byTxCtl = 2;							// setup to set address next interrupt
			D11_TxNull(D11_EP0IN_IDX);			// Send TxNull Packet
			break;
//		case USB_REQUEST_SET_DESCRIPTOR:
//			DbgWrStr("Set Descriptor\n",1);
//			StdDev_SetDescr(pSetupPkt);
//			break;
		case USB_REQUEST_SET_CONFIGURATION:
			printf("Set Configuration ");
			StdDev_SetConfig(pSetupPkt);
			break;
		default:
			// Unsupported Request
			UsbUnspReqHdlr(pSetupPkt);
			break;
	}
}

void StdIntReqHdlr(PUSB_REQUEST pSetupPkt) {
	// Standard Interface request

	printf(" Standard Interface request - ");

	switch(pSetupPkt->byRequest) {
		case USB_REQUEST_GET_STATUS:
			printf("Get Status ");
			StdInt_GetStatus();
			break;
		case USB_REQUEST_GET_DESCRIPTOR:
			printf("Get Descriptor ");
			StdInt_GetDescr(pSetupPkt);
			break;
		case USB_REQUEST_GET_INTERFACE:
			printf("Get Interface ");
			StdInt_GetInt(pSetupPkt);
			break;
//		case USB_REQUEST_CLEAR_FEATURE:
//			DbgWrStr("Clear Feature\n",1);
//			StdInt_ClrFeature(pSetupPkt);
//			break;
		case USB_REQUEST_SET_FEATURE:
			printf("Set Feature ");
			D11_TxNull(D11_EP0IN_IDX);			// TxNull Packet
			break;
		case USB_REQUEST_SET_INTERFACE:
			printf("Set Interface ");
			StdInt_SetInterface(pSetupPkt);
			break;
		default:
			// Unsupported Request
         printf("Unsupported Request %X ",pSetupPkt->byRequest);
			UsbUnspReqHdlr(pSetupPkt);
			break;
	}
}

void StdEndReqHdlr(PUSB_REQUEST pSetupPkt) {

	printf(" Standard Endpoint request - ");

	switch(pSetupPkt->byRequest) {
		case USB_REQUEST_GET_STATUS:
			printf("Status ");
			StdEnd_GetStatus(pSetupPkt);
			break;
//		case USB_REQUEST_SYNC_FRAME:
//			DbgWrStr("Sync Frame\n",1);
//			StdEnd_SyncFrame(pSetupPkt);
//			break;
		case USB_REQUEST_CLEAR_FEATURE:
			printf("Clear Feature ");
			StdEnd_ClrFeature(pSetupPkt);
			break;
		case USB_REQUEST_SET_FEATURE:
			printf("Set Feature ");
			StdEnd_SetFeature(pSetupPkt);
			break;
		default:
			// Unsupported Request
			UsbUnspReqHdlr(pSetupPkt);
			break;
	}
}

void ClsIntReqHdlr(PUSB_REQUEST pSetupPkt) {

	printf(" Class Interface request - ");

	switch(pSetupPkt->byRequest) {
		case USB_HID_REQUEST_GET_REPORT:
			printf("Report ");
			ClsInt_GetReport(pSetupPkt);
			break;
		case USB_HID_REQUEST_GET_IDLE:
			printf("Idle ");
			ClsInt_GetIdle(pSetupPkt);
			break;
		case USB_HID_REQUEST_GET_PROTOCOL:
			printf("Protocol ");
			ClsInt_GetProtocol();
			break;
		case USB_HID_REQUEST_SET_REPORT:
			printf("Report ");
			ClsInt_SetReport(pSetupPkt);
			break;
		case USB_HID_REQUEST_SET_IDLE:
			printf("Idle ");
			ClsInt_SetIdle(pSetupPkt);
			break;
		case USB_HID_REQUEST_SET_PROTOCOL:
			printf("Protocol ");
			bProtocol = (BOOL)LOBYTE(pSetupPkt->wValue);
			D11_TxNull(D11_EP0IN_IDX);			// TxNull Packet
			break;
		default:
			// Unsupported Request
			UsbUnspReqHdlr(pSetupPkt);
			break;
	}
}

void UsbUnspReqHdlr(PUSB_REQUEST pSetupPkt) {
	// unsupported request handler
}

void StdDev_SetConfig(PUSB_REQUEST pSetupPkt) {

   printf(" Setup - Set Standard Device Configuration %x ",pSetupPkt->wValue);

	// in configured state value must be a valid configuration #
	if( LOBYTE(pSetupPkt->wValue) ) {
		// set current configuration
		byUsbConfig = LOBYTE(pSetupPkt->wValue);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -