Add USB code
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.
This commit is contained in:
242
sw/usb/HID.c
Normal file
242
sw/usb/HID.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/* 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);
|
||||
}
|
||||
Reference in New Issue
Block a user