summaryrefslogtreecommitdiff
path: root/USB_Host_Shield/examples/descriptor_parser/descriptor_parser.pde
diff options
context:
space:
mode:
Diffstat (limited to 'USB_Host_Shield/examples/descriptor_parser/descriptor_parser.pde')
-rw-r--r--USB_Host_Shield/examples/descriptor_parser/descriptor_parser.pde720
1 files changed, 0 insertions, 720 deletions
diff --git a/USB_Host_Shield/examples/descriptor_parser/descriptor_parser.pde b/USB_Host_Shield/examples/descriptor_parser/descriptor_parser.pde
deleted file mode 100644
index d417e76..0000000
--- a/USB_Host_Shield/examples/descriptor_parser/descriptor_parser.pde
+++ /dev/null
@@ -1,720 +0,0 @@
-/* MAX3421E USB Host controller configuration descriptor parser */
-#include <Spi.h>
-#include <Max3421e.h>
-#include <Usb.h>
-#include "descriptor_parser.h"
-
-#define LOBYTE(x) ((char*)(&(x)))[0]
-#define HIBYTE(x) ((char*)(&(x)))[1]
-#define BUFSIZE 256 //buffer size
-#define DEVADDR 1
-
-#define getReportDescr( addr, ep, nbytes, parse_func, nak_limit ) ctrlXfer( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, parse_func, nak_limit )
-#define getReport( addr, ep, nbytes, interface, report_type, report_id, parse_func, nak_limit ) ctrlXfer( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, parse_func, nak_limit )
-
-/* Foeward declarations */
-void setup();
-void loop();
-byte ctrlXfer( byte addr, byte ep, byte bmReqType, byte bRequest, byte wValLo, byte wValHi, unsigned int wInd, uint16_t nbytes, PARSE parse_func, uint16_t nak_limit );
-void HIDreport_parse( uint8_t* buf, uint8_t* head, uint8_t* tail);
-
-typedef struct {
- uint8_t bDescriptorType;
- uint16_t wDescriptorLength;
-} HID_CLASS_DESCRIPTOR;
-
-
-//typedef void (*PARSE)( int8_t*, int8_t*, int8_t );
-
-MAX3421E Max;
-USB Usb;
-
-void setup()
-{
- Serial.begin( 115200 );
- printProgStr(PSTR("\r\nStart"));
- Max.powerOn();
- delay( 200 );
-}
-
-void loop()
-{
- uint8_t rcode;
- uint8_t tmpbyte = 0;
- //PARSE pf = &HIDreport_parse;
- /**/
- Max.Task();
- Usb.Task();
- if( Usb.getUsbTaskState() >= USB_STATE_CONFIGURING ) { //state configuring or higher
- /* printing device descriptor */
- printProgStr(PSTR("\r\nDevice addressed... "));
- printProgStr(PSTR("Requesting device descriptor."));
- tmpbyte = getdevdescr( DEVADDR ); //number of configurations, 0 if error
- if( tmpbyte == 0 ) {
- printProgStr(PSTR("\r\nDevice descriptor cannot be retrieved. Program Halted\r\n"));
- while( 1 ); //stop
- }//if( tmpbyte
- /* print configuration descriptors for all configurations */
- for( uint8_t i = 0; i < tmpbyte; i++ ) {
- getconfdescr( DEVADDR, i );
- }
- /* Stop */
- while( 1 ); //stop
- }
-}
-
-/* Prints device descriptor. Returns number of configurations or zero if request error occured */
-byte getdevdescr( byte addr )
-{
- USB_DEVICE_DESCRIPTOR buf;
- byte rcode;
- //Max.toggle( BPNT_0 );
- rcode = Usb.getDevDescr( addr, 0, 0x12, ( char *)&buf );
- if( rcode ) {
- printProgStr( rcode_error_msg );
- print_hex( rcode, 8 );
- return( 0 );
- }
- printProgStr(PSTR("\r\nDevice descriptor: \r\n"));
- //Descriptor length
- printProgStr( descr_len );
- print_hex( buf.bLength, 8 );
- //Descriptor type
-// printProgStr( descr_type );
-// print_hex( buf.bDescriptorType, 8 );
-// printProgStr( descrtype_parse( buf.bDescriptorType ));
- //USB Version
- printProgStr(PSTR("\r\nUSB version:\t\t"));
- Serial.print(( HIBYTE( buf.bcdUSB )), HEX );
- Serial.print(".");
- Serial.print(( LOBYTE( buf.bcdUSB )), HEX );
- //Device class
- printProgStr( class_str );
- print_hex( buf.bDeviceClass, 8 );
- printProgStr( classname_parse( buf.bDeviceClass ));
- //Device Subclass
- printProgStr( subclass_str );
- print_hex( buf.bDeviceSubClass, 8 );
- //Device Protocol
- printProgStr( protocol_str );
- print_hex( buf.bDeviceProtocol, 8 );
- //Max.packet size
- printProgStr( maxpktsize_str );
- print_hex( buf.bMaxPacketSize0, 8 );
- //VID
- printProgStr(PSTR("\r\nVendor ID:\t\t"));
- print_hex( buf.idVendor, 16 );
- //PID
- printProgStr(PSTR("\r\nProduct ID:\t\t"));
- print_hex( buf.idProduct, 16 );
- //Revision
- printProgStr(PSTR("\r\nRevision ID:\t\t"));
- print_hex( buf.bcdDevice, 16 );
- //Mfg.string
- printProgStr (PSTR("\r\nMfg.string index:\t"));
- print_hex( buf.iManufacturer, 8 );
- getstrdescr( addr, buf.iManufacturer );
- //Prod.string
- printProgStr(PSTR("\r\nProd.string index:\t"));
- print_hex( buf.iProduct, 8 );
- //printProgStr( str_cont );
- getstrdescr( addr, buf.iProduct );
- //Serial number string
- printProgStr(PSTR("\r\nSerial number index:\t"));
- print_hex( buf.iSerialNumber, 8 );
- //printProgStr( str_cont );
- getstrdescr( addr, buf.iSerialNumber );
- //Number of configurations
- printProgStr(PSTR("\r\nNumber of conf.:\t"));
- print_hex( buf.bNumConfigurations, 8 );
- return( buf.bNumConfigurations );
-}
-/* Get string descriptor. Takes device address and string index */
-byte getstrdescr( byte addr, byte idx )
-{
- char buf[ BUFSIZE ];
- byte rcode;
- byte length;
- byte i;
- unsigned int langid;
- if( idx == 0 ) { //don't try to get index zero
- return( 0 );
- }
- rcode = Usb.getStrDescr( addr, 0, 1, 0, 0, buf ); //get language table length
- if( rcode ) {
- printProgStr(PSTR("\r\nError retrieving LangID table length"));
- return( rcode );
- }
- length = buf[ 0 ]; //length is the first byte
- rcode = Usb.getStrDescr( addr, 0, length, 0, 0, buf ); //get language table
- if( rcode ) {
- printProgStr(PSTR("\r\nError retrieving LangID table"));
- return( rcode );
- }
- HIBYTE( langid ) = buf[ 3 ]; //get first langid
- LOBYTE( langid ) = buf[ 2 ]; //bytes are swapped to account for endiannes
- //printProgStr(PSTR("\r\nLanguage ID: "));
- //print_hex( langid, 16 );
- rcode = Usb.getStrDescr( addr, 0, 1, idx, langid, buf );
- if( rcode ) {
- printProgStr(PSTR("\r\nError retrieving string length"));
- return( rcode );
- }
- length = ( buf[ 0 ] < 254 ? buf[ 0 ] : 254 );
- printProgStr(PSTR(" Length: "));
- Serial.print( length, DEC );
- rcode = Usb.getStrDescr( addr, 0, length, idx, langid, buf );
- if( rcode ) {
- printProgStr(PSTR("\r\nError retrieveing string"));
- return( rcode );
- }
- printProgStr(PSTR(" Contents: "));
- for( i = 2; i < length; i+=2 ) {
- Serial.print( buf[ i ] );
- }
- return( idx );
-}
-/* Returns string to class name */
-const char* classname_parse( byte class_number )
-{
- switch( class_number ) {
- case 0x00:
- return PSTR(" Use class information in the Interface Descriptor");
- case 0x01:
- return PSTR(" Audio");
- case 0x02:
- return PSTR(" Communications and CDC Control");
- case 0x03:
- return PSTR(" HID (Human Interface Device)");
- case 0x05:
- return PSTR(" Physical");
- case 0x06:
- return PSTR(" Image");
- case 0x07:
- return PSTR(" Printer");
- case 0x08:
- return PSTR(" Mass Storage");
- case 0x09:
- return PSTR(" Hub");
- case 0x0a:
- return PSTR(" CDC-Data");
- case 0x0b:
- return PSTR(" Smart Card");
- case 0x0d:
- return PSTR(" Content Security");
- case 0x0e:
- return PSTR(" Video");
- case 0x0f:
- return PSTR(" Personal Healthcare");
- case 0xdc:
- return PSTR("Diagnostic Device");
- case 0xe0:
- return PSTR(" Wireless Controller");
- case 0xef:
- return PSTR(" Miscellaneous");
- case 0xfe:
- return PSTR(" Application Specific");
- case 0xff:
- return PSTR(" Vendor Specific");
- default:
- return unk_msg;
- }//switch( class_number
-}
-/* Getting configuration descriptor */
-byte getconfdescr( byte addr, byte conf )
-{
- char buf[ BUFSIZE ];
- char* buf_ptr = buf;
- byte rcode;
- byte descr_length;
- byte descr_type;
- unsigned int total_length;
- printProgStr(PSTR("\r\n\nConfiguration number "));
- Serial.print( conf, HEX );
- rcode = Usb.getConfDescr( addr, 0, 4, conf, buf ); //get total length
- if( rcode ) {
- printProgStr(PSTR("Error retrieving configuration length. Error code "));
- Serial.println( rcode, HEX );
- return( 0 );
- }//if( rcode
- LOBYTE( total_length ) = buf[ 2 ];
- HIBYTE( total_length ) = buf[ 3 ];
- printProgStr(PSTR("\r\nTotal configuration length: "));
- Serial.print( total_length, DEC );
- printProgStr(PSTR(" bytes"));
- if( total_length > BUFSIZE ) { //check if total length is larger than buffer
- printProgStr(PSTR("Total length truncated to "));
- Serial.print( BUFSIZE, DEC);
- printProgStr(PSTR("bytes"));
- total_length = BUFSIZE;
- }
- rcode = Usb.getConfDescr( addr, 0, total_length, conf, buf ); //get the whole descriptor
- while( buf_ptr < buf + total_length ) { //parsing descriptors
- descr_length = *( buf_ptr );
- descr_type = *( buf_ptr + 1 );
- switch( descr_type ) {
- case( USB_DESCRIPTOR_CONFIGURATION ):
- printconfdescr( buf_ptr );
- break;
- case( USB_DESCRIPTOR_INTERFACE ):
- printintfdescr( buf_ptr );
- break;
- case( USB_DESCRIPTOR_ENDPOINT ):
- printepdescr( buf_ptr );
- break;
- case( HID_DESCRIPTOR_HID ):
- printhid_descr( buf_ptr );
- break;
- default:
- printunkdescr( buf_ptr );
- break;
- }//switch( descr_type
- Serial.println("");
- buf_ptr = ( buf_ptr + descr_length ); //advance buffer pointer
- }//while( buf_ptr <=...
- return( 0 );
-}
-/* function to print configuration descriptor */
-void printconfdescr( char* descr_ptr )
-{
- USB_CONFIGURATION_DESCRIPTOR* conf_ptr = ( USB_CONFIGURATION_DESCRIPTOR* )descr_ptr;
- uint8_t tmpbyte;
- printProgStr(PSTR("\r\n\nConfiguration descriptor:"));
- printProgStr(PSTR("\r\nTotal length:\t\t"));
- print_hex( conf_ptr->wTotalLength, 16 );
- printProgStr(PSTR("\r\nNumber of interfaces:\t"));
- print_hex( conf_ptr->bNumInterfaces, 8 );
- printProgStr(PSTR("\r\nConfiguration value:\t"));
- print_hex( conf_ptr->bConfigurationValue, 8 );
- printProgStr(PSTR("\r\nConfiguration string:\t"));
- tmpbyte = conf_ptr->iConfiguration;
- print_hex( tmpbyte, 8 );
- getstrdescr( DEVADDR, tmpbyte );
- printProgStr(PSTR("\r\nAttributes:\t\t"));
- tmpbyte = conf_ptr->bmAttributes;
- print_hex( tmpbyte, 8 );
- if( tmpbyte & 0x40 ) { //D6
- printProgStr(PSTR(" Self-powered"));
- }
- if( tmpbyte & 0x20 ) { //D5
- printProgStr(PSTR(" Remote Wakeup"));
- }
- printProgStr(PSTR("\r\nMax.power:\t\t"));
- tmpbyte = conf_ptr->bMaxPower;
- print_hex( tmpbyte, 8 );
- printProgStr(PSTR(" "));
- Serial.print(( tmpbyte * 2 ), DEC);
- printProgStr(PSTR("ma"));
- return;
-}
-/* function to print interface descriptor */
-void printintfdescr( char* descr_ptr )
-{
- USB_INTERFACE_DESCRIPTOR* intf_ptr = ( USB_INTERFACE_DESCRIPTOR* )descr_ptr;
- uint8_t tmpbyte;
- printProgStr(PSTR("\r\nInterface descriptor:"));
- printProgStr(PSTR("\r\nInterface number:\t"));
- print_hex( intf_ptr->bInterfaceNumber, 8 );
- printProgStr(PSTR("\r\nAlternate setting:\t"));
- print_hex( intf_ptr->bAlternateSetting, 8 );
- printProgStr(PSTR("\r\nEndpoints:\t\t"));
- print_hex( intf_ptr->bNumEndpoints, 8 );
- printProgStr( class_str );
- tmpbyte = intf_ptr->bInterfaceClass;
- print_hex( tmpbyte, 8 );
- printProgStr(classname_parse( tmpbyte ));
- printProgStr( subclass_str );
- print_hex( intf_ptr->bInterfaceSubClass, 8 );
- printProgStr( protocol_str );
- print_hex( intf_ptr->bInterfaceProtocol, 8 );
- printProgStr(PSTR("\r\nInterface string:\t"));
- tmpbyte = intf_ptr->iInterface;
- print_hex( tmpbyte, 8 );
- getstrdescr( DEVADDR, tmpbyte );
- return;
-}
-/* function to print endpoint descriptor */
-void printepdescr( char* descr_ptr )
-{
- USB_ENDPOINT_DESCRIPTOR* ep_ptr = ( USB_ENDPOINT_DESCRIPTOR* )descr_ptr;
- uint8_t tmpbyte;
- printProgStr(PSTR("\r\nEndpoint descriptor:"));
- printProgStr(PSTR("\r\nEndpoint address:\t"));
- tmpbyte = ep_ptr->bEndpointAddress;
- print_hex( tmpbyte & 0x0f, 8 );
- printProgStr(PSTR(" Direction: "));
- ( tmpbyte & 0x80 ) ? printProgStr(PSTR("IN")) : printProgStr(PSTR("OUT"));
- printProgStr(PSTR("\r\nAttributes:\t\t"));
- tmpbyte = ep_ptr->bmAttributes;
- print_hex( tmpbyte, 8 );
- printProgStr(PSTR(" Transfer type: "));
- printProgStr((char*)pgm_read_word(&transfer_types[(tmpbyte & 0x03)]));
- if(( tmpbyte & 0x03 ) == 1 ) { //Isochronous Transfer
- printProgStr(PSTR(", Sync Type: "));
- printProgStr((char*)pgm_read_word(&sync_types[(tmpbyte & 0x0c)]));
- printProgStr(PSTR(", Usage Type: "));
- printProgStr((char*)pgm_read_word(&usage_types[(tmpbyte & 0x30)]));
- }//if( tmpbyte & 0x01
- printProgStr( maxpktsize_str );
- print_hex( ep_ptr->wMaxPacketSize, 16 );
- printProgStr(PSTR("\r\nPolling interval:\t"));
- tmpbyte = ep_ptr->bInterval;
- print_hex( tmpbyte, 8 );
- printProgStr(PSTR(" "));
- Serial.print( tmpbyte, DEC );
- printProgStr(PSTR(" ms"));
- return;
-}
-/* function to print HID descriptor */
-void printhid_descr( char* descr_ptr )
-{
- PARSE pf = &HIDreport_parse;
- USB_HID_DESCRIPTOR* hid_ptr = ( USB_HID_DESCRIPTOR* )descr_ptr;
- uint8_t tmpbyte;
- /**/
- printProgStr(PSTR("\r\nHID descriptor:"));
- printProgStr(PSTR("\r\nDescriptor length:\t"));
- tmpbyte = hid_ptr->bLength;
- print_hex( tmpbyte, 8 );
- printProgStr(PSTR(" "));
- Serial.print( tmpbyte, DEC );
- printProgStr(PSTR(" bytes"));
- printProgStr(PSTR("\r\nHID version:\t\t"));
- Serial.print(( HIBYTE( hid_ptr->bcdHID )), HEX );
- Serial.print(".");
- Serial.print(( LOBYTE( hid_ptr->bcdHID )), HEX );
- tmpbyte = hid_ptr->bCountryCode;
- printProgStr(PSTR("\r\nCountry Code:\t\t"));
- Serial.print( tmpbyte, DEC );
- printProgStr(PSTR(" "));
- ( tmpbyte > 35 ) ? printProgStr(PSTR("Reserved")) : printProgStr((char*)pgm_read_word(&HID_Country_Codes[ tmpbyte ]));
- tmpbyte = hid_ptr->bNumDescriptors;
- printProgStr(PSTR("\r\nClass Descriptors:\t"));
- Serial.print( tmpbyte, DEC );
- //Printing class descriptors
- descr_ptr += 6; //advance buffer pointer
- for( uint8_t i = 0; i < tmpbyte; i++ ) {
- uint8_t tmpdata;
- HID_CLASS_DESCRIPTOR* hidclass_ptr = ( HID_CLASS_DESCRIPTOR* )descr_ptr;
- tmpdata = hidclass_ptr->bDescriptorType;
- printProgStr(PSTR("\r\nClass Descriptor Type:\t"));
- Serial.print( tmpdata, HEX );
- if(( tmpdata < 0x21 ) || ( tmpdata > 0x2f )) {
- printProgStr(PSTR(" Invalid"));
- }
- switch( tmpdata ) {
- case 0x21:
- printProgStr(PSTR(" HID"));
- break;
- case 0x22:
- printProgStr(PSTR(" Report"));
- break;
- case 0x23:
- printProgStr(PSTR(" Physical"));
- break;
- default:
- printProgStr(PSTR(" Reserved"));
- break;
- }//switch( tmpdata
- printProgStr(PSTR("\r\nClass Descriptor Length:"));
- Serial.print( hidclass_ptr->wDescriptorLength );
- printProgStr(PSTR(" bytes"));
- printProgStr(PSTR("\r\n\nHID report descriptor:\r\n"));
- getReportDescr( DEVADDR, 0 , hidclass_ptr->wDescriptorLength, pf, USB_NAK_LIMIT );
- descr_ptr += 3; //advance to the next record
- }//for( uint8_t i=...
- return;
-}
-/*function to print unknown descriptor */
-void printunkdescr( char* descr_ptr )
-{
- byte length = *descr_ptr;
- byte i;
- printProgStr(PSTR("\r\nUnknown descriptor:"));
- printProgStr(PSTR("Length:\t\t"));
- print_hex( *descr_ptr, 8 );
- printProgStr(PSTR("\r\nType:\t\t"));
- print_hex( *(descr_ptr + 1 ), 8 );
- printProgStr(PSTR("\r\nContents:\t"));
- descr_ptr += 2;
- for( i = 0; i < length; i++ ) {
- print_hex( *descr_ptr, 8 );
- descr_ptr++;
- }
-}
-/* Control-IN transfer with callback. Sets address, endpoint, fills control packet with necessary data, dispatches control packet, and initiates bulk IN transfer */
-/* Control, data, and setup stages combined from standard USB library to be able to read large data blocks. Restricted to control-IN transfers with data stage */
-/* data read and MAX3421E RECV FIFO buffer release shall be performed by parse_func callback */
-/* return codes: */
-/* 00 = success */
-/* 01-0f = non-zero HRSLT */
-byte ctrlXfer( byte addr, byte ep, byte bmReqType, byte bRequest, byte wValLo, byte wValHi, unsigned int wInd, uint16_t nbytes, PARSE parse_func, uint16_t nak_limit = USB_NAK_LIMIT )
-{
- byte rcode;
- SETUP_PKT sp;
- EP_RECORD* ep_rec = Usb.getDevTableEntry( addr, ep );
- byte pktsize;
- byte maxpktsize = ep_rec->MaxPktSize;
- unsigned int xfrlen = 0;
- /**/
- Max.regWr( rPERADDR, addr ); //set peripheral address
- /* fill in setup packet */
- sp.ReqType_u.bmRequestType = bmReqType;
- sp.bRequest = bRequest;
- sp.wVal_u.wValueLo = wValLo;
- sp.wVal_u.wValueHi = wValHi;
- sp.wIndex = wInd;
- sp.wLength = nbytes;
- Max.bytesWr( rSUDFIFO, 8, ( char *)&sp ); //transfer to setup packet FIFO
- rcode = Usb.dispatchPkt( tokSETUP, ep, nak_limit ); //dispatch packet
- //Serial.println("Setup packet"); //DEBUG
- if( rcode ) { //return HRSLT if not zero
- printProgStr(PSTR("\r\nSetup packet error: "));
- Serial.print( rcode, HEX );
- return( rcode );
- }
- /* Data stage */
- //ep_rec->rcvToggle = bmRCVTOG1;
- Max.regWr( rHCTL, bmRCVTOG1 ); //set toggle
- while( 1 ) { //exited by break
- /* request data */
- rcode = Usb.dispatchPkt( tokIN, ep, nak_limit );
- if( rcode ) {
- printProgStr(PSTR("\r\nData Stage Error: "));
- Serial.print( rcode, HEX );
- return( rcode );
- }
- /* check for RCVDAVIRQ and generate error if not present */
- /* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
- if(( Max.regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) {
- printProgStr(PSTR("\r\nData Toggle error."));
- return ( 0xf0 );
- }
- pktsize = Max.regRd( rRCVBC ); //get received bytes count
- parse_func( pktsize ); //call parse function. Parse is expected to read the FIFO completely
- Max.regWr( rHIRQ, bmRCVDAVIRQ ); // Clear the IRQ & free the buffer
- xfrlen += pktsize; // add this packet's byte count to total transfer length
- /* The transfer is complete under two conditions: */
- /* 1. The device sent a short packet (L.T. maxPacketSize) */
- /* 2. 'nbytes' have been transferred. */
- if (( pktsize < maxpktsize ) || (xfrlen >= nbytes )) { // have we transferred 'nbytes' bytes?
- break;
- }
- }//while( 1 )
- rcode = Usb.dispatchPkt( tokOUTHS, ep, nak_limit );
- if( rcode ) { //return error
- printProgStr(PSTR("Status packet error: "));
- Serial.print( rcode, HEX );
- }
- return( rcode );
-}
-/* Parses bitfields in main items */
-void print_mainbitfield( uint8_t byte_toparse )
-{
- ( byte_toparse & 0x01 ) ? printProgStr(PSTR("Constant,")) : printProgStr(PSTR("Data,")); //bit 0
- ( byte_toparse & 0x02 ) ? printProgStr(PSTR("Variable,")) : printProgStr(PSTR("Array,")); //bit 1
- ( byte_toparse & 0x04 ) ? printProgStr(PSTR("Relative,")) : printProgStr(PSTR("Absolute,")); //...
- ( byte_toparse & 0x08 ) ? printProgStr(PSTR("Wrap,")) : printProgStr(PSTR("No Wrap,"));
- ( byte_toparse & 0x10 ) ? printProgStr(PSTR("Non Linear,")) : printProgStr(PSTR("Linear,"));
- ( byte_toparse & 0x20 ) ? printProgStr(PSTR("No preferred,")) : printProgStr(PSTR("Preferred State,"));
- ( byte_toparse & 0x40 ) ? printProgStr(PSTR("Null State,")) : printProgStr(PSTR("No Null Position,")); //bit 6
- ( byte_toparse & 0x40 ) ? printProgStr(PSTR("Volatile( ignore for Input),")) : printProgStr(PSTR("Non-volatile(Ignore for Input),")); //bit 7
-}
-/* HID Report Desriptor Parser Callback */
-/* called repeatedly from Control transfer function */
-void HIDreport_parse( uint8_t pkt_size )
-{
-#define B_SIZE 0x03 //bSize bitmask
-#define B_TYPE 0x0c //bType bitmask
-#define B_TAG 0xf0 //bTag bitmask
- /* parser states */
- enum STATE { ITEM_START, DATA_PARSE };
- static STATE state = ITEM_START;
- static uint8_t databytes_left = 0;
- static uint8_t prefix; //item prefix - type and tag
- uint8_t byte_toparse;
- uint8_t bType;
- uint8_t tmpbyte;
- /**/
- while( 1 ) {
- if( pkt_size ) {
- byte_toparse = Max.regRd( rRCVFIFO ); //read a byte from FIFO
- pkt_size--;
- }
- else {
- return; //all bytes read
- }
- switch( state ) {
- case ITEM_START: //start of the record
- prefix = byte_toparse >>2; //store prefix for databyte parsing
- tmpbyte = byte_toparse & B_SIZE;
- /* get item length */
- ( tmpbyte == 0x03 ) ? databytes_left = 4 : databytes_left = tmpbyte;
- if( databytes_left ) {
- state = DATA_PARSE; //read bytes after prefix
- }
- printProgStr(PSTR("\r\nLength: "));
- Serial.print( databytes_left, DEC );
- /* get item type */
- bType = ( byte_toparse & B_TYPE ) >>2;
- printProgStr(PSTR(" Type: "));
- printProgStr((char*)pgm_read_word(&btypes[ bType ]));
- /* get item tag */
- printProgStr(PSTR("\t\tTag: "));
- tmpbyte = ( byte_toparse & B_TAG ) >>4 ;
- switch( bType ) {
- case 0: //Main
- if( tmpbyte < 0x08 ) {
- printProgStr(PSTR("Invalid Tag"));
- }
- else if( tmpbyte > 0x0c ) {
- printProgStr( reserved_msg );
- }
- else {
- printProgStr((char*)pgm_read_word(&maintags[ tmpbyte - 8 /* & 0x03 */]));
- //Serial.print("Byte: ");
- //Serial.println( tmpbyte, HEX );
- }
- break;//case 0 Main
- case 1: //Global
- ( tmpbyte > 0x0b ) ? printProgStr( reserved_msg ) : printProgStr((char*)pgm_read_word(&globaltags[ tmpbyte ]));
- break;//case 1 Global
- case 2: //Local
- ( tmpbyte > 0x0a ) ? printProgStr( reserved_msg ) : printProgStr((char*)pgm_read_word(&localtags[ tmpbyte ]));
- break;//case 2 Local
- default:
- break;
- }//switch( bType...
- break;//case ITEM_START
- case DATA_PARSE:
- switch( prefix ) {
- case 0x20: //Main Input
- case 0x24: //Main Output
- case 0x2c: //Main Feature
- /* todo: add parsing 8th bit */
- print_mainbitfield( byte_toparse );
- break;
- case 0x28: //Main Collection
- if(( byte_toparse > 0x06 ) && ( byte_toparse < 0x80 )) {
- printProgStr( reserved_msg );
- }
- else if(( byte_toparse > 0x7f ) && ( byte_toparse <= 0xff )) {
- printProgStr(PSTR("Vendor-defined"));
- }
- else {
- printProgStr((char*)pgm_read_word(&collections[ byte_toparse ]));
- }
- break;//case 0x28 Main Collection
- //case 0x30: //Main End Collection
- case 0x01: //Global Usage Page
- switch( byte_toparse ) { //see HID Usage Tables doc v.1.12 page 14
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0c:
- case 0x0d:
- case 0x0e:
- case 0x0f:
- case 0x10:
- printProgStr((char*)pgm_read_word(&usage_pages[ byte_toparse ]));
- break;
- case 0x14:
- printProgStr(PSTR("Alphanumeric Display"));
- break;
- case 0x40:
- printProgStr(PSTR("Medical Instruments"));
- break;
- case 0x80:
- case 0x81:
- case 0x82:
- case 0x83:
- printProgStr(PSTR("Monitor page"));
- break;
- case 0x84:
- case 0x85:
- case 0x86:
- case 0x87:
- printProgStr(PSTR("Power page"));
- break;
- case 0x8c:
- printProgStr(PSTR("Bar Code Scanner page"));
- break;
- case 0x8d:
- printProgStr(PSTR("Scale page"));
- break;
- case 0x8e:
- printProgStr(PSTR("Magnetic Stripe Reading (MSR) Devices"));
- break;
- case 0x8f:
- printProgStr(PSTR("Reserved Point of Sale pages"));
- break;
- case 0x90:
- printProgStr(PSTR("Camera Control Page"));
- break;
- case 0x91:
- printProgStr(PSTR("Arcade Page"));
- break;
- default:
-// printProgStr(PSTR("Data: "));
-// print_hex( byte_toparse, 8 );
- //databytes_left--;
- break;
- }//switch case 0x01: //Global Usage Page
- }//switch( prefix ...
- printProgStr(PSTR(" Data: "));
- print_hex( byte_toparse, 8 );
- databytes_left--;
- if( !databytes_left ) {
- state = ITEM_START;
- }
- break;
- }//switch( state...
- }//while( 1 ...
-}
-/* prints hex numbers with leading zeroes */
-// copyright, Peter H Anderson, Baltimore, MD, Nov, '07
-// source: http://www.phanderson.com/arduino/arduino_display.html
-void print_hex(int v, int num_places)
-{
- int mask=0, n, num_nibbles, digit;
-
- for (n=1; n<=num_places; n++) {
- mask = (mask << 1) | 0x0001;
- }
- v = v & mask; // truncate v to specified number of places
-
- num_nibbles = num_places / 4;
- if ((num_places % 4) != 0) {
- ++num_nibbles;
- }
- do {
- digit = ((v >> (num_nibbles-1) * 4)) & 0x0f;
- Serial.print(digit, HEX);
- }
- while(--num_nibbles);
-}
-
-/* given a PROGMEM string, use Serial.print() to send it out */
-/* Some non-intuitive casting necessary: */
-/* printProgStr(PSTR("Func.Mode:\t0x")); */
-/* printProgStr((char*)pgm_read_word(&mtpopNames[(op & 0xFF)])); */
-void printProgStr(const char* str)
-{
- if(!str) {
- return;
- }
- char c;
- while((c = pgm_read_byte(str++))) {
- Serial.print(c,BYTE);
- }
- return;
-}