Adds the usb code that we got in ECE 385. It will not work now, and parts that involve the timer are disabled. It does compile though, with a few warnings. The goal will be to add USB MSD support, which is not actually given to us so I will have to do myself or find some other code to base it off of.
243 lines
9.2 KiB
C
243 lines
9.2 KiB
C
/* HID class support functions */
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "project_config.h"
|
|
|
|
BYTE bigbuf[256]; //256 bytes
|
|
extern DEV_RECORD devtable[];
|
|
|
|
HID_DEVICE hid_device = { { 0 } };
|
|
EP_RECORD hid_ep[2] = { { 0 } }; //HID class endpoints, 1 control, 1 interrupt-IN
|
|
//the third endpoint is not implemented
|
|
|
|
/* HID Mouse probe. Called from USB state machine. */
|
|
/* assumes configuration length is less than 256 bytes */
|
|
/* looks for Class:03, Subclass: 01, Protocol: 02 in interface descriptor */
|
|
/* sets mouse in boot protocol */
|
|
/* assumes single configuration and interface configuration 0 */
|
|
BOOL HIDMProbe(BYTE addr, DWORD flags) {
|
|
BYTE tmpbyte;
|
|
BYTE rcode;
|
|
BYTE confvalue;
|
|
WORD total_length;
|
|
USB_DESCR* data_ptr = (USB_DESCR *) &bigbuf;
|
|
BYTE* byte_ptr = bigbuf;
|
|
|
|
(void) flags;
|
|
|
|
rcode = XferGetConfDescr(addr, 0, CONF_DESCR_LEN, 0, bigbuf); //get configuration descriptor
|
|
if (rcode) { //error handling
|
|
//printf("unable to get configuration descriptor");
|
|
return (FALSE);
|
|
}
|
|
if (data_ptr->descr.config.wTotalLength > 256) {
|
|
total_length = 256;
|
|
} else {
|
|
total_length = data_ptr->descr.config.wTotalLength;
|
|
}
|
|
rcode = XferGetConfDescr(addr, 0, total_length, 0, bigbuf); //get the whole configuration
|
|
if (rcode) { //error handling
|
|
//printf("unable to get configuration");
|
|
return (FALSE);
|
|
}
|
|
confvalue = data_ptr->descr.config.bConfigurationValue;
|
|
//printf("checking configuration value (length: %d): ",
|
|
// data_ptr->descr.config.wTotalLength);
|
|
//for (int i = 0; i < data_ptr->descr.config.wTotalLength; i++) {
|
|
//printf("%x ", (unsigned char) (bigbuf[i] & 0xff));
|
|
//}
|
|
while (byte_ptr < bigbuf + total_length) {
|
|
if (data_ptr->descr.config.bDescriptorType != USB_DESCRIPTOR_INTERFACE) {
|
|
byte_ptr = byte_ptr + data_ptr->descr.config.bLength;
|
|
data_ptr = (USB_DESCR*) byte_ptr;
|
|
} // if( data_ptr->descr.config.bDescriptorType != USB_DESCRIPTOR_INTERFACE
|
|
else {
|
|
//printf("starting interface parsing at byte location %d\n",
|
|
// data_ptr->descr.config.bLength);
|
|
BYTE class = data_ptr->descr.interface.bInterfaceClass;
|
|
BYTE subclass = data_ptr->descr.interface.bInterfaceSubClass;
|
|
BYTE protocol = data_ptr->descr.interface.bInterfaceProtocol;
|
|
//printf("class %x, subclass %x, protocol %x,\n", class, subclass,
|
|
// protocol);
|
|
//interface descriptor
|
|
if (class == HID_INTF && subclass == BOOT_INTF_SUBCLASS
|
|
&& protocol == HID_PROTOCOL_MOUSE) {
|
|
//detected a mouse
|
|
devtable[addr].devclass = HID_M; //device class
|
|
tmpbyte = devtable[addr].epinfo->MaxPktSize;
|
|
HID_init(); //initialize data structures
|
|
devtable[addr].epinfo = hid_ep; //switch endpoint information structure
|
|
devtable[addr].epinfo[0].MaxPktSize = tmpbyte;
|
|
hid_device.interface =
|
|
data_ptr->descr.interface.bInterfaceNumber;
|
|
hid_device.addr = addr;
|
|
byte_ptr = byte_ptr + data_ptr->descr.config.bLength;
|
|
data_ptr = (USB_DESCR*) byte_ptr;
|
|
while (byte_ptr < bigbuf + total_length) {
|
|
if (data_ptr->descr.config.bDescriptorType
|
|
!= USB_DESCRIPTOR_ENDPOINT) { //skip to endpoint descriptor
|
|
byte_ptr = byte_ptr + data_ptr->descr.config.bLength;
|
|
data_ptr = (USB_DESCR*) byte_ptr;
|
|
} else {
|
|
/* fill endpoint information structure */
|
|
devtable[addr].epinfo[1].epAddr =
|
|
data_ptr->descr.endpoint.bEndpointAddress;
|
|
devtable[addr].epinfo[1].Attr =
|
|
data_ptr->descr.endpoint.bmAttributes;
|
|
devtable[addr].epinfo[1].MaxPktSize =
|
|
data_ptr->descr.endpoint.wMaxPacketSize;
|
|
devtable[addr].epinfo[1].Interval =
|
|
data_ptr->descr.endpoint.bInterval;
|
|
// devtable[ addr ].epinfo[ 1 ].rcvToggle = bmRCVTOG0;
|
|
/* configure device */
|
|
rcode = XferSetConf(addr, 0, confvalue); //set configuration
|
|
if (rcode) { //error handling
|
|
return (FALSE);
|
|
}
|
|
rcode = XferSetProto(addr, 0, hid_device.interface,
|
|
BOOT_PROTOCOL);
|
|
if (rcode) { //error handling
|
|
return (FALSE);
|
|
} else {
|
|
return (TRUE);
|
|
}
|
|
}
|
|
} //while( byte_ptr....
|
|
} //if (Class matches
|
|
else { //if class don't match; die on first interface. Not really correct
|
|
return (FALSE);
|
|
}
|
|
} //else if( data_ptr->
|
|
} // while( byte_ptr < &buf + total_length
|
|
return (FALSE);
|
|
}
|
|
/* HID Keyboard probe. Called from USB state machine. */
|
|
/* assumes configuration length is less than 256 bytes */
|
|
/* looks for Class:03, Subclass: 01, Protocol: 01 in interface descriptor */
|
|
/* sets keyboard in boot protocol */
|
|
/* assumes single configuration, single endpoint, and interface configuration 0 */
|
|
BOOL HIDKProbe(BYTE addr, DWORD flags) {
|
|
BYTE tmpbyte;
|
|
BYTE rcode;
|
|
BYTE confvalue;
|
|
WORD total_length;
|
|
USB_DESCR* data_ptr = (USB_DESCR *) &bigbuf;
|
|
BYTE* byte_ptr = bigbuf;
|
|
|
|
(void) flags;
|
|
|
|
rcode = XferGetConfDescr(addr, 0, CONF_DESCR_LEN, 0, bigbuf); //get configuration descriptor
|
|
if (rcode) { //error handling
|
|
return (FALSE);
|
|
}
|
|
if (data_ptr->descr.config.wTotalLength > 256) {
|
|
total_length = 256;
|
|
} else {
|
|
total_length = data_ptr->descr.config.wTotalLength;
|
|
}
|
|
rcode = XferGetConfDescr(addr, 0, total_length, 0, bigbuf); //get the whole configuration
|
|
if (rcode) { //error handling
|
|
return (FALSE);
|
|
}
|
|
confvalue = data_ptr->descr.config.bConfigurationValue; //save configuration value to use later
|
|
while (byte_ptr < bigbuf + total_length) { //parse configuration
|
|
if (data_ptr->descr.config.bDescriptorType != USB_DESCRIPTOR_INTERFACE) { //skip to the next descriptor
|
|
byte_ptr = byte_ptr + data_ptr->descr.config.bLength;
|
|
data_ptr = (USB_DESCR*) byte_ptr;
|
|
} // if( data_ptr->descr.config.bDescriptorType != USB_DESCRIPTOR_INTERFACE
|
|
else {
|
|
//printf("starting interface parsing at byte location %d\n",
|
|
// data_ptr->descr.config.bLength);
|
|
BYTE class = data_ptr->descr.interface.bInterfaceClass;
|
|
BYTE subclass = data_ptr->descr.interface.bInterfaceSubClass;
|
|
BYTE protocol = data_ptr->descr.interface.bInterfaceProtocol;
|
|
//printf("class %x, subclass %x, protocol %x,\n", class, subclass,
|
|
// protocol);
|
|
//interface descriptor
|
|
if (class == HID_INTF && subclass == BOOT_INTF_SUBCLASS
|
|
&& protocol == HID_PROTOCOL_KEYBOARD) {
|
|
//detected a keyboard
|
|
devtable[addr].devclass = HID_K; //fill device class
|
|
tmpbyte = devtable[addr].epinfo->MaxPktSize; //save max.packet size
|
|
HID_init(); //initialize data structures
|
|
devtable[addr].epinfo = hid_ep; //switch endpoint information structure
|
|
devtable[addr].epinfo[0].MaxPktSize = tmpbyte; //fill in max.packet size
|
|
hid_device.interface =
|
|
data_ptr->descr.interface.bInterfaceNumber; //fill in interface number to be used in HID requests
|
|
hid_device.addr = addr; //fill in address
|
|
byte_ptr = byte_ptr + data_ptr->descr.config.bLength; //skip to the next descriptor
|
|
data_ptr = (USB_DESCR*) byte_ptr;
|
|
while (byte_ptr < bigbuf + total_length) {
|
|
if (data_ptr->descr.config.bDescriptorType
|
|
!= USB_DESCRIPTOR_ENDPOINT) { //skip to endpoint descriptor
|
|
byte_ptr = byte_ptr + data_ptr->descr.config.bLength;
|
|
data_ptr = (USB_DESCR*) byte_ptr;
|
|
} else {
|
|
/* fill endpoint information structure */
|
|
devtable[addr].epinfo[1].epAddr =
|
|
data_ptr->descr.endpoint.bEndpointAddress;
|
|
devtable[addr].epinfo[1].Attr =
|
|
data_ptr->descr.endpoint.bmAttributes;
|
|
devtable[addr].epinfo[1].MaxPktSize =
|
|
data_ptr->descr.endpoint.wMaxPacketSize;
|
|
devtable[addr].epinfo[1].Interval =
|
|
data_ptr->descr.endpoint.bInterval;
|
|
/* configure device */
|
|
rcode = XferSetConf(addr, 0, confvalue); //set configuration
|
|
if (rcode) { //error handling
|
|
return (FALSE);
|
|
}
|
|
rcode = XferSetProto(addr, 0, hid_device.interface,
|
|
BOOT_PROTOCOL);
|
|
if (rcode) { //error handling
|
|
return (FALSE);
|
|
} else {
|
|
return (TRUE);
|
|
}
|
|
}
|
|
} //while( byte_ptr....
|
|
} //if (Class matches
|
|
else { //if class don't match; stop processing after first interface. Not really correct
|
|
return (FALSE);
|
|
}
|
|
} //else if( data_ptr->
|
|
} // while( byte_ptr < &buf + total_length
|
|
return (FALSE);
|
|
}
|
|
/* HID data structures initialization */
|
|
void HID_init(void) {
|
|
hid_ep[1].sndToggle = bmSNDTOG0;
|
|
hid_ep[1].rcvToggle = bmRCVTOG0;
|
|
}
|
|
/* poll boot mouse */
|
|
BYTE mousePoll(BOOT_MOUSE_REPORT* buf) {
|
|
BYTE rcode;
|
|
MAXreg_wr( rPERADDR, hid_device.addr); //set peripheral address
|
|
rcode = XferInTransfer(hid_device.addr, 1, 8, (BYTE*) buf,
|
|
devtable[hid_device.addr].epinfo[1].MaxPktSize);
|
|
return (rcode);
|
|
}
|
|
/* poll boot keyboard */
|
|
BYTE kbdPoll(BOOT_KBD_REPORT* buf) {
|
|
BYTE rcode;
|
|
MAXreg_wr( rPERADDR, hid_device.addr); //set peripheral address
|
|
rcode = XferInTransfer(hid_device.addr, 1, 8, (BYTE*) buf,
|
|
devtable[hid_device.addr].epinfo[1].MaxPktSize);
|
|
return (rcode);
|
|
}
|
|
BOOL HIDMEventHandler(BYTE address, BYTE event, void *data, DWORD size) {
|
|
(void) address;
|
|
(void) event;
|
|
(void) size;
|
|
(void) data;
|
|
return (FALSE);
|
|
}
|
|
BOOL HIDKEventHandler(BYTE address, BYTE event, void *data, DWORD size) {
|
|
(void) address;
|
|
(void) event;
|
|
(void) size;
|
|
(void) data;
|
|
return (FALSE);
|
|
}
|