?? fw2hid.c
字號:
//-----------------------------------------------------------------------------
// File: fw2HID.c (fw.c modified by LTH on 20-Aug-01
// Contents: Firmware frameworks task dispatcher and device request parser
// source.
//
// Copyright (c) 2001 Cypress Semiconductor, Inc. All rights reserved
//-----------------------------------------------------------------------------
#include "ezusb.h"
#include "ezregs.h"
//-----------------------------------------------------------------------------
// Macros
//-----------------------------------------------------------------------------
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
#define bmRequestType 0
#define bRequest 1
#define wValueL 2
#define wValueH 3
#define wIndexL 4
#define wIndexH 5
#define wLengthL 6
#define wLengthH 7
//
#define GET_REPORT 0x01 // HID Request Types
#define SET_REPORT 0x09
#define GET_IDLE 0x02
#define SET_IDLE 0x0A
//
#define rt_INPUT 1 // HID report types
#define rt_OUTPUT 2
#define rt_FEATURE 3 // all others are 'reserved'
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
//volatile BOOL GotSUD; // set by SUDAV ISR
//volatile BOOL Sleep; // Sleep mode enable flag
BOOL GotSUD; // set by SUDAV ISR
BOOL Sleep; // Sleep mode enable flag
BOOL Rwuen;
BOOL Selfpwr;
BYTE IdleRate;
//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
void SetupCommand(void);
void TD_Init(void);
void TD_Poll(void);
BOOL TD_Suspend(void);
BOOL TD_Resume(void);
BOOL DR_SetConfiguration(void);
BOOL DR_GetConfiguration(void);
BOOL DR_SetInterface(void);
BOOL DR_GetInterface(void);
BOOL DR_GetStatus(void);
BOOL DR_ClearFeature(void);
BOOL DR_SetFeature(void);
void process_standard_request(void);
void process_class_request(void);
void process_descriptor(void);
//-----------------------------------------------------------------------------
// Descriptors
//-----------------------------------------------------------------------------
extern code DeviceDescr,ConfigDescr,String0,String1,String2,HIDDescr;
extern code ReportDescr,ReportDescr_end;
//-----------------------------------------------------------------------------
// Code
//-----------------------------------------------------------------------------
// Task dispatcher
void main(void) // power-on reset takes us here
{
// Initialize Global States
Sleep = FALSE; // Disable sleep mode
Rwuen = FALSE; // Disable remote wakeup
Selfpwr = FALSE; // Disable self powered
GotSUD = FALSE; // Clear "Got setup data" flag
// Initialize user device
TD_Init();
EZUSB_IRQ_ENABLE(); // Enable USB interrupt (INT2)
EZUSB_ENABLE_RSMIRQ(); // Wake-up interrupt
PORTCCFG |= 0xc0; // Turn on r/w lines for external memory (Keil monitor)
USBBAV = USBBAV | 1 & ~bmBREAK; // Disable breakpoints and ENABLE autovectoring
USBIEN |= bmSUDAV | bmSUSP | bmURES; // Enable selected interrupts
EA = 1; // Enable 8051 interrupts
EZUSB_Discon(TRUE); // ReNumerate
// Task Dispatcher
while(TRUE) // Main Loop
{
if(GotSUD) // Wait for SUDAV
{
SetupCommand(); // Service the SETUP request
GotSUD = FALSE; // Clear SUDAV flag--NOTE: clearing GotSUD after calling SetupCommand()
} // properly handles multi-packet Get_Descriptor_Report requests
// (which would generate multiple SUDAV interrupts).
if (Sleep) // set to TRUE by the SUSPEND ISR
{
if(TD_Suspend()) // hook in periph.c to do stuff before suspending
{
Sleep = FALSE; // Clear the "go to sleep" flag. Do it here to prevent any race condition between wakeup and the next sleep.
do
{
EZUSB_Susp(); // Place processor in idle mode.
}
while(!Rwuen && EZUSB_EXTWAKEUP());
// Must continue to go back into suspend if the host has disabled remote wakeup
// *and* the wakeup was caused by the external wakeup pin.
// 8051 activity will resume here due to USB bus or Wakeup# pin activity.
EZUSB_Resume(); // If source is the Wakeup# pin, signal the host to Resume.
TD_Resume();
}
}
TD_Poll();
} // end while(TRUE)
}
// Device request parser
void SetupCommand(void)
{
switch(SETUPDAT[bmRequestType] & 0x60) // 00-std,20-class,40-vendor,60-reserved.
{
case SETUP_STANDARD_REQUEST:
process_standard_request();
break;
case SETUP_CLASS_REQUEST:
process_class_request();
break;
default:
EZUSB_STALL_EP0(); // we don't handle SETUP_VENDOR_REQUEST or "Reserved".
}
EP0CS = bmHS; // Clear the HS-NAK bit by writing '1' to it
}
void process_standard_request(void)
{
switch(SETUPDAT[bRequest])
{
case SC_GET_DESCRIPTOR: // *** Get Descriptor
process_descriptor();
break;
case SC_GET_INTERFACE: // *** Get Interface
DR_GetInterface();
break;
case SC_SET_INTERFACE: // *** Set Interface
DR_SetInterface();
break;
case SC_SET_CONFIGURATION: // *** Set Configuration
DR_SetConfiguration();
break;
case SC_GET_CONFIGURATION: // *** Get Configuration
DR_GetConfiguration();
break;
case SC_GET_STATUS: // *** Get Status
if(DR_GetStatus())
switch(SETUPDAT[bmRequestType])
{
case GS_DEVICE: // Device
IN0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr;
IN0BUF[1] = 0;
EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
break;
case GS_INTERFACE: // Interface
IN0BUF[0] = 0;
IN0BUF[1] = 0;
EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
break;
case GS_ENDPOINT: // End Point
IN0BUF[0] = EPIO[EPID(SETUPDAT[wIndexL])].cntrl & bmEPSTALL;
IN0BUF[1] = 0;
EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
break;
default: // Invalid Command
EZUSB_STALL_EP0();
}
break;
case SC_CLEAR_FEATURE: // *** Clear Feature
if(DR_ClearFeature())
switch(SETUPDAT[bmRequestType])
{
case FT_DEVICE: // Device
if(SETUPDAT[wValueL] == 1)
Rwuen = FALSE; // Disable Remote Wakeup
else
EZUSB_STALL_EP0(); // we only recognize '1'
break;
case FT_ENDPOINT: // End Point
if(SETUPDAT[wValueL] == 0)
{
EZUSB_UNSTALL_EP(EPID(SETUPDAT[wIndexL]));
EZUSB_RESET_DATA_TOGGLE(SETUPDAT[wIndexL]);
}
else
EZUSB_STALL_EP0();
break;
}
break;
case SC_SET_FEATURE: // *** Set Feature
if(DR_SetFeature())
switch(SETUPDAT[bmRequestType])
{
case FT_DEVICE: // Device
if(SETUPDAT[wValueL] == 1)
Rwuen = TRUE; // Enable Remote Wakeup
else
EZUSB_STALL_EP0();
break;
case FT_ENDPOINT: // End Point
if(SETUPDAT[wValueL] == 0)
EZUSB_STALL_EP( EPID(SETUPDAT[wIndexL]) );
else
EZUSB_STALL_EP0();
break;
}
break;
default: // *** Invalid Command
EZUSB_STALL_EP0();
} // end switch
} // end process_request()
void process_descriptor()
{
unsigned int j,k,ReportSize;
switch(SETUPDAT[wValueH])
{
case GD_DEVICE: // Device
SUDPTRH = MSB(&DeviceDescr);
SUDPTRL = LSB(&DeviceDescr);
break;
case GD_CONFIGURATION: // Configuration
SUDPTRH = MSB(&ConfigDescr);
SUDPTRL = LSB(&ConfigDescr);
break;
case GD_STRING: // String
{
switch(SETUPDAT[wValueL])
{
case 0: // string index 1
SUDPTRH = MSB(&String0);
SUDPTRL = LSB(&String0);
break;
case 1: // string index 1
SUDPTRH = MSB(&String1);
SUDPTRL = LSB(&String1);
break;
case 2: // string index 2
SUDPTRH = MSB(&String2);
SUDPTRL = LSB(&String2);
break;
default: // Invalid string requested
EZUSB_STALL_EP0();
} // end switch
} // end case
break;
case GD_HID: // Get-Descriptor: HID
SUDPTRH = MSB(&HIDDescr);
SUDPTRL = LSB(&HIDDescr);
break;
case GD_REPORT: // Get-Descriptor: Report
/*
Note: A HID report does not have a length field which the SIE can read to determine how many
bytes to send using the Setup Data Pointer. Therefore we need to 'manually' send the data.
*/
ReportSize = (WORD)&ReportDescr_end - (WORD)&ReportDescr;
AUTOPTRH = MSB(&ReportDescr);
AUTOPTRL = LSB(&ReportDescr);
while(ReportSize)
{
k = min(ReportSize,64); // smaller of ReportSize or IN0 Buffer (64 bytes)
for(j=0;j<k;j++)
IN0BUF[j]=AUTODATA;
IN0BC = j; // arm the IN transfer
ReportSize = ReportSize-j;
while(EP0CS & bmIN); // wait for it to go out and get ACK'd
}
break;
default: // *** Invalid Command
EZUSB_STALL_EP0();
} // end switch
} // end function
void process_class_request(void) // Handle the HID class
{
switch(SETUPDAT[bRequest])
{
case SET_REPORT:
switch(SETUPDAT[wValueH]) // wValueH has report type
{
case rt_INPUT:
break;
case rt_OUTPUT:
break;
case rt_FEATURE:
break;
default:
EZUSB_STALL_EP0();
}
break;
case GET_REPORT:
switch(SETUPDAT[wValueH]) // wValueH has report type
{
case rt_INPUT:
break;
case rt_OUTPUT:
break;
case rt_FEATURE:
break;
default:
EZUSB_STALL_EP0();
}
break;
case SET_IDLE:
IdleRate = SETUPDAT[wValueH];
break;
case GET_IDLE:
IN0BUF[0]=IdleRate;
IN0BC = 1; // arm the IN transfer
break;
default:
EZUSB_STALL_EP0(); // this includes 'GET/SET_PROTOCOL'
} // end switch
}
void resume_isr(void) interrupt WKUP_VECT // Wakeup interrupt handler
{
EZUSB_CLEAR_RSMIRQ();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -