mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Merge branch 'xxxajk' into premerge
This commit is contained in:
commit
7d981b4361
22 changed files with 1059 additions and 454 deletions
27
BTD.cpp
27
BTD.cpp
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BTD.h"
|
#include "BTD.h"
|
||||||
#define DEBUG // Uncomment to print data for debugging
|
// #define DEBUG // Uncomment to print data for debugging -- NO! see message.h
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
|
|
||||||
const uint8_t BTD::BTD_CONTROL_PIPE = 0;
|
const uint8_t BTD::BTD_CONTROL_PIPE = 0;
|
||||||
|
@ -222,30 +222,40 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
/* diagnostic messages */
|
/* diagnostic messages */
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetConfDescr();
|
NotifyFailGetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
|
#endif
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailUnknownDevice:
|
FailUnknownDevice:
|
||||||
NotifyFailUnknownDevice(VID,PID);
|
#ifdef DEBUG
|
||||||
|
NotifyFailUnknownDevice(VID, PID);
|
||||||
|
#endif
|
||||||
pUsb->setAddr(bAddress, 0, 0); // Reset address
|
pUsb->setAddr(bAddress, 0, 0); // Reset address
|
||||||
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
Fail:
|
Fail:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Notify(PSTR("\r\nBTD Init Failed, error code: "), 0x80);
|
Notify(PSTR("\r\nBTD Init Failed, error code: "), 0x80);
|
||||||
#endif
|
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
@ -432,7 +442,7 @@ void BTD::HCI_event_task() {
|
||||||
|
|
||||||
case EV_REMOTE_NAME_COMPLETE:
|
case EV_REMOTE_NAME_COMPLETE:
|
||||||
if (!hcibuf[2]) { // check if reading is OK
|
if (!hcibuf[2]) { // check if reading is OK
|
||||||
for (uint8_t i = 0; i < min(sizeof(remote_name),sizeof(hcibuf)-9); i++)
|
for (uint8_t i = 0; i < min(sizeof (remote_name), sizeof (hcibuf) - 9); i++)
|
||||||
remote_name[i] = hcibuf[9 + i];
|
remote_name[i] = hcibuf[9 + i];
|
||||||
hci_event_flag |= HCI_FLAG_REMOTE_NAME_COMPLETE;
|
hci_event_flag |= HCI_FLAG_REMOTE_NAME_COMPLETE;
|
||||||
}
|
}
|
||||||
|
@ -946,15 +956,14 @@ void BTD::hci_pin_code_request_reply() {
|
||||||
hcibuf[8] = disc_bdaddr[5];
|
hcibuf[8] = disc_bdaddr[5];
|
||||||
if (pairWithWii) {
|
if (pairWithWii) {
|
||||||
hcibuf[9] = 6; // Pin length is the length of the Bluetooth address
|
hcibuf[9] = 6; // Pin length is the length of the Bluetooth address
|
||||||
if(wiiUProController) {
|
if (wiiUProController) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Notify(PSTR("\r\nParing with Wii U Pro Controller"), 0x80);
|
Notify(PSTR("\r\nParing with Wii U Pro Controller"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
for(uint8_t i = 0; i < 6; i++)
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
hcibuf[10 + i] = my_bdaddr[i]; // The pin is the Bluetooth dongles Bluetooth address backwards
|
hcibuf[10 + i] = my_bdaddr[i]; // The pin is the Bluetooth dongles Bluetooth address backwards
|
||||||
}
|
} else {
|
||||||
else {
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
for(uint8_t i = 0; i < 6; i++)
|
|
||||||
hcibuf[10 + i] = disc_bdaddr[i]; // The pin is the Wiimote's Bluetooth address backwards
|
hcibuf[10 + i] = disc_bdaddr[i]; // The pin is the Wiimote's Bluetooth address backwards
|
||||||
}
|
}
|
||||||
for (uint8_t i = 16; i < 26; i++)
|
for (uint8_t i = 16; i < 26; i++)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PS3BT.h"
|
#include "PS3BT.h"
|
||||||
#define DEBUG // Uncomment to print data for debugging
|
//#define DEBUG // Uncomment to print data for debugging -- NO! see message.h
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
||||||
|
|
||||||
|
|
22
PS3USB.cpp
22
PS3USB.cpp
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PS3USB.h"
|
#include "PS3USB.h"
|
||||||
#define DEBUG // Uncomment to print data for debugging
|
//#define DEBUG // Uncomment to print data for debugging -- NO! see message.h
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
||||||
|
|
||||||
|
@ -221,25 +221,32 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
/* diagnostic messages */
|
/* diagnostic messages */
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
|
#endif
|
||||||
goto Fail;
|
goto Fail;
|
||||||
FailUnknownDevice:
|
FailUnknownDevice:
|
||||||
NotifyFailUnknownDevice(VID,PID);
|
#ifdef DEBUG
|
||||||
|
NotifyFailUnknownDevice(VID, PID);
|
||||||
|
#endif
|
||||||
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
Fail:
|
Fail:
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80);
|
Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80);
|
||||||
#endif
|
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
@ -427,7 +434,7 @@ void PS3USB::setRumbleOff() {
|
||||||
|
|
||||||
void PS3USB::setRumbleOn(Rumble mode) {
|
void PS3USB::setRumbleOn(Rumble mode) {
|
||||||
if ((mode & 0x30) > 0x00) {
|
if ((mode & 0x30) > 0x00) {
|
||||||
uint8_t power[2] = { 0xff, 0x00 }; // Defaults to RumbleLow
|
uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
|
||||||
if (mode == RumbleHigh) {
|
if (mode == RumbleHigh) {
|
||||||
power[0] = 0x00;
|
power[0] = 0x00;
|
||||||
power[1] = 0xff;
|
power[1] = 0xff;
|
||||||
|
@ -448,14 +455,17 @@ void PS3USB::setLedRaw(uint8_t value) {
|
||||||
writeBuf[9] = value << 1;
|
writeBuf[9] = value << 1;
|
||||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::setLedOff(LED a) {
|
void PS3USB::setLedOff(LED a) {
|
||||||
writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1));
|
writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1));
|
||||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::setLedOn(LED a) {
|
void PS3USB::setLedOn(LED a) {
|
||||||
writeBuf[9] |= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
|
writeBuf[9] |= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
|
||||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::setLedToggle(LED a) {
|
void PS3USB::setLedToggle(LED a) {
|
||||||
writeBuf[9] ^= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
|
writeBuf[9] ^= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
|
||||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||||
|
|
139
Usb.cpp
139
Usb.cpp
|
@ -132,7 +132,7 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
|
||||||
SETUP_PKT setup_pkt;
|
SETUP_PKT setup_pkt;
|
||||||
|
|
||||||
EpInfo *pep = NULL;
|
EpInfo *pep = NULL;
|
||||||
uint16_t nak_limit;
|
uint16_t nak_limit = 0;
|
||||||
|
|
||||||
rcode = SetAddress(addr, ep, &pep, nak_limit);
|
rcode = SetAddress(addr, ep, &pep, nak_limit);
|
||||||
|
|
||||||
|
@ -170,11 +170,16 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
|
||||||
//uint16_t read = (left<nbytes) ? left : nbytes;
|
//uint16_t read = (left<nbytes) ? left : nbytes;
|
||||||
|
|
||||||
rcode = InTransfer(pep, nak_limit, &read, dataptr);
|
rcode = InTransfer(pep, nak_limit, &read, dataptr);
|
||||||
|
if (rcode == hrTOGERR) {
|
||||||
|
// yes, we flip it wrong here so that next time it is actually correct!
|
||||||
|
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
||||||
// Invoke callback function if inTransfer completed successfuly and callback function pointer is specified
|
// Invoke callback function if inTransfer completed successfully and callback function pointer is specified
|
||||||
if (!rcode && p)
|
if (!rcode && p)
|
||||||
((USBReadParser*)p)->Parse(read, dataptr, total - left);
|
((USBReadParser*)p)->Parse(read, dataptr, total - left);
|
||||||
|
|
||||||
|
@ -227,21 +232,33 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
|
||||||
while (1) // use a 'return' to exit this loop
|
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.
|
rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS.
|
||||||
|
if (rcode == hrTOGERR) {
|
||||||
|
// yes, we flip it wrong here so that next time it is actually correct!
|
||||||
|
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
||||||
|
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (rcode) {
|
if (rcode) {
|
||||||
//printf("Problem! %i\r\n", rcode);
|
//printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
|
||||||
break; //should be 0, indicating ACK. Else return error code.
|
break; //should be 0, indicating ACK. Else return error code.
|
||||||
}
|
}
|
||||||
/* check for RCVDAVIRQ and generate error if not present */
|
/* 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 */
|
/* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */
|
||||||
if ((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
|
if ((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
|
||||||
//printf("Problem! NO RCVDAVIRQ!\r\n");
|
//printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
|
||||||
rcode = 0xf0; //receive error
|
rcode = 0xf0; //receive error
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pktsize = regRd(rRCVBC); //number of received bytes
|
pktsize = regRd(rRCVBC); //number of received bytes
|
||||||
//printf("Got %i bytes ", pktsize);
|
//printf("Got %i bytes \r\n", pktsize);
|
||||||
assert(pktsize <= nbytes);
|
// This would be OK, but...
|
||||||
|
//assert(pktsize <= nbytes);
|
||||||
|
if (pktsize > nbytes) {
|
||||||
|
// This can happen. Use of assert on Arduino locks up the Arduino.
|
||||||
|
// So I will trim the value, and hope for the best.
|
||||||
|
//printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize);
|
||||||
|
pktsize = nbytes;
|
||||||
|
}
|
||||||
|
|
||||||
int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
|
int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
|
||||||
|
|
||||||
|
@ -274,7 +291,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
|
||||||
/* rcode 0 if no errors. rcode 01-0f is relayed from HRSL */
|
/* rcode 0 if no errors. rcode 01-0f is relayed from HRSL */
|
||||||
uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data) {
|
uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data) {
|
||||||
EpInfo *pep = NULL;
|
EpInfo *pep = NULL;
|
||||||
uint16_t nak_limit;
|
uint16_t nak_limit = 0;
|
||||||
|
|
||||||
uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit);
|
uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit);
|
||||||
|
|
||||||
|
@ -315,15 +332,22 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
|
||||||
case hrNAK:
|
case hrNAK:
|
||||||
nak_count++;
|
nak_count++;
|
||||||
if (nak_limit && (nak_count == nak_limit))
|
if (nak_limit && (nak_count == nak_limit))
|
||||||
return ( rcode);
|
goto breakout;
|
||||||
|
//return ( rcode);
|
||||||
break;
|
break;
|
||||||
case hrTIMEOUT:
|
case hrTIMEOUT:
|
||||||
retry_count++;
|
retry_count++;
|
||||||
if (retry_count == USB_RETRY_LIMIT)
|
if (retry_count == USB_RETRY_LIMIT)
|
||||||
return ( rcode);
|
goto breakout;
|
||||||
|
//return ( rcode);
|
||||||
|
break;
|
||||||
|
case hrTOGERR:
|
||||||
|
// yes, we flip it wrong here so that next time it is actually correct!
|
||||||
|
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
||||||
|
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ( rcode);
|
goto breakout;
|
||||||
}//switch( rcode
|
}//switch( rcode
|
||||||
|
|
||||||
/* process NAK according to Host out NAK bug */
|
/* process NAK according to Host out NAK bug */
|
||||||
|
@ -338,10 +362,12 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
|
||||||
bytes_left -= bytes_tosend;
|
bytes_left -= bytes_tosend;
|
||||||
data_p += bytes_tosend;
|
data_p += bytes_tosend;
|
||||||
}//while( bytes_left...
|
}//while( bytes_left...
|
||||||
|
breakout:
|
||||||
|
|
||||||
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle
|
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle
|
||||||
return ( rcode); //should be 0 in all cases
|
return ( rcode); //should be 0 in all cases
|
||||||
}
|
}
|
||||||
/* dispatch usb packet. Assumes peripheral address is set and relevant buffer is loaded/empty */
|
/* dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty */
|
||||||
/* If NAK, tries to re-send up to nak_limit times */
|
/* If NAK, tries to re-send up to nak_limit times */
|
||||||
/* If nak_limit == 0, do not count NAKs, exit after timeout */
|
/* If nak_limit == 0, do not count NAKs, exit after timeout */
|
||||||
/* If bus timeout, re-sends up to USB_RETRY_LIMIT times */
|
/* If bus timeout, re-sends up to USB_RETRY_LIMIT times */
|
||||||
|
@ -358,7 +384,7 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
|
||||||
regWr(rHXFR, (token | ep)); //launch the transfer
|
regWr(rHXFR, (token | ep)); //launch the transfer
|
||||||
rcode = USB_ERROR_TRANSFER_TIMEOUT;
|
rcode = USB_ERROR_TRANSFER_TIMEOUT;
|
||||||
|
|
||||||
while (millis() < timeout) //wait for transfer completion
|
while (timeout > millis()) //wait for transfer completion
|
||||||
{
|
{
|
||||||
tmpdata = regRd(rHIRQ);
|
tmpdata = regRd(rHIRQ);
|
||||||
|
|
||||||
|
@ -370,8 +396,8 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
|
||||||
|
|
||||||
}//while ( millis() < timeout
|
}//while ( millis() < timeout
|
||||||
|
|
||||||
if (rcode != 0x00) //exit if timeout
|
//if (rcode != 0x00) //exit if timeout
|
||||||
return ( rcode);
|
// return ( rcode);
|
||||||
|
|
||||||
rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
|
rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
|
||||||
|
|
||||||
|
@ -379,15 +405,15 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
|
||||||
case hrNAK:
|
case hrNAK:
|
||||||
nak_count++;
|
nak_count++;
|
||||||
if (nak_limit && (nak_count == nak_limit))
|
if (nak_limit && (nak_count == nak_limit))
|
||||||
return ( rcode);
|
return (rcode);
|
||||||
break;
|
break;
|
||||||
case hrTIMEOUT:
|
case hrTIMEOUT:
|
||||||
retry_count++;
|
retry_count++;
|
||||||
if (retry_count == USB_RETRY_LIMIT)
|
if (retry_count == USB_RETRY_LIMIT)
|
||||||
return ( rcode);
|
return (rcode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ( rcode);
|
return (rcode);
|
||||||
}//switch( rcode
|
}//switch( rcode
|
||||||
|
|
||||||
}//while( timeout > millis()
|
}//while( timeout > millis()
|
||||||
|
@ -419,7 +445,9 @@ void USB::Task(void) //USB state machine
|
||||||
lowspeed = false;
|
lowspeed = false;
|
||||||
break;
|
break;
|
||||||
case LSHOST:
|
case LSHOST:
|
||||||
lowspeed = true;
|
if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
|
||||||
|
lowspeed = true;
|
||||||
|
}
|
||||||
case FSHOST: //attached
|
case FSHOST: //attached
|
||||||
if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
|
if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
|
||||||
delay = millis() + USB_SETTLE_DELAY;
|
delay = millis() + USB_SETTLE_DELAY;
|
||||||
|
@ -459,16 +487,23 @@ void USB::Task(void) //USB state machine
|
||||||
tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
|
tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
|
||||||
regWr(rMODE, tmpdata);
|
regWr(rMODE, tmpdata);
|
||||||
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
|
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
|
||||||
delay = millis() + 20; //20ms wait after reset per USB spec
|
//delay = millis() + 20; //20ms wait after reset per USB spec
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
|
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
|
||||||
if (regRd(rHIRQ) & bmFRAMEIRQ) //when first SOF received we can continue
|
if (regRd(rHIRQ) & bmFRAMEIRQ) {
|
||||||
{
|
//when first SOF received _and_ 20ms has passed we can continue
|
||||||
|
/*
|
||||||
if (delay < millis()) //20ms passed
|
if (delay < millis()) //20ms passed
|
||||||
usb_task_state = USB_STATE_CONFIGURING;
|
usb_task_state = USB_STATE_CONFIGURING;
|
||||||
|
*/
|
||||||
|
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET;
|
||||||
|
delay = millis() + 20;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case USB_ATTACHED_SUBSTATE_WAIT_RESET:
|
||||||
|
if (delay < millis()) usb_task_state = USB_STATE_CONFIGURING;
|
||||||
|
break;
|
||||||
case USB_STATE_CONFIGURING:
|
case USB_STATE_CONFIGURING:
|
||||||
rcode = Configuring(0, 0, lowspeed);
|
rcode = Configuring(0, 0, lowspeed);
|
||||||
|
|
||||||
|
@ -483,6 +518,7 @@ void USB::Task(void) //USB state machine
|
||||||
case USB_STATE_RUNNING:
|
case USB_STATE_RUNNING:
|
||||||
break;
|
break;
|
||||||
case USB_STATE_ERROR:
|
case USB_STATE_ERROR:
|
||||||
|
//MAX3421E::Init();
|
||||||
break;
|
break;
|
||||||
} // switch( usb_task_state )
|
} // switch( usb_task_state )
|
||||||
}
|
}
|
||||||
|
@ -527,27 +563,78 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is broken. We need to enumerate differently.
|
||||||
|
* It causes major problems with several devices if detected in an unexpected order.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Oleg - I wouldn't do anything before the newly connected device is considered sane.
|
||||||
|
* i.e.(delays are not indicated for brevity):
|
||||||
|
* 1. reset
|
||||||
|
* 2. GetDevDescr();
|
||||||
|
* 3a. If ACK, continue with allocating address, addressing, etc.
|
||||||
|
* 3b. Else reset again, count resets, stop at some number (5?).
|
||||||
|
* 4. When max.number of resets is reached, toggle power/fail
|
||||||
|
* If desired, this could be modified by performing two resets with GetDevDescr() in the middle - however, from my experience, if a device answers to GDD()
|
||||||
|
* it doesn't need to be reset again
|
||||||
|
* New steps proposal:
|
||||||
|
* 1: get address pool instance. exit on fail
|
||||||
|
* 2: pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf). exit on fail.
|
||||||
|
* 3: bus reset, 100ms delay
|
||||||
|
* 4: set address
|
||||||
|
* 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail
|
||||||
|
* 6: while (configurations) {
|
||||||
|
* for(each configuration) {
|
||||||
|
* for (each driver) {
|
||||||
|
* 6a: Ask device if it likes configuration. Returns 0 on OK.
|
||||||
|
* If successful, the driver configured device.
|
||||||
|
* The driver now owns the endpoints, and takes over managing them.
|
||||||
|
* The following will need codes:
|
||||||
|
* Everything went well, instance consumed, exit with success.
|
||||||
|
* Instance already in use, ignore it, try next driver.
|
||||||
|
* Not a supported device, ignore it, try next driver.
|
||||||
|
* Not a supported configuration for this device, ignore it, try next driver.
|
||||||
|
* Could not configure device, fatal, exit with fail.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* 7: for(each driver) {
|
||||||
|
* 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID
|
||||||
|
* 8: if we get here, no driver likes the device plugged in, so exit failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
//static uint8_t dev_index = 0;
|
|
||||||
uint8_t rcode = 0;
|
uint8_t rcode = 0;
|
||||||
|
|
||||||
for (; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
|
for (; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
|
||||||
if (!devConfig[devConfigIndex])
|
if (!devConfig[devConfigIndex])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
rcode = devConfig[devConfigIndex]->ConfigureDevice(parent, port, lowspeed);
|
||||||
|
if (rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
|
||||||
|
if (parent == 0) {
|
||||||
|
// Send a bus reset on the root interface.
|
||||||
|
regWr(rHCTL, bmBUSRST); //issue bus reset
|
||||||
|
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
||||||
|
} /* else {
|
||||||
|
* @Oleg
|
||||||
|
* TO-DO:
|
||||||
|
* How do we do an individual bus reset on a child interface?
|
||||||
|
* Is that even possible with the current code?
|
||||||
|
*/
|
||||||
|
}
|
||||||
rcode = devConfig[devConfigIndex]->Init(parent, port, lowspeed);
|
rcode = devConfig[devConfigIndex]->Init(parent, port, lowspeed);
|
||||||
|
|
||||||
if (!rcode) {
|
if (!rcode) {
|
||||||
devConfigIndex = 0;
|
devConfigIndex = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
//printf("ERROR ENUMERATING %2.2x\r\n", rcode);
|
||||||
if (!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) {
|
if (!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) {
|
||||||
// in case of an error dev_index should be reset to 0
|
// in case of an error dev_index should be reset to 0
|
||||||
// in order to start from the very beginning the
|
// in order to start from the very beginning the
|
||||||
// next time the program gets here
|
// next time the program gets here
|
||||||
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
|
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
|
||||||
devConfigIndex = 0;
|
devConfigIndex = 0;
|
||||||
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
31
Usb.h
31
Usb.h
|
@ -20,7 +20,8 @@ e-mail : support@circuitsathome.com
|
||||||
|
|
||||||
//#define BOARD_BLACK_WIDDOW
|
//#define BOARD_BLACK_WIDDOW
|
||||||
|
|
||||||
#define USB_METHODS_INLINE
|
// Not used anymore?
|
||||||
|
//#define USB_METHODS_INLINE
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
@ -105,19 +106,15 @@ typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega
|
||||||
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9
|
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9
|
||||||
#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA
|
#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA
|
||||||
#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB
|
#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB
|
||||||
|
#define USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET 0xE0
|
||||||
|
#define USB_ERROR_FailGetDevDescr 0xE1
|
||||||
|
#define USB_ERROR_FailSetDevTblEntry 0xE2
|
||||||
|
#define USB_ERROR_FailGetConfDescr 0xE3
|
||||||
#define USB_ERROR_TRANSFER_TIMEOUT 0xFF
|
#define USB_ERROR_TRANSFER_TIMEOUT 0xFF
|
||||||
|
|
||||||
class USBDeviceConfig {
|
#define USB_XFER_TIMEOUT 10000 //30000 // (5000) USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
|
||||||
public:
|
|
||||||
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed) = 0;
|
|
||||||
virtual uint8_t Release() = 0;
|
|
||||||
virtual uint8_t Poll() = 0;
|
|
||||||
virtual uint8_t GetAddress() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define USB_XFER_TIMEOUT 5000 //USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
|
|
||||||
//#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. 0 means NAKs are not counted
|
//#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. 0 means NAKs are not counted
|
||||||
#define USB_RETRY_LIMIT 3 //retry limit for a transfer
|
#define USB_RETRY_LIMIT 3 // 3 retry limit for a transfer
|
||||||
#define USB_SETTLE_DELAY 200 //settle delay in milliseconds
|
#define USB_SETTLE_DELAY 200 //settle delay in milliseconds
|
||||||
|
|
||||||
#define USB_NUMDEVICES 16 //number of USB devices
|
#define USB_NUMDEVICES 16 //number of USB devices
|
||||||
|
@ -135,12 +132,22 @@ public:
|
||||||
#define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30
|
#define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30
|
||||||
#define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40
|
#define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40
|
||||||
#define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50
|
#define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50
|
||||||
|
#define USB_ATTACHED_SUBSTATE_WAIT_RESET 0x51
|
||||||
#define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60
|
#define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60
|
||||||
#define USB_STATE_ADDRESSING 0x70
|
#define USB_STATE_ADDRESSING 0x70
|
||||||
#define USB_STATE_CONFIGURING 0x80
|
#define USB_STATE_CONFIGURING 0x80
|
||||||
#define USB_STATE_RUNNING 0x90
|
#define USB_STATE_RUNNING 0x90
|
||||||
#define USB_STATE_ERROR 0xa0
|
#define USB_STATE_ERROR 0xa0
|
||||||
|
|
||||||
|
class USBDeviceConfig {
|
||||||
|
public:
|
||||||
|
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed) = 0;
|
||||||
|
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {return 0; }
|
||||||
|
virtual uint8_t Release() = 0;
|
||||||
|
virtual uint8_t Poll() = 0;
|
||||||
|
virtual uint8_t GetAddress() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/* USB Setup Packet Structure */
|
/* USB Setup Packet Structure */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
|
@ -169,7 +176,7 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Base class for incomming data parser
|
// Base class for incoming data parser
|
||||||
|
|
||||||
class USBReadParser {
|
class USBReadParser {
|
||||||
public:
|
public:
|
||||||
|
|
14
XBOXRECV.cpp
14
XBOXRECV.cpp
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "XBOXRECV.h"
|
#include "XBOXRECV.h"
|
||||||
#define DEBUG // Uncomment to print data for debugging
|
//#define DEBUG // Uncomment to print data for debugging -- NO! see message.h
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
||||||
|
|
||||||
|
@ -120,8 +120,8 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Notify(PSTR("\r\nsetAddr: "), 0x80);
|
Notify(PSTR("\r\nsetAddr: "), 0x80);
|
||||||
#endif
|
|
||||||
PrintHex<uint8_t > (rcode, 0x80);
|
PrintHex<uint8_t > (rcode, 0x80);
|
||||||
|
#endif
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
|
@ -218,26 +218,34 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
/* diagnostic messages */
|
/* diagnostic messages */
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
|
#endif
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailUnknownDevice:
|
FailUnknownDevice:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailUnknownDevice(VID,PID);
|
NotifyFailUnknownDevice(VID,PID);
|
||||||
|
#endif
|
||||||
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
|
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
|
||||||
#endif
|
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
14
XBOXUSB.cpp
14
XBOXUSB.cpp
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "XBOXUSB.h"
|
#include "XBOXUSB.h"
|
||||||
#define DEBUG // Uncomment to print data for debugging
|
//#define DEBUG // Uncomment to print data for debugging -- NO! see message.h
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
||||||
|
|
||||||
|
@ -183,25 +183,33 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
/* diagnostic messages */
|
/* diagnostic messages */
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
FailUnknownDevice:
|
FailUnknownDevice:
|
||||||
NotifyFailUnknownDevice(VID,PID);
|
#ifdef DEBUG
|
||||||
|
NotifyFailUnknownDevice(VID, PID);
|
||||||
|
#endif
|
||||||
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
|
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
|
||||||
#endif
|
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ struct UsbDeviceAddress {
|
||||||
|
|
||||||
#define bmUSB_DEV_ADDR_ADDRESS 0x07
|
#define bmUSB_DEV_ADDR_ADDRESS 0x07
|
||||||
#define bmUSB_DEV_ADDR_PARENT 0x38
|
#define bmUSB_DEV_ADDR_PARENT 0x38
|
||||||
#define bmUSB_DEV_ADDR_HUB 0x40
|
#define bmUSB_DEV_ADDR_HUB 0x40
|
||||||
|
|
||||||
struct UsbDevice {
|
struct UsbDevice {
|
||||||
EpInfo *epinfo; // endpoint info pointer
|
EpInfo *epinfo; // endpoint info pointer
|
||||||
|
|
16
adk.cpp
16
adk.cpp
|
@ -227,33 +227,45 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
/* diagnostic messages */
|
/* diagnostic messages */
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetConfDescr();
|
NotifyFailGetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailGetProto:
|
FailGetProto:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("\r\ngetProto:");
|
USBTRACE("\r\ngetProto:");
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSwAcc:
|
FailSwAcc:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("\r\nswAcc:");
|
USBTRACE("\r\nswAcc:");
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
SwAttempt:
|
SwAttempt:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("\r\nAccessory mode switch attempt");
|
USBTRACE("\r\nAccessory mode switch attempt");
|
||||||
// goto Fail;
|
#endif
|
||||||
|
|
||||||
//FailOnInit:
|
//FailOnInit:
|
||||||
// USBTRACE("OnInit:");
|
// USBTRACE("OnInit:");
|
||||||
// goto Fail;
|
// goto Fail;
|
||||||
|
|
12
cdcacm.cpp
12
cdcacm.cpp
|
@ -183,26 +183,38 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetConfDescr();
|
NotifyFailGetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailOnInit:
|
FailOnInit:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("OnInit:");
|
USBTRACE("OnInit:");
|
||||||
|
#endif
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
12
cdcftdi.cpp
12
cdcftdi.cpp
|
@ -178,26 +178,38 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetConfDescr();
|
NotifyFailGetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailOnInit:
|
FailOnInit:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("OnInit:");
|
USBTRACE("OnInit:");
|
||||||
|
#endif
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,26 +155,38 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetConfDescr();
|
NotifyFailGetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailOnInit:
|
FailOnInit:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("OnInit:");
|
USBTRACE("OnInit:");
|
||||||
|
#endif
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@ e-mail : support@circuitsathome.com
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
#include "printhex.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
extern int UsbDEBUGlvl;
|
||||||
|
|
||||||
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
||||||
class HexDumper : public BASE_CLASS {
|
class HexDumper : public BASE_CLASS {
|
||||||
|
@ -40,7 +44,6 @@ public:
|
||||||
|
|
||||||
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
||||||
void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {
|
void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {
|
||||||
#ifdef DEBUG
|
|
||||||
if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug.
|
if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug.
|
||||||
for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
|
for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
|
||||||
if(!byteCount) {
|
if(!byteCount) {
|
||||||
|
@ -56,7 +59,6 @@ void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __HEXDUMP_H__
|
#endif // __HEXDUMP_H__
|
||||||
|
|
16
hidboot.h
16
hidboot.h
|
@ -393,32 +393,44 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetConfDescr();
|
NotifyFailGetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetProtocol:
|
FailSetProtocol:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("SetProto:");
|
USBTRACE("SetProto:");
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetIdle:
|
FailSetIdle:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("SetIdle:");
|
USBTRACE("SetIdle:");
|
||||||
goto Fail;
|
#endif
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,27 +221,39 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetDevTblEntry();
|
NotifyFailSetDevTblEntry();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailGetConfDescr();
|
NotifyFailGetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
FailSetIdle:
|
FailSetIdle:
|
||||||
|
#ifdef DEBUG
|
||||||
USBTRACE("SetIdle:");
|
USBTRACE("SetIdle:");
|
||||||
|
#endif
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
|
#ifdef DEBUG
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
957
masstorage.cpp
957
masstorage.cpp
File diff suppressed because it is too large
Load diff
91
masstorage.h
91
masstorage.h
|
@ -1,7 +1,15 @@
|
||||||
#if !defined(__MASSTORAGE_H__)
|
#if !defined(__MASSTORAGE_H__)
|
||||||
#define __MASSTORAGE_H__
|
#define __MASSTORAGE_H__
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
|
//<RANT>
|
||||||
|
// @Oleg -- Perhaps we need a central 'config.h', many of these includes and
|
||||||
|
// defines could be handled there, allowing for easier config.
|
||||||
|
|
||||||
|
// <<<<<<<<<<<<<<<< IMPORTANT >>>>>>>>>>>>>>>
|
||||||
|
// Set this to 1 to support single LUN devices, and save RAM. -- I.E. thumb drives.
|
||||||
|
// Each LUN needs ~13 bytes to be able to track the state of each unit.
|
||||||
|
#define MASS_MAX_SUPPORTED_LUN 8
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "avrpins.h"
|
#include "avrpins.h"
|
||||||
|
@ -10,6 +18,7 @@
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
#include <message.h>
|
||||||
|
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
@ -19,6 +28,9 @@
|
||||||
|
|
||||||
#include <confdescparser.h>
|
#include <confdescparser.h>
|
||||||
|
|
||||||
|
// </RANT>
|
||||||
|
|
||||||
|
|
||||||
#define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
|
#define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
|
||||||
|
|
||||||
#define bmREQ_MASSOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
#define bmREQ_MASSOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||||
|
@ -68,7 +80,7 @@
|
||||||
#define SCSI_CMD_MODE_SENSE_6 0x1A
|
#define SCSI_CMD_MODE_SENSE_6 0x1A
|
||||||
#define SCSI_CMD_MODE_SENSE_10 0x5A
|
#define SCSI_CMD_MODE_SENSE_10 0x5A
|
||||||
#define SCSI_CMD_START_STOP_UNIT 0x1B
|
#define SCSI_CMD_START_STOP_UNIT 0x1B
|
||||||
|
#define SCSI_CMD_PREVENT_REMOVAL 0x1E
|
||||||
#define SCSI_S_NOT_READY 0x02
|
#define SCSI_S_NOT_READY 0x02
|
||||||
#define SCSI_S_MEDIUM_ERROR 0x03
|
#define SCSI_S_MEDIUM_ERROR 0x03
|
||||||
#define SCSI_S_ILLEGAL_REQUEST 0x05
|
#define SCSI_S_ILLEGAL_REQUEST 0x05
|
||||||
|
@ -76,7 +88,7 @@
|
||||||
|
|
||||||
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
|
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
|
||||||
#define SCSI_ASC_LBA_OUT_OF_RANGE 0x21
|
#define SCSI_ASC_LBA_OUT_OF_RANGE 0x21
|
||||||
|
#define SCSI_ASC_MEDIA_CHANGED 0x28
|
||||||
|
|
||||||
#define MASS_ERR_SUCCESS 0x00
|
#define MASS_ERR_SUCCESS 0x00
|
||||||
#define MASS_ERR_PHASE_ERROR 0x02
|
#define MASS_ERR_PHASE_ERROR 0x02
|
||||||
|
@ -87,9 +99,14 @@
|
||||||
#define MASS_ERR_INVALID_CSW 0x07
|
#define MASS_ERR_INVALID_CSW 0x07
|
||||||
#define MASS_ERR_NO_MEDIA 0x08
|
#define MASS_ERR_NO_MEDIA 0x08
|
||||||
#define MASS_ERR_BAD_LBA 0x09
|
#define MASS_ERR_BAD_LBA 0x09
|
||||||
|
#define MASS_ERR_MEDIA_CHANGED 0x0A
|
||||||
#define MASS_ERR_DEVICE_DISCONNECTED 0x11
|
#define MASS_ERR_DEVICE_DISCONNECTED 0x11
|
||||||
#define MASS_ERR_UNABLE_TO_RECOVER 0x12 // Reset recovery error
|
#define MASS_ERR_UNABLE_TO_RECOVER 0x12 // Reset recovery error
|
||||||
#define MASS_ERR_INVALID_LUN 0x13
|
#define MASS_ERR_INVALID_LUN 0x13
|
||||||
|
#define MASS_ERR_WRITE_STALL 0x14
|
||||||
|
#define MASS_ERR_READ_NAKS 0x15
|
||||||
|
#define MASS_ERR_WRITE_NAKS 0x16
|
||||||
|
#define MASS_ERR_WRITE_PROTECTED 0x17
|
||||||
#define MASS_ERR_GENERAL_SCSI_ERROR 0xFE
|
#define MASS_ERR_GENERAL_SCSI_ERROR 0xFE
|
||||||
#define MASS_ERR_GENERAL_USB_ERROR 0xFF
|
#define MASS_ERR_GENERAL_USB_ERROR 0xFF
|
||||||
#define MASS_ERR_USER 0xA0 // For subclasses to define their own error codes
|
#define MASS_ERR_USER 0xA0 // For subclasses to define their own error codes
|
||||||
|
@ -98,6 +115,8 @@
|
||||||
#define MASS_TRANS_FLG_NO_STALL_CHECK 0x02 // STALL condition is not checked
|
#define MASS_TRANS_FLG_NO_STALL_CHECK 0x02 // STALL condition is not checked
|
||||||
#define MASS_TRANS_FLG_NO_PHASE_CHECK 0x04 // PHASE_ERROR is not checked
|
#define MASS_TRANS_FLG_NO_PHASE_CHECK 0x04 // PHASE_ERROR is not checked
|
||||||
|
|
||||||
|
#define MASS_MAX_ENDPOINTS 3
|
||||||
|
|
||||||
struct Capacity {
|
struct Capacity {
|
||||||
uint8_t data[8];
|
uint8_t data[8];
|
||||||
//uint32_t dwBlockAddress;
|
//uint32_t dwBlockAddress;
|
||||||
|
@ -184,8 +203,6 @@ struct RequestSenseResponce {
|
||||||
uint8_t SenseKeySpecific[3];
|
uint8_t SenseKeySpecific[3];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#define MASS_MAX_ENDPOINTS 3
|
|
||||||
|
|
||||||
class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter {
|
class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter {
|
||||||
protected:
|
protected:
|
||||||
static const uint8_t epDataInIndex; // DataIn endpoint index
|
static const uint8_t epDataInIndex; // DataIn endpoint index
|
||||||
|
@ -207,20 +224,18 @@ protected:
|
||||||
uint8_t bLastUsbError; // Last USB error
|
uint8_t bLastUsbError; // Last USB error
|
||||||
uint8_t bMaxLUN; // Max LUN
|
uint8_t bMaxLUN; // Max LUN
|
||||||
uint8_t bTheLUN; // Active LUN
|
uint8_t bTheLUN; // Active LUN
|
||||||
|
uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]; // Total sectors
|
||||||
protected:
|
uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
|
||||||
|
bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
|
||||||
|
bool WriteOk[MASS_MAX_SUPPORTED_LUN];
|
||||||
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||||
|
|
||||||
bool IsValidCBW(uint8_t size, uint8_t *pcbw);
|
|
||||||
bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
|
|
||||||
|
|
||||||
bool IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw);
|
// Additional Initialization Method for Subclasses
|
||||||
|
|
||||||
uint8_t ClearEpHalt(uint8_t index);
|
|
||||||
uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf, uint8_t flags);
|
|
||||||
uint8_t HandleUsbError(uint8_t error, uint8_t index);
|
|
||||||
uint8_t HandleSCSIError(uint8_t status);
|
|
||||||
|
|
||||||
|
virtual uint8_t OnInit() {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
BulkOnly(USB *p);
|
BulkOnly(USB *p);
|
||||||
|
|
||||||
|
@ -236,23 +251,21 @@ public:
|
||||||
return bTheLUN; // Active LUN
|
return bTheLUN; // Active LUN
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Reset();
|
boolean WriteProtected(uint8_t lun);
|
||||||
uint8_t GetMaxLUN(uint8_t *max_lun);
|
|
||||||
uint8_t SetCurLUN(uint8_t lun);
|
|
||||||
|
|
||||||
uint8_t ResetRecovery();
|
|
||||||
uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
|
|
||||||
uint8_t TestUnitReady(uint8_t lun);
|
|
||||||
uint8_t ReadCapacity(uint8_t lun, uint16_t size, uint8_t *buf);
|
|
||||||
uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
|
|
||||||
uint8_t ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
|
|
||||||
uint8_t MediaCTL(uint8_t lun, uint8_t ctl);
|
uint8_t MediaCTL(uint8_t lun, uint8_t ctl);
|
||||||
uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
|
uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
|
||||||
uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser *prs);
|
uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser *prs);
|
||||||
uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t *buf);
|
uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t *buf);
|
||||||
|
uint8_t LockMedia(uint8_t lun, uint8_t lock);
|
||||||
|
|
||||||
|
bool LUNIsGood(uint8_t lun);
|
||||||
|
uint32_t GetCapacity(uint8_t lun);
|
||||||
|
uint16_t GetSectorSize(uint8_t lun);
|
||||||
|
|
||||||
// USBDeviceConfig implementation
|
// USBDeviceConfig implementation
|
||||||
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
||||||
|
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
|
||||||
|
|
||||||
virtual uint8_t Release();
|
virtual uint8_t Release();
|
||||||
virtual uint8_t Poll();
|
virtual uint8_t Poll();
|
||||||
|
|
||||||
|
@ -263,12 +276,30 @@ public:
|
||||||
// UsbConfigXtracter implementation
|
// UsbConfigXtracter implementation
|
||||||
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
// Additional Initialization Method for Subclasses
|
uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
|
||||||
|
uint8_t TestUnitReady(uint8_t lun);
|
||||||
|
uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
|
||||||
|
uint8_t ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
|
||||||
|
uint8_t GetMaxLUN(uint8_t *max_lun);
|
||||||
|
uint8_t SetCurLUN(uint8_t lun);
|
||||||
|
uint8_t Reset();
|
||||||
|
uint8_t ResetRecovery();
|
||||||
|
uint8_t ReadCapacity(uint8_t lun, uint16_t size, uint8_t *buf);
|
||||||
|
void ClearAllEP();
|
||||||
|
void CheckMedia();
|
||||||
|
boolean CheckLUN(uint8_t lun);
|
||||||
|
uint8_t Page3F(uint8_t lun);
|
||||||
|
bool IsValidCBW(uint8_t size, uint8_t *pcbw);
|
||||||
|
bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
|
||||||
|
|
||||||
|
bool IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw);
|
||||||
|
|
||||||
|
uint8_t ClearEpHalt(uint8_t index);
|
||||||
|
uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf, uint8_t flags);
|
||||||
|
uint8_t HandleUsbError(uint8_t error, uint8_t index);
|
||||||
|
uint8_t HandleSCSIError(uint8_t status);
|
||||||
|
|
||||||
virtual uint8_t OnInit() {
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __MASSTORAGE_H__
|
#endif // __MASSTORAGE_H__
|
||||||
|
|
39
message.cpp
39
message.cpp
|
@ -15,14 +15,13 @@ Web : http://www.circuitsathome.com
|
||||||
e-mail : support@circuitsathome.com
|
e-mail : support@circuitsathome.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
// 0x80 is the default (i.e. trace) to turn off set this global to something lower.
|
// 0x80 is the default (i.e. trace) to turn off set this global to something lower.
|
||||||
// this allows for 126 other debugging levels.
|
// this allows for 126 other debugging levels.
|
||||||
// TO-DO: Allow assignment to a different serial port
|
// TO-DO: Allow assignment to a different serial port
|
||||||
int UsbDEBUGlvl = 0x80;
|
int UsbDEBUGlvl = 0x80;
|
||||||
|
|
||||||
void Notifyc(char c, int lvl) {
|
void E_Notifyc(char c, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if (UsbDEBUGlvl < lvl) return;
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
Serial.print(c);
|
Serial.print(c);
|
||||||
|
@ -32,23 +31,23 @@ void Notifyc(char c, int lvl) {
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notify(char const * msg, int lvl) {
|
void E_Notify(char const * msg, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if (UsbDEBUGlvl < lvl) return;
|
||||||
if (!msg) return;
|
if (!msg) return;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
while ((c = pgm_read_byte(msg++))) Notifyc(c, lvl);
|
while ((c = pgm_read_byte(msg++))) E_Notifyc(c, lvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyStr(char const * msg, int lvl) {
|
void E_NotifyStr(char const * msg, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if (UsbDEBUGlvl < lvl) return;
|
||||||
if (!msg) return;
|
if (!msg) return;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
while (c = *msg++) Notifyc(c, lvl);
|
while (c = *msg++) E_Notifyc(c, lvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notify(uint8_t b, int lvl) {
|
void E_Notify(uint8_t b, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if (UsbDEBUGlvl < lvl) return;
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
Serial.print(b);
|
Serial.print(b);
|
||||||
|
@ -58,12 +57,13 @@ void Notify(uint8_t b, int lvl) {
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notify(double d, int lvl) {
|
void E_Notify(double d, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if (UsbDEBUGlvl < lvl) return;
|
||||||
Serial.print(d);
|
Serial.print(d);
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
void NotifyFailGetDevDescr(void) {
|
void NotifyFailGetDevDescr(void) {
|
||||||
Notify(PSTR("\r\ngetDevDescr"), 0x80);
|
Notify(PSTR("\r\ngetDevDescr"), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,28 @@ void NotifyFailSetConfDescr(void) {
|
||||||
Notify(PSTR("\r\nsetConf"), 0x80);
|
Notify(PSTR("\r\nsetConf"), 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotifyFailGetDevDescr(uint8_t reason) {
|
||||||
|
NotifyFailGetDevDescr();
|
||||||
|
NotifyFail(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyFailSetDevTblEntry(uint8_t reason) {
|
||||||
|
NotifyFailSetDevTblEntry();
|
||||||
|
NotifyFail(reason);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyFailGetConfDescr(uint8_t reason) {
|
||||||
|
NotifyFailGetConfDescr();
|
||||||
|
NotifyFail(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Will we need this in the future?
|
||||||
|
void NotifyFailSetConfDescr(uint8_t reason) {
|
||||||
|
NotifyFailSetConfDescr();
|
||||||
|
NotifyFail(reason);
|
||||||
|
}
|
||||||
|
*/
|
||||||
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID) {
|
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID) {
|
||||||
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
|
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
|
||||||
PrintHex<uint16_t > (VID, 0x80);
|
PrintHex<uint16_t > (VID, 0x80);
|
||||||
|
@ -90,3 +112,4 @@ void NotifyFail(uint8_t rcode) {
|
||||||
PrintHex<uint8_t > (rcode, 0x80);
|
PrintHex<uint8_t > (rcode, 0x80);
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
Notify(PSTR("\r\n"), 0x80);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
47
message.h
47
message.h
|
@ -17,18 +17,27 @@ e-mail : support@circuitsathome.com
|
||||||
#if !defined(__MESSAGE_H__)
|
#if !defined(__MESSAGE_H__)
|
||||||
#define __MESSAGE_H__
|
#define __MESSAGE_H__
|
||||||
|
|
||||||
|
// uncomment to activate
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
extern int UsbDEBUGlvl;
|
extern int UsbDEBUGlvl;
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
|
void E_Notify(char const * msg, int lvl);
|
||||||
|
void E_Notify(uint8_t b, int lvl);
|
||||||
|
void E_NotifyStr(char const * msg, int lvl);
|
||||||
|
void E_Notifyc(char c, int lvl);
|
||||||
|
|
||||||
void Notify(uint8_t b, int lvl);
|
|
||||||
void Notify(double d, int lvl);
|
|
||||||
void Notify(char const * msg, int lvl);
|
|
||||||
void NotifyStr(char const * msg, int lvl);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
#define Notify E_Notify
|
||||||
|
#define NotifyStr E_NotifyStr
|
||||||
|
#define Notifyc E_Notifyc
|
||||||
|
void NotifyFailGetDevDescr(uint8_t reason);
|
||||||
|
void NotifyFailSetDevTblEntry(uint8_t reason);
|
||||||
|
void NotifyFailGetConfDescr(uint8_t reason);
|
||||||
void NotifyFailGetDevDescr(void);
|
void NotifyFailGetDevDescr(void);
|
||||||
void NotifyFailSetDevTblEntry(void);
|
void NotifyFailSetDevTblEntry(void);
|
||||||
void NotifyFailGetConfDescr(void);
|
void NotifyFailGetConfDescr(void);
|
||||||
|
@ -36,20 +45,38 @@ void NotifyFailSetConfDescr(void);
|
||||||
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID);
|
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID);
|
||||||
void NotifyFail(uint8_t rcode);
|
void NotifyFail(uint8_t rcode);
|
||||||
#else
|
#else
|
||||||
#define NotifyFailGetDevDescr()
|
#define Notify(...) ((void)0)
|
||||||
#define NotifyFailSetDevTblEntry()
|
#define NotifyStr(...) ((void)0)
|
||||||
#define NotifyFailGetConfDescr()
|
#define Notifyc(...) ((void)0)
|
||||||
#define NotifyFailSetConfDescr()
|
#define NotifyFailGetDevDescr(...) ((void)0)
|
||||||
#define NotifyFailUnknownDevice(VID, PID)
|
#define NotifyFailSetDevTblEntry(...) ((void)0)
|
||||||
#define NotifyFail(rcode)
|
#define NotifyFailGetConfDescr(...) ((void)0)
|
||||||
|
#define NotifyFailGetDevDescr(...) ((void)0)
|
||||||
|
#define NotifyFailSetDevTblEntry(...) ((void)0)
|
||||||
|
#define NotifyFailGetConfDescr(...) ((void)0)
|
||||||
|
#define NotifyFailSetConfDescr(...) ((void)0)
|
||||||
|
#define NotifyFailUnknownDevice(...) ((void)0)
|
||||||
|
#define NotifyFail(...) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <class ERROR_TYPE>
|
||||||
|
void ErrorMessage(uint8_t level, char const * msg, ERROR_TYPE rcode = 0) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
Notify(msg, level);
|
||||||
|
Notify(PSTR(": "), level);
|
||||||
|
PrintHex<ERROR_TYPE > (rcode, level);
|
||||||
|
Notify(PSTR("\r\n"), level);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <class ERROR_TYPE>
|
template <class ERROR_TYPE>
|
||||||
void ErrorMessage(char const * msg, ERROR_TYPE rcode = 0) {
|
void ErrorMessage(char const * msg, ERROR_TYPE rcode = 0) {
|
||||||
|
#ifdef DEBUG
|
||||||
Notify(msg, 0x80);
|
Notify(msg, 0x80);
|
||||||
Notify(PSTR(": "), 0x80);
|
Notify(PSTR(": "), 0x80);
|
||||||
PrintHex<ERROR_TYPE > (rcode, 0x80);
|
PrintHex<ERROR_TYPE > (rcode, 0x80);
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
Notify(PSTR("\r\n"), 0x80);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
|
|
@ -19,9 +19,9 @@ e-mail : support@circuitsathome.com
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "printhex.h"
|
|
||||||
#include "hexdump.h"
|
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
//#include "printhex.h"
|
||||||
|
//#include "hexdump.h"
|
||||||
|
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
17
printhex.h
17
printhex.h
|
@ -22,30 +22,36 @@ e-mail : support@circuitsathome.com
|
||||||
#else
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
#endif
|
#endif
|
||||||
void Notifyc(char c, int lvl);
|
|
||||||
|
void E_Notifyc(char c, int lvl);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PrintHex(T val, int lvl) {
|
void PrintHex(T val, int lvl) {
|
||||||
|
#ifdef DEBUG
|
||||||
int num_nibbles = sizeof(T) * 2;
|
int num_nibbles = sizeof(T) * 2;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||||
if(v > 57) v += 7;
|
if(v > 57) v += 7;
|
||||||
Notifyc(v, lvl);
|
E_Notifyc(v, lvl);
|
||||||
} while(--num_nibbles);
|
} while(--num_nibbles);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PrintBin(T val, int lvl) {
|
void PrintBin(T val, int lvl) {
|
||||||
|
#ifdef DEBUG
|
||||||
for(T mask = (((T) 1) << ((sizeof(T) << 3) - 1)); mask; mask >>= 1)
|
for(T mask = (((T) 1) << ((sizeof(T) << 3) - 1)); mask; mask >>= 1)
|
||||||
if(val & mask)
|
if(val & mask)
|
||||||
Notifyc('1', lvl);
|
E_Notifyc('1', lvl);
|
||||||
else
|
else
|
||||||
Notifyc('0', lvl);
|
E_Notifyc('0', lvl);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void SerialPrintHex(T val) {
|
void SerialPrintHex(T val) {
|
||||||
|
#ifdef DEBUG
|
||||||
int num_nibbles = sizeof(T) * 2;
|
int num_nibbles = sizeof(T) * 2;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -53,10 +59,12 @@ void SerialPrintHex(T val) {
|
||||||
if(v > 57) v += 7;
|
if(v > 57) v += 7;
|
||||||
Serial.print(v);
|
Serial.print(v);
|
||||||
} while(--num_nibbles);
|
} while(--num_nibbles);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PrintHex2(Print *prn, T val) {
|
void PrintHex2(Print *prn, T val) {
|
||||||
|
#ifdef DEBUG
|
||||||
T mask = (((T) 1) << (((sizeof(T) << 1) - 1) << 2));
|
T mask = (((T) 1) << (((sizeof(T) << 1) - 1) << 2));
|
||||||
|
|
||||||
while(mask > 1) {
|
while(mask > 1) {
|
||||||
|
@ -66,6 +74,7 @@ void PrintHex2(Print *prn, T val) {
|
||||||
mask >>= 4;
|
mask >>= 4;
|
||||||
}
|
}
|
||||||
prn->print((T) val, HEX);
|
prn->print((T) val, HEX);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __PRINTHEX_H__
|
#endif // __PRINTHEX_H__
|
||||||
|
|
15
usbhost.h
15
usbhost.h
|
@ -21,7 +21,7 @@ e-mail : support@circuitsathome.com
|
||||||
#include "avrpins.h"
|
#include "avrpins.h"
|
||||||
#include "max3421e.h"
|
#include "max3421e.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
|
#include <stdio.h>
|
||||||
/* SPI initialization */
|
/* SPI initialization */
|
||||||
template< typename CLK, typename MOSI, typename MISO, typename SPI_SS > class SPi {
|
template< typename CLK, typename MOSI, typename MISO, typename SPI_SS > class SPi {
|
||||||
public:
|
public:
|
||||||
|
@ -34,7 +34,7 @@ public:
|
||||||
SPI_SS::SetDirWrite();
|
SPI_SS::SetDirWrite();
|
||||||
/* mode 00 (CPOL=0, CPHA=0) master, fclk/2. Mode 11 (CPOL=11, CPHA=11) is also supported by MAX3421E */
|
/* mode 00 (CPOL=0, CPHA=0) master, fclk/2. Mode 11 (CPOL=11, CPHA=11) is also supported by MAX3421E */
|
||||||
SPCR = 0x50;
|
SPCR = 0x50;
|
||||||
SPSR = 0x01;
|
SPSR = 0x01; // 0x01
|
||||||
/**/
|
/**/
|
||||||
//tmp = SPSR;
|
//tmp = SPSR;
|
||||||
//tmp = SPDR;
|
//tmp = SPDR;
|
||||||
|
@ -159,9 +159,18 @@ uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* dat
|
||||||
SPDR = 0; //send empty byte
|
SPDR = 0; //send empty byte
|
||||||
nbytes--;
|
nbytes--;
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
*data_p = SPDR;
|
#if 0
|
||||||
|
{
|
||||||
|
*data_p = SPDR;
|
||||||
|
printf("%2.2x ", *data_p);
|
||||||
|
}
|
||||||
data_p++;
|
data_p++;
|
||||||
}
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
#else
|
||||||
|
*data_p++ = SPDR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
SS::Set();
|
SS::Set();
|
||||||
return( data_p);
|
return( data_p);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue