📄 usb.c
字号:
/******************************************************************************
* VAULT INFORMATION SERVICES *
* TEXAS INSTRUMENTS, INC. *
*----------------------------------------------------------------------------*
* "USB Handler for TUSB2136 Demo App" *
* *
* Programmed by: Craig Steiner, VIS (csteiner@vaultbbs.com) *
* Develop Date: 30/Sep/2000 *
*----------------------------------------------------------------------------*
* Description: This module is a component of the TUSB2136 Demo App. It *
* handles all USB-related operation functions such as USB request *
* handlers, interrupts, etc. Functions related to USB initialization *
* may be found in usbinit.c *
* *
* Modified by Jim Chen 2001/01/03: *
* 1. total 102 keys *
* 2. can work in Mac *
* 3. use scanline8, scanline9 and return 0x40 as suspend key *
* 4. added usbSetIdle(void), void usbSetProtocol(void) for Mac *
* *
* Modified by Jim Chen 2001/01/19: *
* 1. fixed bug in high speed Mac *
* *
* Modified by Jim Chen 2001/01/31: *
* 1. added usbGetIdle and usbGetProtocol for passing HIDView optional *
* commands *
* *
* Modified by Jim Chen 2001/05/20: *
* 1. fix bug on *
* USB_REQ_SET_INTERFACE mapping usbSetInterface of tUsbRequestList *
******************************************************************************/
#include <io51.h>
#include "types.h"
#include "tusb2136.h"
#include "usb.h"
#include "delay.h"
/***************************************************************************
* Section: TUSB2136 Segment Definitions *
* Programmer: Craig Steiner (csteiner@vaultbbs.com) *
* Description: This section of code assigns certain variables to defined *
* mapped memory addresses in the TUSB2136. The mapped memory symbols *
* used in the dataset() pragmas are found in the .XCL file for the *
* project. *
***************************************************************************/
#pragma memory = dataseg(TUSB2136_SETUPPACKET_SEG)
tDEVICE_REQUEST tSetupPacket;
#pragma memory = default
#pragma memory = dataseg(TUSB2136_EP0_EDB_SEG)
tEDB0 tEndPoint0DescriptorBlock;
#pragma memory = default
#pragma memory = dataseg(TUSB2136_IEP_EDB_SEG)
tEDB tInputEndPointDescriptorBlock[3];
#pragma memory = default
#pragma memory = dataseg(TUSB2136_OEP_EDB_SEG)
tEDB tOutputEndPointDescriptorBlock[3];
#pragma memory = default
#pragma memory = dataseg(TUSB2136_IEP0BUFFER_SEG)
BYTE abIEP0Buffer[EP0_MAX_PACKET_SIZE];
#pragma memory = default
#pragma memory = dataseg(TUSB2136_OEP0BUFFER_SEG)
BYTE abOEP0Buffer[EP0_MAX_PACKET_SIZE];
#pragma memory = default
#pragma memory = dataseg(TUSB2136_DESC_SEG) // 0xfe00
BYTE abDescriptor[SIZEOF_DEVICE_DESCRIPTOR];
//BYTE abConfigurationDescriptorGroup[SIZEOF_BOOTCODE_CONFIG_DESC_GROUP];
//BYTE abStringDescriptor[SIZEOF_BOOTCODE_STRING_DESC_GROUP];
#pragma memory = default
#pragma memory = dataseg(TUSB2136_OEP1_X_BUFFER_SEG) // 0xfd80
BYTE pbXBufferAddress[EP_MAX_PACKET_SIZE];
#pragma memory = default
#pragma memory = dataseg(TUSB2136_OEP1_Y_BUFFER_SEG) // 0xfdc0
BYTE pbYBufferAddress[EP_MAX_PACKET_SIZE];
#pragma memory = default
/***************************************************************************
* Section: Declarations *
* Programmer: Craig Steiner (csteiner@vaultbbs.com) *
* Description: This section of the code declares global and external *
* variables, as well as functions, etc. *
***************************************************************************/
// EXTERNAL DECLARATIONS
extern BYTE code abromReportDescriptor[SIZEOF_REPORT_DESCRIPTOR];
extern void setLEDs(BYTE bData); // From 8255.c
extern unsigned char intFlags; // From keyboard.c
extern unsigned char otherFlags; // From keyboard.c
extern void IEP1InterruptHandler(void); // From keyboard.c
extern void UsbReset(void); // From usbinit.c
extern void OEP0SetLEDs(void);
extern BYTE bLED;
extern struct FUNCDEF_STRUCT code funcDefs[17]; // From vidpid.c
extern unsigned char fncOffset; // From vidpid.c
extern BYTE code abromReportDescriptor[SIZEOF_REPORT_DESCRIPTOR];
extern BYTE code abromConfigurationDescriptorGroup[SIZEOF_BOOTCODE_CONFIG_DESC_GROUP];
extern BYTE code abromDeviceDescriptor[SIZEOF_DEVICE_DESCRIPTOR];
extern BYTE strlen(char *string); // From support.c
// GLOBAL VARIABLE DECLARATIONS
BYTE deviceReady = FALSE; // Indicates whether the device has been
// properly initialized on the USB bus.
BYTE bSuspended = FALSE; // Indicates whether the device is suspended or not
BYTE bStatusAction; // Indicates the current state of sending
// receiving data packets.
BYTE bUsbDeviceAddress; // The device's USB address.
WORD wBytesRemainingOnIEP0; // For endpoint zero transmitter only
// Holds count of bytes remaining to be
// transmitted by endpoint 0. A value
// of 0 means that a 0-length data packet
// A value of 0xFFFF means that transfer
// is complete.
BOOL bHostAskMoreDataThanAvailable;
// If host ask more data then TUSB2136 has
// It will send one zero-length packet
// if the asked lenght is a multiple of
// max. size of endpoint 0
PBYTE pbIEP0Buffer; // A buffer pointer to input end point 0
// Data sent back to host is copied from
// this pointed memory location
BYTE bConfigurationNumber = 0; // Set to 1 when USB device has been
// configured, set to 0 when unconfigured
BYTE bInterfaceNumber = 0; // The interface number selected
WORD wDeviceFeatures = 0; // The device features
WORD wBytesRemainingOnOEP0; // For endpoint zero transmitter only
// Holds count of bytes remaining to be
// received by endpoint 0. A value
// of 0 means that a 0-length data packet
// A value of 0xFFFF means that transfer
PBYTE pbOEP0Buffer; // A buffer pointer to output end point 0
// Data sent from host is copied to
// this pointed memory location
// is complete.
#define usbClearOEP0ByteCount tEndPoint0DescriptorBlock.bOEPBCNT = 0x00
#define usbStallOEP0 tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL
void usbReceiveDataPacketOnEP0(PBYTE pbBuffer);
void usbStallEndpoint0(void);
void usbSendZeroLengthPacketOnIEP0(void);
void usbSendNextPacketOnIEP0(void);
void usbSendDataPacketOnEP0(PBYTE pbBuffer);
/***************************************************************************
* Section: USB REQUEST FUNCTIONS *
* Programmer: Craig Steiner (csteiner@vaultbbs.com) based on code by *
* Lobo Tai (lobotai@ti.com) *
* Description: The functions in this section of code are called by the *
* usbDecodeAndProcessUsbRequest function when a Setup packet is *
* received. Each function handles a specific USB/Class/Endpoint *
* function. *
***************************************************************************/
// The Get/Set configuration functions allow the host to select one of various
// configurations that the keyboard may support. This firmware only supports
// one configuration, but the following functions allow the firmware to accept
// any given configuration number. The code, as-is, will function identically
// in any given configuration, but additional configurations may be supported
// by simply adding support for the configurations, presumably in keyboard.c.
void usbGetConfiguration(void)
{
wBytesRemainingOnIEP0 = 1;
usbSendDataPacketOnEP0((PBYTE) &bConfigurationNumber);
}
void usbSetConfiguration(void)
{
usbStallOEP0;
bConfigurationNumber = tSetupPacket.bValueL;
usbSendZeroLengthPacketOnIEP0();
}
// The Set_Report request is sent by the host to a typical HID device,
// such as this keyboard, to update the LEDs that correspond to the
// scroll lock, caps lock, and num lock. When the Set_Report setup
// packet is received, we initiate a "Receive Data Packet" sequence
// since the actual 1-byte data value will be in the following
// packet on OEP0. Thus we initicate that we will receive 1 byte
// (since the LED data is contained in a single byte) and we
// instruct the receive routine to receive the data at the address
// at which the bLED variable is located. Thus bLed will automatically
// be updated with the new value after the transfer is completed.
void usbSetReport(void)
{
wBytesRemainingOnOEP0 = 1;
usbReceiveDataPacketOnEP0((PBYTE) &bLED);
}
// The following functions are called at initial device enumeration, and are used
// to obtain the device, configuration, and string descriptors from the
// device.
//extern unsigned char s0123; // The s0132 value read from VIDSTA at boot time
void usbGetDeviceDescriptor(void)
{
BYTE bTemp;
// Copy the DEVICE DESCRIPTOR from program "ROM" to XRAM
for(bTemp=0;bTemp<SIZEOF_DEVICE_DESCRIPTOR;bTemp++)
abDescriptor[bTemp] = abromDeviceDescriptor[bTemp];
// Modify the FUNCTION VID/PID and firmware version using our selected value
// abDescriptor[OFFSET_DEVICE_DESCRIPTOR_VID_L] = s0123;
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_VID_L] = (funcDefs[fncOffset].fncVID & 0xFF);
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_VID_H] = ((funcDefs[fncOffset].fncVID & 0xFF00) >> 8);
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_PID_L] = (funcDefs[fncOffset].fncPID & 0xFF);
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_PID_H] = ((funcDefs[fncOffset].fncPID & 0xFF00) >> 8);
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_VER_L] = (funcDefs[fncOffset].fncRevision & 0xFF);
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_VER_H] = ((funcDefs[fncOffset].fncRevision & 0xFF00) >> 8);
if(funcDefs[fncOffset].mfgDescription == NULL )
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_IMFG] = 0x00;
if(funcDefs[fncOffset].prodDescription == NULL )
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_IPROD] = 0x00;
if(funcDefs[fncOffset].serialNumber == NULL )
abDescriptor[OFFSET_DEVICE_DESCRIPTOR_ISN] = 0x00;
usbClearOEP0ByteCount;
wBytesRemainingOnIEP0 = SIZEOF_DEVICE_DESCRIPTOR;
usbSendDataPacketOnEP0((PBYTE)&abDescriptor);
// Once the Device Descriptor has been sent, the device can essentially
// function. Thus we enable the deviceReady variable so that the main
// code in keyboard.c knows that it can begin the service loop.
deviceReady = TRUE;
}
void usbGetHIDDescriptor(void)
{
BYTE bTemp;
// Copy the DEVICE DESCRIPTOR from program "ROM" to XRAM
for(bTemp=0;bTemp<SIZEOF_DEVICE_DESCRIPTOR;bTemp++)
abDescriptor[bTemp] = abromConfigurationDescriptorGroup[SIZEOF_CONFIG_DESCRIPTOR+SIZEOF_INTERFACE_DESCRIPTOR + bTemp];
usbClearOEP0ByteCount;
wBytesRemainingOnIEP0 = SIZEOF_KEYBD_HID_DESCRIPTOR;
usbSendDataPacketOnEP0((PBYTE)&abDescriptor);
}
void usbGetConfigurationDescriptor(void)
{
BYTE bTemp;
// Copy the DEVICE DESCRIPTOR from program "ROM" to XRAM
for(bTemp=0;bTemp<SIZEOF_BOOTCODE_CONFIG_DESC_GROUP;bTemp++)
abDescriptor[bTemp] = abromConfigurationDescriptorGroup[bTemp];
usbClearOEP0ByteCount;
wBytesRemainingOnIEP0 = SIZEOF_BOOTCODE_CONFIG_DESC_GROUP;
usbSendDataPacketOnEP0((PBYTE)&abDescriptor);
}
void usbGetStringDescriptor(void)
{
// WORD bIndex;
BYTE bTemp;
BYTE stringOffset = 0;
usbClearOEP0ByteCount;
switch(tSetupPacket.bValueL)
{
case 0: // LANGUAGE ID
abDescriptor[0] = 4; // Length of language descriptor ID
abDescriptor[1] = 3; // LANGID tag
abDescriptor[2] = 0x09; // Low byte of 0x0409 (English)
abDescriptor[3] = 0x04; // High byte of 0x0409 (English)
break;
case 1: // MANUFACTURER DESCRIPTION
abDescriptor[stringOffset++] = strlen(funcDefs[fncOffset].mfgDescription) * 2 + 2; // Length of this string
abDescriptor[stringOffset++] = DESC_TYPE_STRING; // String descriptor type
for(bTemp = 0; bTemp < strlen(funcDefs[fncOffset].mfgDescription);bTemp++)
{
abDescriptor[stringOffset++] = funcDefs[fncOffset].mfgDescription[bTemp]; // Insert the character from the string
abDescriptor[stringOffset++] = 0x00; // Insert a trailing 00h for Unicode representation
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -