📄 usb.c
字号:
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
/* This is the source code for a sample USBN9602 firmware implemen- */
/* tation. This firmware is capable of all USB "Chapter 9" */
/* required functions, as well as HID class functionality. */
/* */
/* Written by Jim Lyle. (408) 721-7772 jim.lyle@nsc.com */
/* */
/* Copyright (c) 1997, 1998, National Semiconductor. All rights */
/* reserved. No warranties, expressed or implied. */
/* */
/* VERSION 0A.00, Feb 28, 1998, Jim Lyle: Revision control begins. */
/* This version contains significant modifications over previous */
/* revisions, including HID class capabilities, and restructuring */
/* to enhance code portability. */
/* */
/* VERSION 0A.10, Apr 15, 1998, Jim Lyle: Support included for COP8, */
/* 80C188EB, and MC68HC11 microprocessors. Additional enhancements*/
/* to enhance code portability. */
/* */
/* VERSION 0A.11, Apr 17, 1998, Jim Lyle: Added the VREG_ON test to */
/* determine the proper state for the VGE bit in the MCNTRL reg. */
/* Note that REV_ID in the descriptor is incorrectly set to 1.01 */
/* for this version. */
/* */
/* VERSION 0A.20, May 15, 1998, Jim Lyle: set_address sequence mod- */
/* ified so that it will work when issued from other than the */
/* default address (supports multiple set_address sequences after */
/* a single reset). Also added SET_INTERFACE and GET_INTERFACE */
/* standard requests. */
/* */
/* VERSION 0A.21, Jul 18, 1998, Jim Lyle: modified descriptors to */
/* report max power in bus-powered mode. Also modified the */
/* langid array to report US english (0409) instead of just */
/* english (0009). This enables windows to show our strings */
/* when loading the drivers. */
/* */
/* VERSION 0A.30, Aug 25, 1998, Jim Lyle: added a more complete */
/* implementation of the SET_IDLE and GET_IDLE commands, to */
/* satisfy the new version of HIDview. */
/* */
/* VERSION 0A.31, Sep 22, 1998, Jim Lyle: added (optional) support */
/* for bus-powered applications. */
/* */
/* VERSION 0A.40, Oct 16, 1998, Jim Lyle: corrected index errors in */
/* the following commands: SET_FEATURE, CLEAR_FEATURE, GET_STATUS. */
/* The buffer index used was usb_buf[3], but has been changed to */
/* usb_buf[4]. Also, the OS seems to include the "direction" bit */
/* in the address (e.g. 0x85 instead of 0x05 if endpoint 5 is an */
/* IN endpoint), so this has to be stripped. */
/* */
/* VERSION 0A.41, Jan 20, 2000, Ernest Bron Added 9603 support */
/* Corrected descriptor string to return 9603 instead of 9602 */
/* Changed optional buspower scheme to take advantage of new */
/* power down features in the 9603. */
/* */
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
/* COMPILE INSTRUCTIONS */
/* */
/* 1) Select processor type by updating the associated #define state-*/
/*ment below: i.e. '#define X86 TRUE' for 80C188EB. */
/* */
/* 2) Compile and link code using the compiler specific instructions */
/*that follow: */
/* */
/**********************************************************************/
/* COP8 */
/* */
/* 1) Use the COP8C compiler available from Bytecraft (Canada) */
/* (519) 888-6911. Invoke as follows: */
/* */
/* cop8c usb +l */
/* */
/* 2) Upload the USB.COD file to the Debug Module or EPU per the */
/* manufacturer's instructions. */
/* */
/**********************************************************************/
/* X86 */
/* */
/* 1) Use the Borland TURBO C compiler, adjusting the 'Directories' */
/* option to begin with the path to the modified 'C0' libraries. */
/* */
/* Start the IDE and open the file USB.C, then build it. */
/* */
/* */
/* 2) The resulting USB.EXE file needs to be translated into a pure */
/* memory image (relocatable entries need to be hard-wired at */
/* this time). Use the LOCATE shareware and invoke as follows: */
/* */
/* locate /I:usb.exe /O:usb.brn /@:0100 /N */
/* */
/* 3) Upload the USB.BRN file to the target board per the manufact- */
/* urer's instructions, or if using the MMT188 board then use */
/* the MULTITRM shareware as follows: */
/* */
/* a) Issue the 'H' command to enter the download mode (specify */
/* segment 0100). */
/* */
/* b) Hit F8, then enter the file name (USB.BRN). */
/* */
/* c) Issue the 'G0100:0000' command to begin execution. */
/* */
/**********************************************************************/
/* HC11 */
/* */
/* 1) Use the ICC11 compiler available from Imagecraft (USA) */
/* (650) 493-9326. Invoke as follows: */
/* */
/* icc11 -l -v -e -dinit_sp:0x7FFF -btext:0xC000 -bdata:0x0000 */
/* */
/* If necessary, also include the -L option to specify the lib */
/* directory included with the compiler */
/* */
/* 2) Upload the USB.S19 file to the target board per the manufact- */
/* urer's instructions, or if using the BUFFALO board then use */
/* the MULTITRM shareware as follows: */
/* */
/* a) Issue the 'LOAD T' command to enter the download mode. */
/* */
/* b) Hit F8, then enter the file name (USB.S19). */
/* */
/* c) Issue the 'G C000' command to begin execution. */
/* */
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
typedef unsigned char byte;
#define FALSE 0
#define TRUE -1
#include "defusb.h" /*include USB defines */
#include "def9602.h" /*include 9602 defines */
/**********************************************************************/
/***** MODIFY THIS LINE FOR SPECIFIC PROCESSOR TARGET *****************/
/**********************************************************************/
#define COP8 TRUE /*SELECT PROCESSOR HERE */
/*valid choices are: */
/* COP8 */
/* X86 */
/* HC11 */
/**********************************************************************/
#ifdef COP8
/* include this line if compiling for bus powered operation */
/* #define BUSPOWER TRUE */
#ifdef BUSPOWER
#define VREG_ON TRUE /*use the regulator */
#endif
#include "defcop8.h" /*source in the COP8 defs */
#endif
#ifdef X86
#include "defx86.h" /*source in the X86 defs */
#endif
#ifdef HC11
#include "defhc11.h" /*source in the HC11 defs */
#endif
/* if the 9602's voltage regulator needs to be turned on, define a */
/* constant named 'VREG_ON'. Otherwise, the voltage regulator will */
/* remain off, and an external 3.3 Volt source is assumed. */
#ifdef VREG_ON
#define VREG_ST VGE
#else
#define VREG_ST 0
#endif
/**********************************************************************/
/* Message related values */
/**********************************************************************/
/* Command message constants */
#define SYNCBYT 0xAA /*sync code expected */
#define MAJREV 'A' /*major revision */
#define MINREV 40 /*minor revision */
/**********************************************************************/
/* These are system independent macros and defines */
/**********************************************************************/
#define HIBYT(x) (x)/256
#define LOBYT(x) (x)%256
#define NORMAL_ALTMSK SD3+RESET_A /*ALTMSK if not in suspend*/
#define SUSPND_ALTMSK RESUME_A+RESET_A /*ALTMSK if in suspend */
/* Enforce a minimum time period active before suspending to make sure*/
/* that the board is detected at power on and restart. The value here*/
/* corresponds to the minimum number of time periods between suspend */
/* events. At half-second intervals, the value here equals 2 seconds */
#define SUSPND_TO 4
/* store the status byte in FIFO0 for the chosen endpoint *************/
#define EPSTATUS(epbit) if(TSTBIT(stalld,epbit)) write_usb(TXD0,1); \
else write_usb(TXD0,0); break;
/* Flush and disable the USB TX0 **************************************/
#define FLUSHTX0 {write_usb(TXC0,FLUSH);}
/* Flush and disable the USB TX1 **************************************/
#define FLUSHTX1 {write_usb(TXC1,FLUSH);}
/* Flush and disable the USB TX2 **************************************/
#define FLUSHTX2 {write_usb(TXC2,FLUSH);}
/* Flush and disable the USB TX3 **************************************/
#define FLUSHTX3 {write_usb(TXC3,FLUSH); CLRBIT(status,RPTBUSY);}
/* Flush and disable the USB RX0 **************************************/
#define FLUSHRX0 {write_usb(RXC0,FLUSH);}
/* Flush and disable the USB RX1 **************************************/
#define FLUSHRX1 {write_usb(RXC1,FLUSH);}
/* Flush and disable the USB RX2 **************************************/
#define FLUSHRX2 {write_usb(RXC2,FLUSH);}
/* Flush and disable the USB RX3 **************************************/
#define FLUSHRX3 {write_usb(RXC3,FLUSH); rcount3=0;}
/* enable TX0, using the appropriate DATA PID *************************/
#define TXEN0_PID {if(TSTBIT(dtapid,TGL0PID)) write_usb(TXC0,TX_TOGL+TX_EN);\
else write_usb(TXC0,TX_EN); TGLBIT(dtapid,TGL0PID);}
/* enable TX1, using the appropriate DATA PID, but not toggling it ****/
#define TXEN1_PID_NO_TGL {if(TSTBIT(dtapid,TGL1PID)) \
write_usb(TXC1,TX_TOGL+TX_LAST+TX_EN); else \
write_usb(TXC1,TX_LAST+TX_EN);}
/* enable TX1, using the appropriate DATA PID *************************/
#define TXEN1_PID {TXEN1_PID_NO_TGL; TGLBIT(dtapid,TGL1PID);}
/* enable TX2, using the appropriate DATA PID, but not toggling it ****/
#define TXEN2_PID_NO_TGL {if(TSTBIT(dtapid,TGL2PID)) \
write_usb(TXC2,TX_TOGL+TX_LAST+TX_EN); else \
write_usb(TXC2,TX_LAST+TX_EN);}
/* enable TX2, using the appropriate DATA PID *************************/
#define TXEN2_PID {TXEN2_PID_NO_TGL; TGLBIT(dtapid,TGL2PID);}
/* enable TX3, using the appropriate DATA PID, but not toggling it ****/
#define TXEN3_PID_NO_TGL {SETBIT(status,RPTBUSY);CLRBIT(status,RPTCHNG);\
if(TSTBIT(dtapid,TGL3PID)) write_usb(TXC3,TX_TOGL+TX_LAST+TX_EN);\
else write_usb(TXC3,TX_LAST+TX_EN);}
/* enable TX3, using the appropriate DATA PID *************************/
#define TXEN3_PID {TXEN3_PID_NO_TGL; TGLBIT(dtapid,TGL3PID);}
/* clears the multi-packet mode bits **********************************/
#define CLR_MLTIPKT {CLRBIT(status,GETDESC); CLRBIT(status,GETRPRT); \
CLRBIT(status,MLTIPKT);}
/* sets status.GETDESC and status.MLTIPKT *****************************/
#define SET_GETDESC {SETBIT(status,GETDESC); SETBIT(status,MLTIPKT);}
/* sets status.GETRPRT and status.MLTIPKT *****************************/
#define SET_GETRPRT {SETBIT(status,GETRPRT); SETBIT(status,MLTIPKT);}
/* this macro helps with the switch change test ***********************/
#define TSTSWITCH {if(rpt_sw!=report[SWITCHES]) /*if val differs */\
{report[SWITCHES]=rpt_sw; SETBIT(status,RPTCHNG);}}
/**********************************************************************/
/* These are the global variables */
/**********************************************************************/
#ifdef COP8
#pragma stack [0x0018] @ 0x0058; /*reserve stack space */
#endif
/*USB related buffers and variables *****************************/
byte usb_buf[8]; /*buffer used for USB */
byte desc_typ, desc_idx;
long desc_sze;
byte evnt, rxstat, txstat; /*USB status temp storage */
byte usb_cfg; /*usb config. setting */
byte usb_idl; /*usb idle setting */
byte report[4]; /*buffer used for report */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -