From 666e0c0142201e09ee077dd50bb284b416857124 Mon Sep 17 00:00:00 2001 From: Oleg Mazurov Date: Thu, 30 Jun 2011 22:31:46 -0600 Subject: [PATCH 1/6] adk initial --- adk.cpp | 469 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ adk.h | 120 +++++++++++++++ 2 files changed, 589 insertions(+) create mode 100644 adk.cpp create mode 100644 adk.h diff --git a/adk.cpp b/adk.cpp new file mode 100644 index 00000000..3e61096b --- /dev/null +++ b/adk.cpp @@ -0,0 +1,469 @@ +/* Google ADK interface */ + +#include "adk.h" + +const uint8_t ADK::epDataInIndex = 1; +const uint8_t ADK::epDataOutIndex = 2; + +ADK::ADK(USB *p, const char* manufacturer, + const char* model, + const char* description, + const char* version, + const char* uri, + const char* serial) : + + pUsb(p), //pointer to USB class instance - mandatory for each driver + manufacturer(manufacturer), + model(model), + description(description), + version(version), + uri(uri), + serial(serial), + + bAddress(0), //device address - mandatory for each driver + bNumEP(1) //if config descriptor needs to be parsed +{ + /* initialize endpoint data structures */ + for(uint8_t i=0; iRegisterDeviceClass(this); +} +/* Android initialization. Performed in 2 steps: + 1. If new device answers to vendor-specific request, another request switched device to accessory mode. + The device is then reset and comes up on a bus with different VID/PID. + 2. After detecting by VID/PID enpoints are extracted and device is configured +*/ +uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) +{ + const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR); + + uint8_t buf[constBufSize]; + uint8_t rcode; + UsbDevice *p = NULL; + EpInfo *oldep_ptr = NULL; + uint8_t num_of_conf; // number of configurations + + // get memory address of USB device address pool + AddressPool &addrPool = pUsb->GetAddressPool(); + + USBTRACE("\r\nADK Init"); + + + // check if address has already been assigned to an instance + if (bAddress) + return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; + + // Get pointer to pseudo device with address 0 assigned + p = addrPool.GetUsbDevicePtr(0); + + if (!p) + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + + if (!p->epinfo) { + USBTRACE("epinfo is null\r\n"); + return USB_ERROR_EPINFO_IS_NULL; + } + + // Save old pointer to EP_RECORD of address 0 + oldep_ptr = p->epinfo; + + // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence + p->epinfo = epInfo; + + p->lowspeed = lowspeed; + + // Get device descriptor + rcode = pUsb->getDevDescr( 0, 0, constBufSize, (uint8_t*)buf ); + + // Restore p->epinfo + p->epinfo = oldep_ptr; + + if( rcode ){ + goto FailGetDevDescr; + } + + // Allocate new address according to device class + bAddress = addrPool.AllocAddress(parent, false, port); + if (!bAddress) { + return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; + } + + // Extract Max Packet Size from the device descriptor + epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; + + /* debug code start */ + num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; + USBTRACE2("\r\nNum.conf: ", num_of_conf ); + for (uint8_t i=0; i HexDump; + //USBTRACE("\r\nHexdumper2: "); + //ConfigDescParser<0, 0, 0, + // 0> confDescrParser(this); + + rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); + //rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); + + } // for (uint8_t i=0; iidVendor == ADK_VID && + (((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID)){ + USBTRACE("\r\nAcc.mode device detected"); + + + // Allocate new address + //bAddress = addrPool.AllocAddress(parent, false, port); + + if (!bAddress) { + return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; + } + + // Extract Max Packet Size from the device descriptor + epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; + + // Assign new address to the device + rcode = pUsb->setAddr( 0, 0, bAddress ); + + if (rcode) { + p->lowspeed = false; + addrPool.FreeAddress(bAddress); + bAddress = 0; + USBTRACE2("setAddr:",rcode); + return rcode; + } + + USBTRACE2("\r\nAddr: ", bAddress); + + p->lowspeed = false; + + p = addrPool.GetUsbDevicePtr(bAddress); + + if (!p) { + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + } + + p->lowspeed = lowspeed; + + // Assign epInfo to epinfo pointer + // rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); +/* + if (rcode) { + goto FailSetDevTblEntry; + } + */ + /* initialize endpoint structures */ + + // Assign epInfo to epinfo pointer + //rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); + + USBTRACE2("Conf:", 1); + + // Set Configuration Value + rcode = pUsb->setConf(bAddress, 0, bConfNum); + + if (rcode) { + goto FailSetConf; + } + + return 0; //successful configuration + }//if( buf->idVendor == ADK_VID... + + //probe device - get accessory protocol revision + { + uint16_t adkproto = -1; + rcode = getProto((uint8_t*)&adkproto ); + if( rcode ){ + goto FailGetProto; //init fails + } + USBTRACE2("\r\nADK protocol rev. ", adkproto ); + } + + //load ID strings and switch to accessory mode + rcode = switchAcc(); + if( rcode ) { + goto FailSwAcc; //init fails + } + rcode = -1; + goto SwAttempt; //switch to accessory mode attempted + +// +// // Allocate new address according to device class +// bAddress = addrPool.AllocAddress(parent, false, port); +// +// if (!bAddress) +// return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; +// +// // Extract Max Packet Size from the device descriptor +// epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; +// +// // Assign new address to the device +// rcode = pUsb->setAddr( 0, 0, bAddress ); +// +// if (rcode) +// { +// p->lowspeed = false; +// addrPool.FreeAddress(bAddress); +// bAddress = 0; +// USBTRACE2("setAddr:",rcode); +// return rcode; +// } +// +// USBTRACE2("Addr:", bAddress); +// +// p->lowspeed = false; +// +// p = addrPool.GetUsbDevicePtr(bAddress); +// +// if (!p) +// return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; +// +// p->lowspeed = lowspeed; +// +// num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; +// +// // Assign epInfo to epinfo pointer +// rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); +// +// if (rcode) +// goto FailSetDevTblEntry; +// +// USBTRACE2("NC:", num_of_conf); +// +// for (uint8_t i=0; i CdcControlParser(this); +// +// ConfigDescParser CdcDataParser(this); +// +// rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcControlParser); +// rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcDataParser); +// +// if (bNumEP > 1) +// break; +// } // for +// +// if (bNumEP < 4) +// return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; +// +// // Assign epInfo to epinfo pointer +// rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); +// +// USBTRACE2("Conf:", bConfNum); +// +// // Set Configuration Value +// rcode = pUsb->setConf(bAddress, 0, bConfNum); +// +// if (rcode) +// goto FailSetConf; +// +// rcode = pAsync->OnInit(this); +// +// if (rcode) +// goto FailOnInit; +// +// USBTRACE("ACM configured\r\n"); +// +// //bPollEnable = true; +// +// //USBTRACE("Poll enabled\r\n"); +// return 0; +// +FailGetDevDescr: + USBTRACE("\r\ngetDevDescr:"); + goto Fail; + +FailGetProto: + USBTRACE("\r\ngetProto:"); + goto Fail; + +FailSwAcc: + USBTRACE("\r\nswAcc:"); + goto Fail; + +SwAttempt: + USBTRACE("\r\nAccessory mode switch attempt"); + goto Fail; + +//FailSetDevTblEntry: +// USBTRACE("setDevTblEn:"); +// goto Fail; +// +//FailGetConfDescr: +// USBTRACE("getConf:"); +// goto Fail; +// +FailSetConf: + USBTRACE("\r\nsetConf: "); + goto Fail; +// +//FailOnInit: +// USBTRACE("OnInit:"); +// goto Fail; +// +Fail: + USBTRACE2("\r\nADK Init Failed, error code: ", rcode); + //Release(); + return rcode; +} + + +//void ACM::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) +//{ +// ErrorMessage(PSTR("Conf.Val"), conf); +// ErrorMessage(PSTR("Iface Num"),iface); +// ErrorMessage(PSTR("Alt.Set"), alt); +// +// bConfNum = conf; +// +// uint8_t index; +// +// if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) +// index = epInterruptInIndex; +// else +// if ((pep->bmAttributes & 0x02) == 2) +// index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; +// else +// return; +// +// // Fill in the endpoint info structure +// epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); +// epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; +// epInfo[index].epAttribs = 0; +// +// bNumEP ++; +// +// PrintEndpointDescriptor(pep); +//} + +uint8_t ADK::Release() +{ +// pUsb->GetAddressPool().FreeAddress(bAddress); +// +// bControlIface = 0; +// bDataIface = 0; +// bNumEP = 1; //must have to be reset to 1 +// +// bAddress = 0; +// qNextPollTime = 0; +// bPollEnable = false; + return 0; +} + +uint8_t ADK::Poll() +{ + uint8_t rcode = 0; + + if (!bPollEnable) + return 0; + + uint32_t time_now = millis(); + + if (qNextPollTime <= time_now) + { + qNextPollTime = time_now + 100; + + uint8_t rcode; + const uint8_t constBufSize = 16; + uint8_t buf[constBufSize]; + + for (uint8_t i=0; i epInfo[epInterruptInIndex].maxPktSize) +// ? epInfo[epInterruptInIndex].maxPktSize : constBufSize; +// rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf); + + if (rcode) + return rcode; + +// for (uint8_t i=0; i(buf[i]); +// Serial.print(" "); +// } +// USBTRACE("\r\n"); + } + return rcode; +} + +uint8_t ADK::RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) +{ + return pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr); +} + +uint8_t ADK::SndData(uint16_t nbytes, uint8_t *dataptr) +{ + return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr); +} + +//uint8_t ACM::SetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL )); +//} +// +//uint8_t ACM::GetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCIN, CDC_GET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL )); +//} +// +//uint8_t ACM::ClearCommFeature(uint16_t fid) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_CLEAR_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, 0, 0, NULL, NULL )); +//} +// +//uint8_t ACM::SetLineCoding(const LINE_CODING *dataptr) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof(LINE_CODING), sizeof(LINE_CODING), (uint8_t*)dataptr, NULL )); +//} +// +//uint8_t ACM::GetLineCoding(LINE_CODING *dataptr) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCIN, CDC_GET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof(LINE_CODING), sizeof(LINE_CODING), (uint8_t*)dataptr, NULL )); +//} +// +//uint8_t ACM::SetControlLineState(uint8_t state) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_CONTROL_LINE_STATE, state, 0, bControlIface, 0, 0, NULL, NULL )); +//} +// +//uint8_t ACM::SendBreak(uint16_t duration) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SEND_BREAK, (duration & 0xff), (duration >> 8), bControlIface, 0, 0, NULL, NULL )); +//} +// +// +//void ACM::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr ) +//{ +// Notify(PSTR("Endpoint descriptor:")); +// Notify(PSTR("\r\nLength:\t\t")); +// PrintHex(ep_ptr->bLength); +// Notify(PSTR("\r\nType:\t\t")); +// PrintHex(ep_ptr->bDescriptorType); +// Notify(PSTR("\r\nAddress:\t")); +// PrintHex(ep_ptr->bEndpointAddress); +// Notify(PSTR("\r\nAttributes:\t")); +// PrintHex(ep_ptr->bmAttributes); +// Notify(PSTR("\r\nMaxPktSize:\t")); +// PrintHex(ep_ptr->wMaxPacketSize); +// Notify(PSTR("\r\nPoll Intrv:\t")); +// PrintHex(ep_ptr->bInterval); +// Notify(PSTR("\r\n")); +//} diff --git a/adk.h b/adk.h new file mode 100644 index 00000000..14d961c9 --- /dev/null +++ b/adk.h @@ -0,0 +1,120 @@ +/* Google ADK interface support header */ + +#if !defined(_ADK_H_) +#define _ADK_H_ + +#include +#include +#include "avrpins.h" +#include "max3421e.h" +#include "usbhost.h" +#include "usb_ch9.h" +#include "Usb.h" +#include + +#include "printhex.h" +#include "hexdump.h" +#include "message.h" + +#include "confdescparser.h" + +#define ADK_VID 0x18D1 +#define ADK_PID 0x2D00 +#define ADB_PID 0x2D01 + +/* requests */ + +#define ADK_GETPROTO 51 //check USB accessory protocol version +#define ADK_SENDSTR 52 //send identifying string +#define ADK_ACCSTART 53 //start device in accessory mode + +#define bmREQ_ADK_GET USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_VENDOR|USB_SETUP_RECIPIENT_DEVICE +#define bmREQ_ADK_SEND USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_VENDOR|USB_SETUP_RECIPIENT_DEVICE + +#define ACCESSORY_STRING_MANUFACTURER 0 +#define ACCESSORY_STRING_MODEL 1 +#define ACCESSORY_STRING_DESCRIPTION 2 +#define ACCESSORY_STRING_VERSION 3 +#define ACCESSORY_STRING_URI 4 +#define ACCESSORY_STRING_SERIAL 5 + +#define ADK_MAX_ENDPOINTS 3 //endpoint 0, bulk_IN, bulk_OUT + +class ADK; + +class ADK : public USBDeviceConfig +{ +private: + /* ID strings */ + const char* manufacturer; + const char* model; + const char* description; + const char* version; + const char* uri; + const char* serial; + + /* ADK proprietary requests */ + uint8_t getProto( uint8_t* adkproto ); + uint8_t sendStr( uint8_t index, const char* str ); + uint8_t switchAcc( void ); + +protected: + static const uint8_t epDataInIndex; // DataIn endpoint index + static const uint8_t epDataOutIndex; // DataOUT endpoint index + + /* mandatory members */ + USB *pUsb; + uint8_t bAddress; + uint8_t bConfNum; // configuration number + uint8_t bControlIface; // Control interface value + uint8_t bDataIface; // Data interface value + uint8_t bNumEP; // total number of EP in the configuration + uint32_t qNextPollTime; // next poll time + bool bPollEnable; // poll enable flag + //uint8_t bInitState; //initialization state machine state + + /* Endpoint data structure */ + EpInfo epInfo[ADK_MAX_ENDPOINTS]; + + // void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); + +public: + ADK(USB *pUsb, const char* manufacturer, + const char* model, + const char* description, + const char* version, + const char* uri, + const char* serial); + + // Methods for recieving and sending data + uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr); + uint8_t SndData(uint16_t nbytes, uint8_t *dataptr); + + + // USBDeviceConfig implementation + virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed); + virtual uint8_t Release(); + virtual uint8_t Poll(); + virtual uint8_t GetAddress() { return bAddress; }; + + // UsbConfigXtracter implementation + // virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); +}; //class ADK : public USBDeviceConfig ... +/* get ADK protocol version */ +/* returns 2 bytes in *adkproto */ +inline uint8_t ADK::getProto( uint8_t* adkproto ) +{ + return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_GET, ADK_GETPROTO, 0, 0, 0, 2, 2, adkproto, NULL )); +} +/* send ADK string */ +inline uint8_t ADK::sendStr( uint8_t index, const char* str ) +{ + return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_SENDSTR, 0, 0, index, strlen(str) + 1, strlen(str) + 1, (uint8_t*)str, NULL)); +} +/* switch to accessory mode */ +inline uint8_t ADK::switchAcc( void ) +{ + return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_ACCSTART, 0, 0, 0, 0, 0, NULL, NULL)); +} + +#endif // _ADK_H_ \ No newline at end of file From ce6aa49501ef7a016913cf19c1c18b04d54160a3 Mon Sep 17 00:00:00 2001 From: Oleg Mazurov Date: Thu, 30 Jun 2011 23:09:46 -0600 Subject: [PATCH 2/6] 063011 --- Usb.cpp | 8 +- Usb.h | 6 +- hid.cpp | 90 +++++++++----- hid.h | 31 ++--- masstorage.cpp | 328 +++++++++++++++++++++++++++++++++++++++++++++++++ masstorage.h | 46 ++++--- 6 files changed, 432 insertions(+), 77 deletions(-) create mode 100644 masstorage.cpp diff --git a/Usb.cpp b/Usb.cpp index 992f57e1..8d51be40 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -234,7 +234,9 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) return ( 0xf0 ); //receive error - pktsize = regRd( rRCVBC ); //number of received bytes */ + pktsize = regRd( rRCVBC ); //number of received bytes + + assert(pktsize <= nbytes); int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr); @@ -249,10 +251,10 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui /* The transfer is complete under two conditions: */ /* 1. The device sent a short packet (L.T. maxPacketSize) */ /* 2. 'nbytes' have been transferred. */ - if (/*pktsize == 6 ||*/ ( pktsize < maxpktsize ) || (*nbytesptr >= nbytes )) // have we transferred 'nbytes' bytes? + if (( pktsize < maxpktsize ) || (*nbytesptr >= nbytes )) // have we transferred 'nbytes' bytes? { // Save toggle value - pep->bmRcvToggle = ( regRd( rHRSL ) & bmRCVTOGRD ) ? 1 : 0; + pep->bmRcvToggle = (( regRd( rHRSL ) & bmRCVTOGRD )) ? 1 : 0; return( 0 ); } // if diff --git a/Usb.h b/Usb.h index d331a09b..5a81e80c 100644 --- a/Usb.h +++ b/Usb.h @@ -21,6 +21,9 @@ e-mail : support@circuitsathome.com #define USB_METHODS_INLINE #include + +#include + #include "avrpins.h" #include "max3421e.h" #include "usbhost.h" @@ -120,9 +123,6 @@ public: #define USB_STATE_RUNNING 0x90 #define USB_STATE_ERROR 0xa0 - -// byte usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE - /* USB Setup Packet Structure */ typedef struct { union { // offset description diff --git a/hid.cpp b/hid.cpp index 3c53bbc9..225ac7d3 100644 --- a/hid.cpp +++ b/hid.cpp @@ -1,19 +1,3 @@ -/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. - -This software may be distributed and modified under the terms of the GNU -General Public License version 2 (GPL2) as published by the Free Software -Foundation and appearing in the file GPL2.TXT included in the packaging of -this file. Please note that GPL2 Section 2[b] requires that all works based -on this software must also be made publicly available under the terms of -the GPL2 ("Copyleft"). - -Contact information -------------------- - -Circuits At Home, LTD -Web : http://www.circuitsathome.com -e-mail : support@circuitsathome.com -*/ #include "hid.h" //const uint16_t HID::maxHidInterfaces = 3; @@ -316,13 +300,13 @@ uint8_t HID::Poll() if (qNextPollTime <= millis()) { - qNextPollTime = millis() + 100; + qNextPollTime = millis() + 500; const uint8_t const_buff_len = 16; uint8_t buf[const_buff_len]; HexDumper Hex; - uint16_t read = (uint16_t)const_buff_len; + uint16_t read = (uint16_t)epInfo[epInterruptInIndex].maxPktSize; uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf); @@ -395,6 +379,22 @@ void ReportDescParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint //if (ParseItem(&p, &cntdn)) // return; } + USBTRACE2("Total:", totalSize); +} + +void ReportDescParser::PrintValue(uint8_t *p, uint8_t len) +{ + Notify(PSTR("(")); + for (; len; p++, len--) + PrintHex(*p); + Notify(PSTR(")")); +} + +void ReportDescParser::PrintByteValue(uint8_t data) +{ + Notify(PSTR("(")); + PrintHex(data); + Notify(PSTR(")")); } uint8_t ReportDescParser::ParseItem(uint8_t **pp, uint16_t *pcntdn) @@ -404,6 +404,11 @@ uint8_t ReportDescParser::ParseItem(uint8_t **pp, uint16_t *pcntdn) switch (itemParseState) { case 0: + if (**pp == HID_LONG_ITEM_PREFIX) + USBTRACE("\r\nLONG\r\n"); + //totalSize = 0; + //rptSize = 0; + //rptCount = 0; //if (**pp == HID_LONG_ITEM_PREFIX) //{ // *pp ++; @@ -417,12 +422,19 @@ uint8_t ReportDescParser::ParseItem(uint8_t **pp, uint16_t *pcntdn) //else { uint8_t size = ((**pp) & DATA_SIZE_MASK); + + USBTRACE2("\r\nSZ:", size); + itemPrefix = (**pp); itemSize = 1 + ((size == DATA_SIZE_4) ? 4 : size); - //USBTRACE2("Sz1:", size); - //Serial.print("\r\nSz:"); - //Serial.println(itemSize,DEC); + Serial.print("\r\nSz:"); + Serial.println(itemSize,DEC); + + PrintHex(*pcntdn); + Serial.print(":"); + PrintHex((itemPrefix & (TYPE_MASK | TAG_MASK))); + Serial.println(""); switch (itemPrefix & (TYPE_MASK | TAG_MASK)) { @@ -518,21 +530,29 @@ uint8_t ReportDescParser::ParseItem(uint8_t **pp, uint16_t *pcntdn) pfUsage(*((uint16_t*)varBuffer)); else pfUsage(data); + case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE): + rptSize = data; + PrintByteValue(data); + break; + case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT): + rptCount = data; + PrintByteValue(data); + break; case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMIN): case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMAX): case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMIN): case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMAX): - case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE): - case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT): case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID): case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN): case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX): case (TYPE_GLOBAL | TAG_GLOBAL_UNITEXP): case (TYPE_GLOBAL | TAG_GLOBAL_UNIT): - Notify(PSTR("(")); - for (uint8_t i=0; i(data); - Notify(PSTR(")")); + PrintValue(varBuffer, theBuffer.valueSize); + //Notify(PSTR("(")); + //for (uint8_t i=0; i(varBuffer[i]); + // //PrintHex(data); + //Notify(PSTR(")")); break; case (TYPE_GLOBAL | TAG_GLOBAL_PUSH): case (TYPE_GLOBAL | TAG_GLOBAL_POP): @@ -540,11 +560,7 @@ uint8_t ReportDescParser::ParseItem(uint8_t **pp, uint16_t *pcntdn) case (TYPE_GLOBAL | TAG_GLOBAL_USAGEPAGE): SetUsagePage(data); PrintUsagePage(data); - - Notify(PSTR("(")); - for (uint8_t i=0; i(data); - Notify(PSTR(")")); + PrintByteValue(data); break; case (TYPE_MAIN | TAG_MAIN_COLLECTION): case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION): @@ -580,6 +596,9 @@ uint8_t ReportDescParser::ParseItem(uint8_t **pp, uint16_t *pcntdn) case (TYPE_MAIN | TAG_MAIN_INPUT): case (TYPE_MAIN | TAG_MAIN_OUTPUT): case (TYPE_MAIN | TAG_MAIN_FEATURE): + totalSize += (uint16_t)rptSize * (uint16_t)rptCount; + rptSize = 0; + rptCount = 0; Notify(PSTR("(")); PrintBin(data); Notify(PSTR(")")); @@ -588,6 +607,13 @@ uint8_t ReportDescParser::ParseItem(uint8_t **pp, uint16_t *pcntdn) } itemParseState = 4; case 4: + USBTRACE2("iSz:", itemSize); + + PrintHex(*pcntdn); + Serial.print(":"); + PrintHex((itemPrefix & (TYPE_MASK | TAG_MASK))); + Serial.println(""); + if (itemSize > 1 && !theSkipper.Skip(pp, pcntdn, itemSize)) return enErrorIncomplete; } // switch (itemParseState) diff --git a/hid.h b/hid.h index 0f41e7e5..9c3be7c5 100644 --- a/hid.h +++ b/hid.h @@ -1,19 +1,3 @@ -/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. - -This software may be distributed and modified under the terms of the GNU -General Public License version 2 (GPL2) as published by the Free Software -Foundation and appearing in the file GPL2.TXT included in the packaging of -this file. Please note that GPL2 Section 2[b] requires that all works based -on this software must also be made publicly available under the terms of -the GPL2 ("Copyleft"). - -Contact information -------------------- - -Circuits At Home, LTD -Web : http://www.circuitsathome.com -e-mail : support@circuitsathome.com -*/ #if !defined(__HID_H__) #define __HID_H__ @@ -26,9 +10,9 @@ e-mail : support@circuitsathome.com #include "Usb.h" #include -#include "printhex.h" -#include "hexdump.h" -#include "message.h" +#include "..\DebugTools\printhex.h" +#include "..\DebugTools\hexdump.h" +#include "..\DebugTools\message.h" #include "confdescparser.h" @@ -180,6 +164,9 @@ public: static void PrintAlphanumDisplayPageUsage(uint16_t usage); static void PrintMedicalInstrumentPageUsage(uint16_t usage); + static void PrintValue(uint8_t *p, uint8_t len); + static void PrintByteValue(uint8_t data); + private: static UsagePageFunc usagePageFunctions[]; @@ -191,6 +178,10 @@ private: uint8_t itemParseState; // Item parser state variable uint8_t itemSize; // Item size uint8_t itemPrefix; // Item prefix (first byte) + uint8_t rptSize; // Report Size + uint8_t rptCount; // Report Count + + uint8_t totalSize; // Report size in bytes uint8_t ParseItem(uint8_t **pp, uint16_t *pcntdn); @@ -204,6 +195,8 @@ public: itemParseState(0), itemSize(0), itemPrefix(0), + rptSize(0), + rptCount(0), pfUsage(NULL) { theBuffer.pValue = varBuffer; diff --git a/masstorage.cpp b/masstorage.cpp new file mode 100644 index 00000000..21c25202 --- /dev/null +++ b/masstorage.cpp @@ -0,0 +1,328 @@ +#include "masstorage.h" + +const uint8_t BulkOnly::epDataInIndex = 1; +const uint8_t BulkOnly::epDataOutIndex = 2; +const uint8_t BulkOnly::epInterruptInIndex = 3; + +BulkOnly::BulkOnly(USB *p /*, CDCAsyncOper *pasync*/) : + pUsb(p), + //pAsync(pasync), + bAddress(0), + qNextPollTime(0), + bPollEnable(false), + bIface(0), + bNumEP(1) +{ + for(uint8_t i=0; iRegisterDeviceClass(this); +} + +uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) +{ + const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR); + + uint8_t buf[constBufSize]; + uint8_t rcode; + UsbDevice *p = NULL; + EpInfo *oldep_ptr = NULL; + uint8_t num_of_conf; // number of configurations + + AddressPool &addrPool = pUsb->GetAddressPool(); + + USBTRACE("MS Init\r\n"); + + if (bAddress) + return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; + + // Get pointer to pseudo device with address 0 assigned + p = addrPool.GetUsbDevicePtr(0); + + if (!p) + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + + if (!p->epinfo) + { + USBTRACE("epinfo\r\n"); + return USB_ERROR_EPINFO_IS_NULL; + } + + // Save old pointer to EP_RECORD of address 0 + oldep_ptr = p->epinfo; + + // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence + p->epinfo = epInfo; + + p->lowspeed = lowspeed; + + // Get device descriptor + rcode = pUsb->getDevDescr( 0, 0, constBufSize, (uint8_t*)buf ); + + // Restore p->epinfo + p->epinfo = oldep_ptr; + + if( rcode ) + goto FailGetDevDescr; + + // Allocate new address according to device class + bAddress = addrPool.AllocAddress(parent, false, port); + + if (!bAddress) + return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; + + // Extract Max Packet Size from the device descriptor + epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; + + // Assign new address to the device + rcode = pUsb->setAddr( 0, 0, bAddress ); + + if (rcode) + { + p->lowspeed = false; + addrPool.FreeAddress(bAddress); + bAddress = 0; + USBTRACE2("setAddr:",rcode); + return rcode; + } + + USBTRACE2("Addr:", bAddress); + + p->lowspeed = false; + + p = addrPool.GetUsbDevicePtr(bAddress); + + if (!p) + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + + p->lowspeed = lowspeed; + + num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; + + // Assign epInfo to epinfo pointer + rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); + + if (rcode) + goto FailSetDevTblEntry; + + USBTRACE2("NC:", num_of_conf); + + for (uint8_t i=0; i HexDump; + ConfigDescParser< USB_CLASS_MASS_STORAGE, + MASS_SUBCLASS_SCSI, + MASS_PROTO_BBB, + CP_MASK_COMPARE_CLASS | + CP_MASK_COMPARE_SUBCLASS | + CP_MASK_COMPARE_PROTOCOL> BulkOnlyParser(this); + + rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); + rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser); + + + if (bNumEP > 1) + break; + } // for + + if (bNumEP < 4) + return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; + + // Assign epInfo to epinfo pointer + rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); + + USBTRACE2("Conf:", bConfNum); + + // Set Configuration Value + rcode = pUsb->setConf(bAddress, 0, bConfNum); + + if (rcode) + goto FailSetConf; + + //rcode = pAsync->OnInit(this); + + if (rcode) + goto FailOnInit; + + USBTRACE("MS configured\r\n"); + + //bPollEnable = true; + + //USBTRACE("Poll enabled\r\n"); + return 0; + +FailGetDevDescr: + USBTRACE("getDevDescr:"); + goto Fail; + +FailSetDevTblEntry: + USBTRACE("setDevTblEn:"); + goto Fail; + +FailGetConfDescr: + USBTRACE("getConf:"); + goto Fail; + +FailSetConf: + USBTRACE("setConf:"); + goto Fail; + +FailOnInit: + USBTRACE("OnInit:"); + goto Fail; + +Fail: + Serial.println(rcode, HEX); + Release(); + return rcode; +} + + +void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) +{ + ErrorMessage(PSTR("Conf.Val"), conf); + ErrorMessage(PSTR("Iface Num"),iface); + ErrorMessage(PSTR("Alt.Set"), alt); + + bConfNum = conf; + + uint8_t index; + + if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) + index = epInterruptInIndex; + else + if ((pep->bmAttributes & 0x02) == 2) + index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; + else + return; + + // Fill in the endpoint info structure + epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); + epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; + epInfo[index].epAttribs = 0; + + bNumEP ++; + + PrintEndpointDescriptor(pep); +} + +uint8_t BulkOnly::Release() +{ + pUsb->GetAddressPool().FreeAddress(bAddress); + + bIface = 0; + bNumEP = 1; + + bAddress = 0; + qNextPollTime = 0; + bPollEnable = false; + return 0; +} + +uint8_t BulkOnly::Poll() +{ + uint8_t rcode = 0; + + if (!bPollEnable) + return 0; + + uint32_t time_now = millis(); + + //if (qNextPollTime <= time_now) + //{ + // qNextPollTime = time_now + 100; + + // uint8_t rcode; + // const uint8_t constBufSize = 16; + // uint8_t buf[constBufSize]; + + // for (uint8_t i=0; i epInfo[epInterruptInIndex].maxPktSize) + // ? epInfo[epInterruptInIndex].maxPktSize : constBufSize; + // rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf); + + // if (rcode) + // return rcode; + + // for (uint8_t i=0; i(buf[i]); + // Serial.print(" "); + // } + // USBTRACE("\r\n"); + //} + return rcode; +} + +//uint8_t ACM::RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) +//{ +// return pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr); +//} +// +//uint8_t ACM::SndData(uint16_t nbytes, uint8_t *dataptr) +//{ +// return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr); +//} +// +//uint8_t ACM::SetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL )); +//} +// +//uint8_t ACM::GetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCIN, CDC_GET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL )); +//} +// +//uint8_t ACM::ClearCommFeature(uint16_t fid) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_CLEAR_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, 0, 0, NULL, NULL )); +//} +// +//uint8_t ACM::SetLineCoding(const LINE_CODING *dataptr) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof(LINE_CODING), sizeof(LINE_CODING), (uint8_t*)dataptr, NULL )); +//} +// +//uint8_t ACM::GetLineCoding(LINE_CODING *dataptr) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCIN, CDC_GET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof(LINE_CODING), sizeof(LINE_CODING), (uint8_t*)dataptr, NULL )); +//} +// +//uint8_t ACM::SetControlLineState(uint8_t state) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_CONTROL_LINE_STATE, state, 0, bControlIface, 0, 0, NULL, NULL )); +//} +// +//uint8_t ACM::SendBreak(uint16_t duration) +//{ +// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SEND_BREAK, (duration & 0xff), (duration >> 8), bControlIface, 0, 0, NULL, NULL )); +//} + + +void BulkOnly::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr ) +{ + Notify(PSTR("Endpoint descriptor:")); + Notify(PSTR("\r\nLength:\t\t")); + PrintHex(ep_ptr->bLength); + Notify(PSTR("\r\nType:\t\t")); + PrintHex(ep_ptr->bDescriptorType); + Notify(PSTR("\r\nAddress:\t")); + PrintHex(ep_ptr->bEndpointAddress); + Notify(PSTR("\r\nAttributes:\t")); + PrintHex(ep_ptr->bmAttributes); + Notify(PSTR("\r\nMaxPktSize:\t")); + PrintHex(ep_ptr->wMaxPacketSize); + Notify(PSTR("\r\nPoll Intrv:\t")); + PrintHex(ep_ptr->bInterval); + Notify(PSTR("\r\n")); +} diff --git a/masstorage.h b/masstorage.h index 2d667ad9..4126c9a8 100644 --- a/masstorage.h +++ b/masstorage.h @@ -1,19 +1,3 @@ -/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. - -This software may be distributed and modified under the terms of the GNU -General Public License version 2 (GPL2) as published by the Free Software -Foundation and appearing in the file GPL2.TXT included in the packaging of -this file. Please note that GPL2 Section 2[b] requires that all works based -on this software must also be made publicly available under the terms of -the GPL2 ("Copyleft"). - -Contact information -------------------- - -Circuits At Home, LTD -Web : http://www.circuitsathome.com -e-mail : support@circuitsathome.com -*/ #if !defined(__MASSTORAGE_H__) #define __MASSTORAGE_H__ @@ -26,9 +10,9 @@ e-mail : support@circuitsathome.com #include "Usb.h" #include -#include "printhex.h" -#include "hexdump.h" -#include "message.h" +#include "..\DebugTools\printhex.h" +#include "..\DebugTools\hexdump.h" +#include "..\DebugTools\message.h" #include "confdescparser.h" @@ -73,7 +57,7 @@ struct CommandBlockWrapper struct { uint8_t bCBWLUN : 4; - uint8_r bReserved1 : 4; + uint8_t bReserved1 : 4; }; struct { @@ -92,9 +76,31 @@ struct CommandStatusWrapper uint8_t bCSWStatus; }; +#define MASS_MAX_ENDPOINTS 3 + class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter { +protected: + static const uint8_t epDataInIndex; // DataIn endpoint index + static const uint8_t epDataOutIndex; // DataOUT endpoint index + static const uint8_t epInterruptInIndex; // InterruptIN endpoint index + + USB *pUsb; +// CDCAsyncOper *pAsync; + uint8_t bAddress; + uint8_t bConfNum; // configuration number + uint8_t bIface; // interface value + uint8_t bNumEP; // total number of EP in the configuration + uint32_t qNextPollTime; // next poll time + bool bPollEnable; // poll enable flag + + EpInfo epInfo[MASS_MAX_ENDPOINTS]; + + void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); + public: + BulkOnly(USB *p); + uint8_t Reset(); uint8_t GetMaxLun(uint8_t *max_lun); From 77f64ce1cdb7714e1f09975b7a28a99451a112cd Mon Sep 17 00:00:00 2001 From: Oleg Mazurov Date: Fri, 1 Jul 2011 20:25:50 -0600 Subject: [PATCH 3/6] 20110701 --- adk.cpp | 403 ++++++++++++++++++--------------------------------- adk.h | 6 +- hid.h | 6 +- masstorage.h | 6 +- 4 files changed, 153 insertions(+), 268 deletions(-) diff --git a/adk.cpp b/adk.cpp index 3e61096b..8b0d365b 100644 --- a/adk.cpp +++ b/adk.cpp @@ -12,7 +12,8 @@ ADK::ADK(USB *p, const char* manufacturer, const char* uri, const char* serial) : - pUsb(p), //pointer to USB class instance - mandatory for each driver + pUsb(p), //pointer to USB class instance - mandatory + /* ADK ID Strings */ manufacturer(manufacturer), model(model), description(description), @@ -20,8 +21,8 @@ ADK::ADK(USB *p, const char* manufacturer, uri(uri), serial(serial), - bAddress(0), //device address - mandatory for each driver - bNumEP(1) //if config descriptor needs to be parsed + bAddress(0), //device address - mandatory + bNumEP(1) //if config descriptor needs to be parsed { /* initialize endpoint data structures */ for(uint8_t i=0; iRegisterDeviceClass(this); //set devConfig[] entry } - if (pUsb) - pUsb->RegisterDeviceClass(this); } -/* Android initialization. Performed in 2 steps: - 1. If new device answers to vendor-specific request, another request switched device to accessory mode. - The device is then reset and comes up on a bus with different VID/PID. - 2. After detecting by VID/PID enpoints are extracted and device is configured -*/ + +/* Connect/disconnect initialization of a phone */ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) { const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR); @@ -56,22 +56,28 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) USBTRACE("\r\nADK Init"); - // check if address has already been assigned to an instance - if (bAddress) + if (bAddress) { + USBTRACE("\r\nAddress in use"); return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; + } + + //USBTRACE("\r\nHere"); + // Get pointer to pseudo device with address 0 assigned p = addrPool.GetUsbDevicePtr(0); - if (!p) + if (!p) { + USBTRACE("\r\nAddress not found"); return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - + } + if (!p->epinfo) { USBTRACE("epinfo is null\r\n"); return USB_ERROR_EPINFO_IS_NULL; } - + // Save old pointer to EP_RECORD of address 0 oldep_ptr = p->epinfo; @@ -82,35 +88,65 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) // Get device descriptor rcode = pUsb->getDevDescr( 0, 0, constBufSize, (uint8_t*)buf ); - + // Restore p->epinfo p->epinfo = oldep_ptr; if( rcode ){ goto FailGetDevDescr; } - - // Allocate new address according to device class - bAddress = addrPool.AllocAddress(parent, false, port); - if (!bAddress) { - return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; - } - - // Extract Max Packet Size from the device descriptor - epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; - + + // Allocate new address according to device class + bAddress = addrPool.AllocAddress(parent, false, port); + + // Extract Max Packet Size from device descriptor + epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; + + // Assign new address to the device + rcode = pUsb->setAddr( 0, 0, bAddress ); + + if (rcode) + { + p->lowspeed = false; + addrPool.FreeAddress(bAddress); + bAddress = 0; + USBTRACE2("setAddr:",rcode); + return rcode; + } + + USBTRACE2("\r\nAddr:", bAddress); + + p->lowspeed = false; + + //get pointer to assigned address record + p = addrPool.GetUsbDevicePtr(bAddress); + if (!p) { + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + } + + p->lowspeed = lowspeed; + + // Assign epInfo to epinfo pointer + rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); + + if (rcode) + goto FailSetDevTblEntry; + + /* debug code start */ num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; - USBTRACE2("\r\nNum.conf: ", num_of_conf ); - for (uint8_t i=0; i HexDump; - //USBTRACE("\r\nHexdumper2: "); - //ConfigDescParser<0, 0, 0, - // 0> confDescrParser(this); - - rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); - //rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); + + USBTRACE2("\r\nNC:",num_of_conf); + USBTRACE2("\r\nNP:",epInfo[0].bmNakPower); + + for (uint8_t i=0; i HexDump; + //ConfigDescParser<0, 0, 0, 0> confDescrParser(this); + + rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); + //rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); } // for (uint8_t i=0; iidProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID)){ USBTRACE("\r\nAcc.mode device detected"); + /* set endpoint info, config */ // Allocate new address //bAddress = addrPool.AllocAddress(parent, false, port); - if (!bAddress) { - return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; - } + //if (!bAddress) { + // return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; + //} // Extract Max Packet Size from the device descriptor - epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; - - // Assign new address to the device - rcode = pUsb->setAddr( 0, 0, bAddress ); - - if (rcode) { - p->lowspeed = false; - addrPool.FreeAddress(bAddress); - bAddress = 0; - USBTRACE2("setAddr:",rcode); - return rcode; - } - - USBTRACE2("\r\nAddr: ", bAddress); - - p->lowspeed = false; - - p = addrPool.GetUsbDevicePtr(bAddress); - - if (!p) { - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - } - - p->lowspeed = lowspeed; - - // Assign epInfo to epinfo pointer - // rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); -/* - if (rcode) { - goto FailSetDevTblEntry; - } - */ - /* initialize endpoint structures */ - - // Assign epInfo to epinfo pointer - //rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); - - USBTRACE2("Conf:", 1); - - // Set Configuration Value + //epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; + // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); - if (rcode) { - goto FailSetConf; - } - return 0; //successful configuration }//if( buf->idVendor == ADK_VID... @@ -190,7 +185,16 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) USBTRACE2("\r\nADK protocol rev. ", adkproto ); } - //load ID strings and switch to accessory mode + //sending ID strings + sendStr( ACCESSORY_STRING_MANUFACTURER, manufacturer); + sendStr( ACCESSORY_STRING_MODEL, model); + sendStr( ACCESSORY_STRING_DESCRIPTION, description); + sendStr( ACCESSORY_STRING_VERSION, version); + sendStr( ACCESSORY_STRING_URI, uri); + sendStr( ACCESSORY_STRING_SERIAL, serial); + + //switch to accessory mode + //the phone will reset rcode = switchAcc(); if( rcode ) { goto FailSwAcc; //init fails @@ -198,98 +202,15 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) rcode = -1; goto SwAttempt; //switch to accessory mode attempted -// -// // Allocate new address according to device class -// bAddress = addrPool.AllocAddress(parent, false, port); -// -// if (!bAddress) -// return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; -// -// // Extract Max Packet Size from the device descriptor -// epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; -// -// // Assign new address to the device -// rcode = pUsb->setAddr( 0, 0, bAddress ); -// -// if (rcode) -// { -// p->lowspeed = false; -// addrPool.FreeAddress(bAddress); -// bAddress = 0; -// USBTRACE2("setAddr:",rcode); -// return rcode; -// } -// -// USBTRACE2("Addr:", bAddress); -// -// p->lowspeed = false; -// -// p = addrPool.GetUsbDevicePtr(bAddress); -// -// if (!p) -// return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; -// -// p->lowspeed = lowspeed; -// -// num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; -// -// // Assign epInfo to epinfo pointer -// rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); -// -// if (rcode) -// goto FailSetDevTblEntry; -// -// USBTRACE2("NC:", num_of_conf); -// -// for (uint8_t i=0; i CdcControlParser(this); -// -// ConfigDescParser CdcDataParser(this); -// -// rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcControlParser); -// rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcDataParser); -// -// if (bNumEP > 1) -// break; -// } // for -// -// if (bNumEP < 4) -// return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; -// -// // Assign epInfo to epinfo pointer -// rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); -// -// USBTRACE2("Conf:", bConfNum); -// -// // Set Configuration Value -// rcode = pUsb->setConf(bAddress, 0, bConfNum); -// -// if (rcode) -// goto FailSetConf; -// -// rcode = pAsync->OnInit(this); -// -// if (rcode) -// goto FailOnInit; -// -// USBTRACE("ACM configured\r\n"); -// -// //bPollEnable = true; -// -// //USBTRACE("Poll enabled\r\n"); -// return 0; -// + FailGetDevDescr: USBTRACE("\r\ngetDevDescr:"); goto Fail; +FailSetDevTblEntry: + USBTRACE("\r\nsetDevTblEn:"); + goto Fail; + FailGetProto: USBTRACE("\r\ngetProto:"); goto Fail; @@ -310,9 +231,9 @@ SwAttempt: // USBTRACE("getConf:"); // goto Fail; // -FailSetConf: - USBTRACE("\r\nsetConf: "); - goto Fail; +//FailSetConf: +// USBTRACE("setConf:"); +// goto Fail; // //FailOnInit: // USBTRACE("OnInit:"); @@ -324,44 +245,44 @@ Fail: return rcode; } +/* Extracts bulk-IN and bulk-OUT endpoint information from config descriptor */ +void ADK::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) +{ + ErrorMessage(PSTR("Conf.Val"), conf); + ErrorMessage(PSTR("Iface Num"),iface); + ErrorMessage(PSTR("Alt.Set"), alt); -//void ACM::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) -//{ -// ErrorMessage(PSTR("Conf.Val"), conf); -// ErrorMessage(PSTR("Iface Num"),iface); -// ErrorMessage(PSTR("Alt.Set"), alt); -// -// bConfNum = conf; -// -// uint8_t index; -// -// if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) -// index = epInterruptInIndex; -// else -// if ((pep->bmAttributes & 0x02) == 2) -// index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; -// else -// return; -// -// // Fill in the endpoint info structure -// epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); -// epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; -// epInfo[index].epAttribs = 0; -// -// bNumEP ++; -// -// PrintEndpointDescriptor(pep); -//} + bConfNum = conf; + uint8_t index; + + + + if ((pep->bmAttributes & 0x02) == 2) { + index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; + } + + + // Fill in the endpoint info structure + epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); + epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; + epInfo[index].epAttribs = 0; + + bNumEP ++; + + PrintEndpointDescriptor(pep); +} + +/* Performs a cleanup after failed Init() attempt */ uint8_t ADK::Release() { -// pUsb->GetAddressPool().FreeAddress(bAddress); + pUsb->GetAddressPool().FreeAddress(bAddress); // // bControlIface = 0; // bDataIface = 0; -// bNumEP = 1; //must have to be reset to 1 + bNumEP = 1; //must have to be reset to 1 // -// bAddress = 0; + bAddress = 0; // qNextPollTime = 0; // bPollEnable = false; return 0; @@ -414,56 +335,20 @@ uint8_t ADK::SndData(uint16_t nbytes, uint8_t *dataptr) return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr); } -//uint8_t ACM::SetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr) -//{ -// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL )); -//} -// -//uint8_t ACM::GetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr) -//{ -// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCIN, CDC_GET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL )); -//} -// -//uint8_t ACM::ClearCommFeature(uint16_t fid) -//{ -// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_CLEAR_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, 0, 0, NULL, NULL )); -//} -// -//uint8_t ACM::SetLineCoding(const LINE_CODING *dataptr) -//{ -// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof(LINE_CODING), sizeof(LINE_CODING), (uint8_t*)dataptr, NULL )); -//} -// -//uint8_t ACM::GetLineCoding(LINE_CODING *dataptr) -//{ -// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCIN, CDC_GET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof(LINE_CODING), sizeof(LINE_CODING), (uint8_t*)dataptr, NULL )); -//} -// -//uint8_t ACM::SetControlLineState(uint8_t state) -//{ -// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_CONTROL_LINE_STATE, state, 0, bControlIface, 0, 0, NULL, NULL )); -//} -// -//uint8_t ACM::SendBreak(uint16_t duration) -//{ -// return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SEND_BREAK, (duration & 0xff), (duration >> 8), bControlIface, 0, 0, NULL, NULL )); -//} -// -// -//void ACM::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr ) -//{ -// Notify(PSTR("Endpoint descriptor:")); -// Notify(PSTR("\r\nLength:\t\t")); -// PrintHex(ep_ptr->bLength); -// Notify(PSTR("\r\nType:\t\t")); -// PrintHex(ep_ptr->bDescriptorType); -// Notify(PSTR("\r\nAddress:\t")); -// PrintHex(ep_ptr->bEndpointAddress); -// Notify(PSTR("\r\nAttributes:\t")); -// PrintHex(ep_ptr->bmAttributes); -// Notify(PSTR("\r\nMaxPktSize:\t")); -// PrintHex(ep_ptr->wMaxPacketSize); -// Notify(PSTR("\r\nPoll Intrv:\t")); -// PrintHex(ep_ptr->bInterval); -// Notify(PSTR("\r\n")); -//} +void ADK::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr ) +{ + Notify(PSTR("Endpoint descriptor:")); + Notify(PSTR("\r\nLength:\t\t")); + PrintHex(ep_ptr->bLength); + Notify(PSTR("\r\nType:\t\t")); + PrintHex(ep_ptr->bDescriptorType); + Notify(PSTR("\r\nAddress:\t")); + PrintHex(ep_ptr->bEndpointAddress); + Notify(PSTR("\r\nAttributes:\t")); + PrintHex(ep_ptr->bmAttributes); + Notify(PSTR("\r\nMaxPktSize:\t")); + PrintHex(ep_ptr->wMaxPacketSize); + Notify(PSTR("\r\nPoll Intrv:\t")); + PrintHex(ep_ptr->bInterval); + Notify(PSTR("\r\n")); +} diff --git a/adk.h b/adk.h index 14d961c9..135bb6db 100644 --- a/adk.h +++ b/adk.h @@ -76,7 +76,7 @@ protected: /* Endpoint data structure */ EpInfo epInfo[ADK_MAX_ENDPOINTS]; - // void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); + void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); public: ADK(USB *pUsb, const char* manufacturer, @@ -97,8 +97,8 @@ public: virtual uint8_t Poll(); virtual uint8_t GetAddress() { return bAddress; }; - // UsbConfigXtracter implementation - // virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); + //UsbConfigXtracter implementation + virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); }; //class ADK : public USBDeviceConfig ... /* get ADK protocol version */ /* returns 2 bytes in *adkproto */ diff --git a/hid.h b/hid.h index 9c3be7c5..7ca81b20 100644 --- a/hid.h +++ b/hid.h @@ -10,9 +10,9 @@ #include "Usb.h" #include -#include "..\DebugTools\printhex.h" -#include "..\DebugTools\hexdump.h" -#include "..\DebugTools\message.h" +#include "printhex.h" +#include "hexdump.h" +#include "message.h" #include "confdescparser.h" diff --git a/masstorage.h b/masstorage.h index 4126c9a8..ac92e737 100644 --- a/masstorage.h +++ b/masstorage.h @@ -10,9 +10,9 @@ #include "Usb.h" #include -#include "..\DebugTools\printhex.h" -#include "..\DebugTools\hexdump.h" -#include "..\DebugTools\message.h" +#include "printhex.h" +#include "hexdump.h" +#include "message.h" #include "confdescparser.h" From 7d177118e58a0ced5426399c7cab64e52c334c33 Mon Sep 17 00:00:00 2001 From: Oleg Mazurov Date: Sat, 2 Jul 2011 00:45:36 -0600 Subject: [PATCH 4/6] adk init works --- adk.cpp | 88 ++++++++++++++++++++++++++---------------------- adk.h | 2 +- confdescparser.h | 3 +- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/adk.cpp b/adk.cpp index 8b0d365b..8cc0cf32 100644 --- a/adk.cpp +++ b/adk.cpp @@ -40,7 +40,7 @@ ADK::ADK(USB *p, const char* manufacturer, } } -/* Connect/disconnect initialization of a phone */ +/* Connection initialization of an Android phone */ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) { const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR); @@ -133,45 +133,53 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) goto FailSetDevTblEntry; - /* debug code start */ - num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; - - USBTRACE2("\r\nNC:",num_of_conf); - USBTRACE2("\r\nNP:",epInfo[0].bmNakPower); - - for (uint8_t i=0; i HexDump; - //ConfigDescParser<0, 0, 0, 0> confDescrParser(this); - - rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); - //rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); - - } // for (uint8_t i=0; iidVendor == ADK_VID && - (((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID)){ + (((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID)) { USBTRACE("\r\nAcc.mode device detected"); - - /* set endpoint info, config */ - - // Allocate new address - //bAddress = addrPool.AllocAddress(parent, false, port); + /* debug code start */ + num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; + + USBTRACE2("\r\nNC:",num_of_conf); + USBTRACE2("\r\nNP:",epInfo[0].bmNakPower); - //if (!bAddress) { - // return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; - //} - - // Extract Max Packet Size from the device descriptor - //epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; + for (uint8_t i=0; i HexDump; + ConfigDescParser<0, 0, 0, 0> confDescrParser(this); + + //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); + //extracting endpoint information. See EndpointXtract() + rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); + + if( bNumEP > 2 ) { + break; + } + } // for (uint8_t i=0; isetConf(bAddress, 0, bConfNum); - + if( rcode ){ + goto FailSetConf; + } + /* print endpoint structure */ + USBTRACE("\r\nEndpoint Structure:"); + USBTRACE("\r\nEP0:"); + USBTRACE2("\r\nAddr: ", epInfo[0].epAddr ); + USBTRACE2("\r\nMax.pkt.size: ", epInfo[0].maxPktSize ); + USBTRACE2("\r\nAttr: ", epInfo[0].epAttribs ); + USBTRACE("\r\nEpout:"); + USBTRACE2("\r\nAddr: ", epInfo[epDataOutIndex].epAddr ); + USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataOutIndex].maxPktSize ); + USBTRACE2("\r\nAttr: ", epInfo[epDataOutIndex].epAttribs ); + USBTRACE("\r\nEpin:"); + USBTRACE2("\r\nAddr: ", epInfo[epDataInIndex].epAddr ); + USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataInIndex].maxPktSize ); + USBTRACE2("\r\nAttr: ", epInfo[epDataInIndex].epAttribs ); + + USBTRACE("\r\nConfiguration successful"); return 0; //successful configuration }//if( buf->idVendor == ADK_VID... @@ -231,9 +239,9 @@ SwAttempt: // USBTRACE("getConf:"); // goto Fail; // -//FailSetConf: +FailSetConf: // USBTRACE("setConf:"); -// goto Fail; + goto Fail; // //FailOnInit: // USBTRACE("OnInit:"); @@ -255,18 +263,16 @@ void ADK::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto bConfNum = conf; uint8_t index; - - - + if ((pep->bmAttributes & 0x02) == 2) { index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; } - // Fill in the endpoint info structure epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; - epInfo[index].epAttribs = 0; + epInfo[index].epAttribs = ( 0x3f & USB_NAK_MAX_POWER ); + //epInfo[index].bmbmNakPower = USB_NAK_MAX_POWER; bNumEP ++; diff --git a/adk.h b/adk.h index 135bb6db..08a4e02c 100644 --- a/adk.h +++ b/adk.h @@ -42,7 +42,7 @@ class ADK; -class ADK : public USBDeviceConfig +class ADK : public USBDeviceConfig, public UsbConfigXtracter { private: /* ID strings */ diff --git a/confdescparser.h b/confdescparser.h index 27ea57e5..295a1203 100644 --- a/confdescparser.h +++ b/confdescparser.h @@ -92,7 +92,8 @@ void ConfigDescParser::Parse(const uin if (!ParseDescriptor(&p, &cntdn)) return; } - +/* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and + compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */ template bool ConfigDescParser::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) { From 55b60c59bc7455417e43de31f3cbe5a69db3bdd8 Mon Sep 17 00:00:00 2001 From: Oleg Mazurov Date: Sat, 2 Jul 2011 12:43:38 -0600 Subject: [PATCH 5/6] adk init() cleanup --- adk.cpp | 190 ++++++++++++++++++++++++++------------------------------ adk.h | 11 ++-- 2 files changed, 93 insertions(+), 108 deletions(-) diff --git a/adk.cpp b/adk.cpp index 8cc0cf32..9452d45f 100644 --- a/adk.cpp +++ b/adk.cpp @@ -12,29 +12,28 @@ ADK::ADK(USB *p, const char* manufacturer, const char* uri, const char* serial) : - pUsb(p), //pointer to USB class instance - mandatory + pUsb(p), //pointer to USB class instance - mandatory + bAddress(0), //device address - mandatory + bNumEP(1), //if config descriptor needs to be parsed + /* ADK ID Strings */ + manufacturer(manufacturer), model(model), description(description), version(version), uri(uri), - serial(serial), + serial(serial) - bAddress(0), //device address - mandatory - bNumEP(1) //if config descriptor needs to be parsed { - /* initialize endpoint data structures */ - for(uint8_t i=0; iRegisterDeviceClass(this); //set devConfig[] entry } @@ -43,9 +42,8 @@ ADK::ADK(USB *p, const char* manufacturer, /* Connection initialization of an Android phone */ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) { - const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR); - - uint8_t buf[constBufSize]; + + uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)]; uint8_t rcode; UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; @@ -62,9 +60,6 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; } - //USBTRACE("\r\nHere"); - - // Get pointer to pseudo device with address 0 assigned p = addrPool.GetUsbDevicePtr(0); @@ -87,7 +82,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) p->lowspeed = lowspeed; // Get device descriptor - rcode = pUsb->getDevDescr( 0, 0, constBufSize, (uint8_t*)buf ); + rcode = pUsb->getDevDescr( 0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf ); // Restore p->epinfo p->epinfo = oldep_ptr; @@ -96,69 +91,60 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) goto FailGetDevDescr; } - // Allocate new address according to device class - bAddress = addrPool.AllocAddress(parent, false, port); + // Allocate new address according to device class + bAddress = addrPool.AllocAddress(parent, false, port); - // Extract Max Packet Size from device descriptor - epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; + // Extract Max Packet Size from device descriptor + epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; - // Assign new address to the device - rcode = pUsb->setAddr( 0, 0, bAddress ); + // Assign new address to the device + rcode = pUsb->setAddr( 0, 0, bAddress ); + if (rcode) { + p->lowspeed = false; + addrPool.FreeAddress(bAddress); + bAddress = 0; + USBTRACE2("setAddr:",rcode); + return rcode; + }//if (rcode... - if (rcode) - { - p->lowspeed = false; - addrPool.FreeAddress(bAddress); - bAddress = 0; - USBTRACE2("setAddr:",rcode); - return rcode; - } + USBTRACE2("\r\nAddr:", bAddress); - USBTRACE2("\r\nAddr:", bAddress); - - p->lowspeed = false; + p->lowspeed = false; - //get pointer to assigned address record - p = addrPool.GetUsbDevicePtr(bAddress); - if (!p) { - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - } + //get pointer to assigned address record + p = addrPool.GetUsbDevicePtr(bAddress); + if (!p) { + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + } - p->lowspeed = lowspeed; + p->lowspeed = lowspeed; - // Assign epInfo to epinfo pointer - rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); + // Assign epInfo to epinfo pointer + rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); + if (rcode) { + goto FailSetDevTblEntry; + } - if (rcode) - goto FailSetDevTblEntry; - - - //check if ADK device is already in accessory mode + //check if ADK device is already in accessory mode; if yes, configure and exit if(((USB_DEVICE_DESCRIPTOR*)buf)->idVendor == ADK_VID && (((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID)) { USBTRACE("\r\nAcc.mode device detected"); - /* debug code start */ + /* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */ num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; USBTRACE2("\r\nNC:",num_of_conf); - USBTRACE2("\r\nNP:",epInfo[0].bmNakPower); for (uint8_t i=0; i HexDump; ConfigDescParser<0, 0, 0, 0> confDescrParser(this); - - //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); - //extracting endpoint information. See EndpointXtract() - rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); - + rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); + if( rcode ) { + goto FailGetConfDescr; + } if( bNumEP > 2 ) { break; } } // for (uint8_t i=0; isetConf(bAddress, 0, bConfNum); if( rcode ){ @@ -202,7 +188,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) sendStr( ACCESSORY_STRING_SERIAL, serial); //switch to accessory mode - //the phone will reset + //the Android phone will reset rcode = switchAcc(); if( rcode ) { goto FailSwAcc; //init fails @@ -210,7 +196,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) rcode = -1; goto SwAttempt; //switch to accessory mode attempted - + /* diagnostic messages */ FailGetDevDescr: USBTRACE("\r\ngetDevDescr:"); goto Fail; @@ -235,9 +221,9 @@ SwAttempt: // USBTRACE("setDevTblEn:"); // goto Fail; // -//FailGetConfDescr: +FailGetConfDescr: // USBTRACE("getConf:"); -// goto Fail; + goto Fail; // FailSetConf: // USBTRACE("setConf:"); @@ -271,8 +257,6 @@ void ADK::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto // Fill in the endpoint info structure epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; - epInfo[index].epAttribs = ( 0x3f & USB_NAK_MAX_POWER ); - //epInfo[index].bmbmNakPower = USB_NAK_MAX_POWER; bNumEP ++; @@ -294,42 +278,42 @@ uint8_t ADK::Release() return 0; } -uint8_t ADK::Poll() -{ - uint8_t rcode = 0; - - if (!bPollEnable) - return 0; - - uint32_t time_now = millis(); - - if (qNextPollTime <= time_now) - { - qNextPollTime = time_now + 100; - - uint8_t rcode; - const uint8_t constBufSize = 16; - uint8_t buf[constBufSize]; - - for (uint8_t i=0; i epInfo[epInterruptInIndex].maxPktSize) -// ? epInfo[epInterruptInIndex].maxPktSize : constBufSize; -// rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf); - - if (rcode) - return rcode; - -// for (uint8_t i=0; i(buf[i]); -// Serial.print(" "); -// } -// USBTRACE("\r\n"); - } - return rcode; -} +//uint8_t ADK::Poll() +//{ +// uint8_t rcode = 0; +// +// if (!bPollEnable) +// return 0; +// +// uint32_t time_now = millis(); +// +// if (qNextPollTime <= time_now) +// { +// qNextPollTime = time_now + 100; +// +// uint8_t rcode; +// const uint8_t constBufSize = 16; +// uint8_t buf[constBufSize]; +// +// for (uint8_t i=0; i epInfo[epInterruptInIndex].maxPktSize) +//// ? epInfo[epInterruptInIndex].maxPktSize : constBufSize; +//// rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf); +// +// if (rcode) +// return rcode; +// +//// for (uint8_t i=0; i(buf[i]); +//// Serial.print(" "); +//// } +//// USBTRACE("\r\n"); +// } +// return rcode; +//} uint8_t ADK::RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) { diff --git a/adk.h b/adk.h index 08a4e02c..210c3d05 100644 --- a/adk.h +++ b/adk.h @@ -66,11 +66,11 @@ protected: USB *pUsb; uint8_t bAddress; uint8_t bConfNum; // configuration number - uint8_t bControlIface; // Control interface value - uint8_t bDataIface; // Data interface value +// uint8_t bControlIface; // Control interface value +// uint8_t bDataIface; // Data interface value uint8_t bNumEP; // total number of EP in the configuration - uint32_t qNextPollTime; // next poll time - bool bPollEnable; // poll enable flag +// uint32_t qNextPollTime; // next poll time +// bool bPollEnable; // poll enable flag //uint8_t bInitState; //initialization state machine state /* Endpoint data structure */ @@ -94,12 +94,13 @@ public: // USBDeviceConfig implementation virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed); virtual uint8_t Release(); - virtual uint8_t Poll(); + virtual uint8_t Poll(){}; //not implemented virtual uint8_t GetAddress() { return bAddress; }; //UsbConfigXtracter implementation virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); }; //class ADK : public USBDeviceConfig ... + /* get ADK protocol version */ /* returns 2 bytes in *adkproto */ inline uint8_t ADK::getProto( uint8_t* adkproto ) From 0244032d0d547c81ed81c09328e58cda54bb9769 Mon Sep 17 00:00:00 2001 From: Oleg Mazurov Date: Wed, 6 Jul 2011 19:48:43 -0600 Subject: [PATCH 6/6] adk final --- Usb.cpp | 4 +- Usb.h | 2 +- adk.cpp | 109 ++++++++++-------------- adk.h | 8 +- examples/adk/demokit_20/demokit_20.pde | 110 +++++++++++++++++++++++++ usbhub.cpp | 8 +- 6 files changed, 165 insertions(+), 76 deletions(-) create mode 100644 examples/adk/demokit_20/demokit_20.pde diff --git a/Usb.cpp b/Usb.cpp index 8d51be40..7a5a6477 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -225,7 +225,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui while( 1 ) // use a 'return' to exit this loop { rcode = dispatchPkt( tokIN, pep->epAddr, nak_limit ); //IN packet to EP-'endpoint'. Function takes care of NAKS. - + if( rcode ) return( rcode ); //should be 0, indicating ACK. Else return error code. @@ -605,7 +605,7 @@ uint8_t USB::getConfDescr( uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser uint16_t total = ((USB_CONFIGURATION_DESCRIPTOR*)buf)->wTotalLength; - USBTRACE2("total:", total); + //USBTRACE2("\r\ntotal conf.size:", total); return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p )); } diff --git a/Usb.h b/Usb.h index 5a81e80c..8676589f 100644 --- a/Usb.h +++ b/Usb.h @@ -100,7 +100,7 @@ public: #define USB_NAK_LIMIT 32000 //NAK limit for a transfer. o meand NAKs are not counted #define USB_RETRY_LIMIT 3 //retry limit for a transfer #define USB_SETTLE_DELAY 200 //settle delay in milliseconds -#define USB_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code +#define USB_NAK_NOWAIT 1 //quit after receiving a single NAK #define USB_NUMDEVICES 16 //number of USB devices //#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller diff --git a/adk.cpp b/adk.cpp index 9452d45f..ce49e350 100644 --- a/adk.cpp +++ b/adk.cpp @@ -15,6 +15,7 @@ ADK::ADK(USB *p, const char* manufacturer, pUsb(p), //pointer to USB class instance - mandatory bAddress(0), //device address - mandatory bNumEP(1), //if config descriptor needs to be parsed + ready(false), /* ADK ID Strings */ @@ -33,6 +34,9 @@ ADK::ADK(USB *p, const char* manufacturer, epInfo[i].epAttribs = ( 0xfc & ( USB_NAK_MAX_POWER<<2 )); }//for(uint8_t i=0; iRegisterDeviceClass(this); //set devConfig[] entry @@ -103,11 +107,11 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) p->lowspeed = false; addrPool.FreeAddress(bAddress); bAddress = 0; - USBTRACE2("setAddr:",rcode); + //USBTRACE2("setAddr:",rcode); return rcode; }//if (rcode... - USBTRACE2("\r\nAddr:", bAddress); + //USBTRACE2("\r\nAddr:", bAddress); p->lowspeed = false; @@ -119,7 +123,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) p->lowspeed = lowspeed; - // Assign epInfo to epinfo pointer + // Assign epInfo to epinfo pointer - only EP0 is known rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); if (rcode) { goto FailSetDevTblEntry; @@ -132,7 +136,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) /* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */ num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; - USBTRACE2("\r\nNC:",num_of_conf); + //USBTRACE2("\r\nNC:",num_of_conf); for (uint8_t i=0; i confDescrParser(this); @@ -144,6 +148,16 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) break; } } // for (uint8_t i=0; isetEpInfoEntry(bAddress, 3, epInfo); + if (rcode) { + goto FailSetDevTblEntry; + } + } + + // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); @@ -151,21 +165,22 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) goto FailSetConf; } /* print endpoint structure */ - USBTRACE("\r\nEndpoint Structure:"); - USBTRACE("\r\nEP0:"); - USBTRACE2("\r\nAddr: ", epInfo[0].epAddr ); - USBTRACE2("\r\nMax.pkt.size: ", epInfo[0].maxPktSize ); - USBTRACE2("\r\nAttr: ", epInfo[0].epAttribs ); - USBTRACE("\r\nEpout:"); - USBTRACE2("\r\nAddr: ", epInfo[epDataOutIndex].epAddr ); - USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataOutIndex].maxPktSize ); - USBTRACE2("\r\nAttr: ", epInfo[epDataOutIndex].epAttribs ); - USBTRACE("\r\nEpin:"); - USBTRACE2("\r\nAddr: ", epInfo[epDataInIndex].epAddr ); - USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataInIndex].maxPktSize ); - USBTRACE2("\r\nAttr: ", epInfo[epDataInIndex].epAttribs ); +// USBTRACE("\r\nEndpoint Structure:"); +// USBTRACE("\r\nEP0:"); +// USBTRACE2("\r\nAddr: ", epInfo[0].epAddr ); +// USBTRACE2("\r\nMax.pkt.size: ", epInfo[0].maxPktSize ); +// USBTRACE2("\r\nAttr: ", epInfo[0].epAttribs ); +// USBTRACE("\r\nEpout:"); +// USBTRACE2("\r\nAddr: ", epInfo[epDataOutIndex].epAddr ); +// USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataOutIndex].maxPktSize ); +// USBTRACE2("\r\nAttr: ", epInfo[epDataOutIndex].epAttribs ); +// USBTRACE("\r\nEpin:"); +// USBTRACE2("\r\nAddr: ", epInfo[epDataInIndex].epAddr ); +// USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataInIndex].maxPktSize ); +// USBTRACE2("\r\nAttr: ", epInfo[epDataInIndex].epAttribs ); USBTRACE("\r\nConfiguration successful"); + ready = true; return 0; //successful configuration }//if( buf->idVendor == ADK_VID... @@ -234,17 +249,17 @@ FailSetConf: // goto Fail; // Fail: - USBTRACE2("\r\nADK Init Failed, error code: ", rcode); - //Release(); + //USBTRACE2("\r\nADK Init Failed, error code: ", rcode); + Release(); return rcode; } /* Extracts bulk-IN and bulk-OUT endpoint information from config descriptor */ void ADK::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) { - ErrorMessage(PSTR("Conf.Val"), conf); - ErrorMessage(PSTR("Iface Num"),iface); - ErrorMessage(PSTR("Alt.Set"), alt); + //ErrorMessage(PSTR("Conf.Val"), conf); + //ErrorMessage(PSTR("Iface Num"),iface); + //ErrorMessage(PSTR("Alt.Set"), alt); bConfNum = conf; @@ -260,63 +275,25 @@ void ADK::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto bNumEP ++; - PrintEndpointDescriptor(pep); + //PrintEndpointDescriptor(pep); } /* Performs a cleanup after failed Init() attempt */ uint8_t ADK::Release() { pUsb->GetAddressPool().FreeAddress(bAddress); -// -// bControlIface = 0; -// bDataIface = 0; + bNumEP = 1; //must have to be reset to 1 -// + bAddress = 0; -// qNextPollTime = 0; -// bPollEnable = false; + ready = false; return 0; } -//uint8_t ADK::Poll() -//{ -// uint8_t rcode = 0; -// -// if (!bPollEnable) -// return 0; -// -// uint32_t time_now = millis(); -// -// if (qNextPollTime <= time_now) -// { -// qNextPollTime = time_now + 100; -// -// uint8_t rcode; -// const uint8_t constBufSize = 16; -// uint8_t buf[constBufSize]; -// -// for (uint8_t i=0; i epInfo[epInterruptInIndex].maxPktSize) -//// ? epInfo[epInterruptInIndex].maxPktSize : constBufSize; -//// rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf); -// -// if (rcode) -// return rcode; -// -//// for (uint8_t i=0; i(buf[i]); -//// Serial.print(" "); -//// } -//// USBTRACE("\r\n"); -// } -// return rcode; -//} - uint8_t ADK::RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) { + //USBTRACE2("\r\nAddr: ", bAddress ); + //USBTRACE2("\r\nEP: ",epInfo[epDataInIndex].epAddr); return pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr); } diff --git a/adk.h b/adk.h index 210c3d05..2d41f9da 100644 --- a/adk.h +++ b/adk.h @@ -66,12 +66,9 @@ protected: USB *pUsb; uint8_t bAddress; uint8_t bConfNum; // configuration number -// uint8_t bControlIface; // Control interface value -// uint8_t bDataIface; // Data interface value + uint8_t bNumEP; // total number of EP in the configuration -// uint32_t qNextPollTime; // next poll time -// bool bPollEnable; // poll enable flag - //uint8_t bInitState; //initialization state machine state + bool ready; /* Endpoint data structure */ EpInfo epInfo[ADK_MAX_ENDPOINTS]; @@ -96,6 +93,7 @@ public: virtual uint8_t Release(); virtual uint8_t Poll(){}; //not implemented virtual uint8_t GetAddress() { return bAddress; }; + virtual bool isReady() { return ready; }; //UsbConfigXtracter implementation virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); diff --git a/examples/adk/demokit_20/demokit_20.pde b/examples/adk/demokit_20/demokit_20.pde new file mode 100644 index 00000000..b1f47294 --- /dev/null +++ b/examples/adk/demokit_20/demokit_20.pde @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +USB Usb; +USBHub hub0(&Usb); +USBHub hub1(&Usb); +ADK adk(&Usb,"Google, Inc.", + "DemoKit", + "DemoKit Arduino Board", + "1.0", + "http://www.android.com", + "0000000012345678"); +uint8_t b, b1; + + +#define LED1_RED 3 +#define BUTTON1 2 + +void setup(); +void loop(); + +void init_buttons() +{ + pinMode(BUTTON1, INPUT); + + // enable the internal pullups + digitalWrite(BUTTON1, HIGH); +} + +void init_leds() +{ + digitalWrite(LED1_RED, 0); + + pinMode(LED1_RED, OUTPUT); +} + +void setup() +{ + Serial.begin(115200); + Serial.println("\r\nADK demo start"); + + if (Usb.Init() == -1) { + Serial.println("OSCOKIRQ failed to assert"); + while(1); //halt + }//if (Usb.Init() == -1... + + + init_leds(); + init_buttons(); + b1 = digitalRead(BUTTON1); +} + +void loop() +{ + uint8_t rcode; + uint8_t msg[3] = { 0x00 }; + Usb.Task(); + + if( adk.isReady() == false ) { + analogWrite(LED1_RED, 255); + return; + } + uint16_t len = sizeof(msg); + + rcode = adk.RcvData(&len, msg); + if( rcode ) { + USBTRACE2("Data rcv. :", rcode ); + } + if(len > 0) { + USBTRACE("\r\nData Packet."); + // assumes only one command per packet + if (msg[0] == 0x2) { + switch( msg[1] ) { + case 0: + analogWrite(LED1_RED, 255 - msg[2]); + break; + }//switch( msg[1]... + }//if (msg[0] == 0x2... + }//if( len > 0... + + msg[0] = 0x1; + + b = digitalRead(BUTTON1); + if (b != b1) { + USBTRACE("\r\nButton state changed"); + msg[1] = 0; + msg[2] = b ? 0 : 1; + rcode = adk.SndData( 3, msg ); + if( rcode ) { + USBTRACE2("Button send: ", rcode ); + } + b1 = b; + }//if (b != b1... + + + delay( 10 ); +} diff --git a/usbhub.cpp b/usbhub.cpp index 2ec1f754..4fe427be 100644 --- a/usbhub.cpp +++ b/usbhub.cpp @@ -47,9 +47,11 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) EpInfo *oldep_ptr = NULL; uint8_t len = 0; uint16_t cd_len = 0; + + //USBTRACE("\r\nHub Init Start"); AddressPool &addrPool = pUsb->GetAddressPool(); - + switch (bInitState) { case 0: @@ -113,7 +115,9 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) bAddress = 0; return rcode; } - + + //USBTRACE2("\r\nHub address: ", bAddress ); + // Restore p->epinfo p->epinfo = oldep_ptr;