Update USB_FLASH_DRIVE_SUPPORT (#15021)

2.0.x
Marcio Teixeira 5 years ago committed by Scott Lahteine
parent 20fc66f875
commit da601d5114

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -22,12 +22,75 @@
#include "../../inc/MarlinConfigPre.h"
/**
* Adjust USB_DEBUG to select debugging verbosity.
* 0 - no debug messages
* 1 - basic insertion/removal messages
* 2 - show USB state transitions
* 3 - perform block range checking
* 4 - print each block access
*/
#define USB_DEBUG 1
#define USB_STARTUP_DELAY 0
// uncomment to get 'printf' console debugging. NOT FOR UNO!
//#define HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPAIR("UHS:",s);}
//#define BS_HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPAIR("UHS:",s);}
//#define MAX_HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPAIR("UHS:",s);}
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#include "../../Marlin.h"
#include "../../core/serial.h"
#include "../../module/temperature.h"
static_assert(USB_CS_PIN != -1, "USB_CS_PIN must be defined");
static_assert(USB_INTR_PIN != -1, "USB_INTR_PIN must be defined");
#if ENABLED(USE_UHS3_USB)
#define NO_AUTO_SPEED
#define UHS_MAX3421E_SPD 8000000 >> SPI_SPEED
#define UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE 1
#define UHS_HOST_MAX_INTERFACE_DRIVERS 2
#define MASS_MAX_SUPPORTED_LUN 1
#define USB_HOST_SERIAL MYSERIAL0
// Workaround for certain issues with UHS3
#define SKIP_PAGE3F // Required for IOGEAR media adapter
#define USB_NO_TEST_UNIT_READY // Required for removable media adapter
#define USB_HOST_MANUAL_POLL // Optimization to shut off IRQ automatically
// Workarounds for keeping Marlin's watchdog timer from barking...
void marlin_yield() {
thermalManager.manage_heater();
}
#define SYSTEM_OR_SPECIAL_YIELD(...) marlin_yield();
#define delay(x) safe_delay(x)
#include "lib/Usb.h"
#include "lib/masstorage.h"
#define LOAD_USB_HOST_SYSTEM
#define LOAD_USB_HOST_SHIELD
#define LOAD_UHS_BULK_STORAGE
#define MARLIN_UHS_WRITE_SS(v) WRITE(USB_CS_PIN, v)
#define MARLIN_UHS_READ_IRQ() READ(USB_INTR_PIN)
#include "lib-uhs3/UHS_host/UHS_host.h"
MAX3421E_HOST usb(USB_CS_PIN, USB_INTR_PIN);
UHS_Bulk_Storage bulk(&usb);
#define UHS_START (usb.Init() == 0)
#define UHS_STATE(state) UHS_USB_HOST_STATE_##state
#else
#include "lib-uhs2/Usb.h"
#include "lib-uhs2/masstorage.h"
USB usb;
BulkOnly bulk(&usb);
#define UHS_START usb.start()
#define UHS_STATE(state) USB_STATE_##state
#endif
#include "Sd2Card_FlashDrive.h"
@ -35,10 +98,41 @@
#include "../../lcd/ultralcd.h"
#endif
USB usb;
BulkOnly bulk(&usb);
static enum {
UNINITIALIZED,
DO_STARTUP,
WAIT_FOR_DEVICE,
WAIT_FOR_LUN,
MEDIA_READY,
MEDIA_ERROR
} state;
#if USB_DEBUG >= 3
uint32_t lun0_capacity;
#endif
bool Sd2Card::usbStartup() {
if (state <= DO_STARTUP) {
SERIAL_ECHOPGM("Starting USB host...");
if (!UHS_START) {
SERIAL_ECHOLNPGM(" failed.");
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
LCD_MESSAGEPGM("USB start failed");
#endif
return false;
}
Sd2Card::state_t Sd2Card::state;
// SPI quick test - check revision register
switch (usb.regRd(rREVISION)) {
case 0x01: SERIAL_ECHOLNPGM("rev.01 started"); break;
case 0x12: SERIAL_ECHOLNPGM("rev.02 started"); break;
case 0x13: SERIAL_ECHOLNPGM("rev.03 started"); break;
default: SERIAL_ECHOLNPGM("started. rev unknown."); break;
}
state = WAIT_FOR_DEVICE;
}
return true;
}
// The USB library needs to be called periodically to detect USB thumbdrive
// insertion and removals. Call this idle() function periodically to allow
@ -46,75 +140,145 @@ Sd2Card::state_t Sd2Card::state;
// of initializing the USB library for the first time.
void Sd2Card::idle() {
static uint32_t next_retry;
usb.Task();
switch (state) {
case USB_HOST_DELAY_INIT:
next_retry = millis() + 2000;
state = USB_HOST_WAITING;
const uint8_t task_state = usb.getUsbTaskState();
#if USB_DEBUG >= 2
if (state > DO_STARTUP) {
static uint8_t laststate = 232;
if (task_state != laststate) {
laststate = task_state;
#define UHS_USB_DEBUG(x) case UHS_STATE(x): SERIAL_ECHOLNPGM(#x); break
switch (task_state) {
UHS_USB_DEBUG(IDLE);
UHS_USB_DEBUG(RESET_DEVICE);
UHS_USB_DEBUG(RESET_NOT_COMPLETE);
UHS_USB_DEBUG(DEBOUNCE);
UHS_USB_DEBUG(DEBOUNCE_NOT_COMPLETE);
UHS_USB_DEBUG(WAIT_SOF);
UHS_USB_DEBUG(ERROR);
UHS_USB_DEBUG(CONFIGURING);
UHS_USB_DEBUG(CONFIGURING_DONE);
UHS_USB_DEBUG(RUNNING);
default:
SERIAL_ECHOLNPAIR("UHS_USB_HOST_STATE: ", task_state);
break;
case USB_HOST_WAITING:
if (ELAPSED(millis(), next_retry)) {
next_retry = millis() + 2000;
state = USB_HOST_UNINITIALIZED;
}
}
}
#endif
static millis_t next_state_ms = millis();
#define GOTO_STATE_AFTER_DELAY(STATE, DELAY) do{ state = STATE; next_state_ms = millis() + DELAY; }while(0)
if (ELAPSED(millis(), next_state_ms)) {
GOTO_STATE_AFTER_DELAY(state, 250); // Default delay
switch (state) {
case UNINITIALIZED:
#ifndef MANUAL_USB_STARTUP
GOTO_STATE_AFTER_DELAY( DO_STARTUP, USB_STARTUP_DELAY );
#endif
break;
case USB_HOST_UNINITIALIZED:
SERIAL_ECHOPGM("Starting USB host...");
if (!usb.start()) {
SERIAL_ECHOPGM(" Failed. Retrying in 2s.");
#if HAS_DISPLAY
LCD_MESSAGEPGM("USB start failed");
case DO_STARTUP: usbStartup(); break;
case WAIT_FOR_DEVICE:
if (task_state == UHS_STATE(RUNNING)) {
#if USB_DEBUG >= 1
SERIAL_ECHOLNPGM("USB device inserted");
#endif
state = USB_HOST_DELAY_INIT;
GOTO_STATE_AFTER_DELAY( WAIT_FOR_LUN, 250 );
}
else
state = USB_HOST_INITIALIZED;
SERIAL_EOL();
break;
case USB_HOST_INITIALIZED:
const uint8_t lastUsbTaskState = usb.getUsbTaskState();
usb.Task();
const uint8_t newUsbTaskState = usb.getUsbTaskState();
if (lastUsbTaskState == USB_STATE_RUNNING && newUsbTaskState != USB_STATE_RUNNING) {
// the user pulled the flash drive. Make sure the bulk storage driver releases the address
#ifdef USB_DEBUG
SERIAL_ECHOLNPGM("USB drive removed");
case WAIT_FOR_LUN:
/* USB device is inserted, but if it is an SD card,
* adapter it may not have an SD card in it yet. */
if (bulk.LUNIsGood(0)) {
#if USB_DEBUG >= 1
SERIAL_ECHOLNPGM("LUN is good");
#endif
//bulk.Release();
GOTO_STATE_AFTER_DELAY( MEDIA_READY, 100 );
}
if (lastUsbTaskState != USB_STATE_RUNNING && newUsbTaskState == USB_STATE_RUNNING) {
#ifdef USB_DEBUG
SERIAL_ECHOLNPGM("USB drive inserted");
else {
#ifdef USB_HOST_MANUAL_POLL
// Make sure we catch disconnect events
usb.busprobe();
usb.VBUS_changed();
#endif
#if USB_DEBUG >= 1
SERIAL_ECHOLNPGM("Waiting for media");
#endif
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
LCD_MESSAGEPGM("Waiting for media");
#endif
GOTO_STATE_AFTER_DELAY(state, 2000);
}
break;
case MEDIA_READY: break;
case MEDIA_ERROR: break;
}
if (state > WAIT_FOR_DEVICE && task_state != UHS_STATE(RUNNING)) {
// Handle device removal events
#if USB_DEBUG >= 1
SERIAL_ECHOLNPGM("USB device removed");
#endif
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
if (state != MEDIA_READY)
LCD_MESSAGEPGM("USB device removed");
#endif
GOTO_STATE_AFTER_DELAY( WAIT_FOR_DEVICE, 0 );
}
else if (state > WAIT_FOR_LUN && !bulk.LUNIsGood(0)) {
// Handle media removal events
#if USB_DEBUG >= 1
SERIAL_ECHOLNPGM("Media removed");
#endif
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
LCD_MESSAGEPGM("Media removed");
#endif
GOTO_STATE_AFTER_DELAY( WAIT_FOR_DEVICE, 0 );
}
else if (task_state == UHS_STATE(ERROR)) {
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
LCD_MESSAGEPGM("Media read error");
#endif
GOTO_STATE_AFTER_DELAY( MEDIA_ERROR, 0 );
}
}
}
// Marlin calls this function to check whether an USB drive is inserted.
// This is equivalent to polling the SD_DETECT when using SD cards.
bool Sd2Card::isInserted() {
return usb.getUsbTaskState() == USB_STATE_RUNNING;
return state == MEDIA_READY;
}
// Marlin calls this to initialize an SD card once it is inserted.
bool Sd2Card::init(const uint8_t sckRateID/*=0*/, const pin_t chipSelectPin/*=SD_CHIP_SELECT_PIN*/) {
if (!ready()) return false;
if (!bulk.LUNIsGood(0)) {
SERIAL_ECHOLNPGM("LUN zero is not good");
return false;
bool Sd2Card::ready() {
return state > DO_STARTUP;
}
// Marlin calls this to initialize an SD card once it is inserted.
bool Sd2Card::init(const uint8_t, const pin_t) {
if (!isInserted()) return false;
#if USB_DEBUG >= 1
const uint32_t sectorSize = bulk.GetSectorSize(0);
if (sectorSize != 512) {
SERIAL_ECHOLNPAIR("Expecting sector size of 512. Got: ", sectorSize);
return false;
}
#endif
#ifdef USB_DEBUG
#if USB_DEBUG >= 3
lun0_capacity = bulk.GetCapacity(0);
SERIAL_ECHOLNPAIR("LUN Capacity (in blocks): ", lun0_capacity);
#endif
@ -123,8 +287,8 @@ bool Sd2Card::init(const uint8_t sckRateID/*=0*/, const pin_t chipSelectPin/*=SD
// Returns the capacity of the card in blocks.
uint32_t Sd2Card::cardSize() {
if (!ready()) return 0;
#ifndef USB_DEBUG
if (!isInserted()) return false;
#if USB_DEBUG < 3
const uint32_t
#endif
lun0_capacity = bulk.GetCapacity(0);
@ -132,13 +296,13 @@ uint32_t Sd2Card::cardSize() {
}
bool Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
if (!ready()) return false;
#ifdef USB_DEBUG
if (!isInserted()) return false;
#if USB_DEBUG >= 3
if (block >= lun0_capacity) {
SERIAL_ECHOLNPAIR("Attempt to read past end of LUN: ", block);
return false;
}
#if USB_DEBUG > 1
#if USB_DEBUG >= 4
SERIAL_ECHOLNPAIR("Read block ", block);
#endif
#endif
@ -146,13 +310,13 @@ bool Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
}
bool Sd2Card::writeBlock(uint32_t block, const uint8_t* src) {
if (!ready()) return false;
#ifdef USB_DEBUG
if (!isInserted()) return false;
#if USB_DEBUG >= 3
if (block >= lun0_capacity) {
SERIAL_ECHOLNPAIR("Attempt to write past end of LUN: ", block);
return false;
}
#if USB_DEBUG > 1
#if USB_DEBUG >= 4
SERIAL_ECHOLNPAIR("Write block ", block);
#endif
#endif

@ -26,12 +26,6 @@
* \brief Sd2Card class for V2 SD/SDHC cards
*/
/* Uncomment USB_DEBUG to enable debugging.
* 1 - basic debugging and bounds checking
* 2 - print each block access
*/
//#define USB_DEBUG 1
#include "../SdFatConfig.h"
#include "../SdInfo.h"
@ -52,24 +46,13 @@
class Sd2Card {
private:
typedef enum : uint8_t {
USB_HOST_UNINITIALIZED,
USB_HOST_INITIALIZED,
USB_HOST_DELAY_INIT,
USB_HOST_WAITING
} state_t;
static state_t state;
uint32_t pos;
#ifdef USB_DEBUG
uint32_t lun0_capacity;
#endif
static inline bool ready() { return state == USB_HOST_INITIALIZED; }
static void usbStateDebug();
public:
static bool usbStartup();
bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=SD_CHIP_SELECT_PIN);
static void idle();
@ -87,4 +70,5 @@ class Sd2Card {
uint32_t cardSize();
static bool isInserted();
static bool ready();
};

@ -1,15 +1,4 @@
==== SUMMARY ====
Source Path: Repository: License:
------------ ----------- --------
usb_flashdrive/lib github.com/felis/USB_Host_Shield_2.0 GPLv2 or later
usb_flashdrive/lib/masstorage.cpp [1] github.com/greiman/UsbFat MIT
usb_flashdrive/lib/settings.h [1] github.com/greiman/UsbFat MIT
[1] Changes related to SKIP_WRITE_PROTECT and DELAY only
==== USB HOST SHIELD 2.0 LIBRARY ====
The lib/ folder contains a subset of the files from the USB Host Shield 2.0
@ -26,6 +15,15 @@ files needed for Marlin as "GPLv2 or later", as documented in this thread.
Small modifications have been made to the source. Please search for
USB_FLASH_DRIVE_SUPPORT or look at the patch file to see what was changed.
==== LICENSE SUMMARY ====
Source Path: Repository: License:
------------ ----------- --------
lib-uhs3/ github.com/felis/USB_Host_Shield_2.0 GPLv2 or later
lib-uhs3/lib/masstorage.cpp github.com/greiman/UsbFat [1] MIT
lib-uhs3/lib/settings.h github.com/greiman/UsbFat [1] MIT
[1] Changes related to SKIP_WRITE_PROTECT and DELAY only
==== PERFORMANCE ENHANCEMENTS FOR USB DRIVES ====

@ -26,7 +26,7 @@
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#if ENABLED(USB_FLASH_DRIVE_SUPPORT) && DISABLED(USE_UHS3_USB)
#include "Usb.h"

@ -45,8 +45,7 @@
#include "address.h"
//#include "avrpins.h"
#include "usb_ch9.h"
//#include "usbhost.h"
#include "../usb_host.h"
#include "usbhost.h"
#include "UsbCore.h"
#include "parsetools.h"
#include "confdescparser.h"

@ -25,7 +25,7 @@
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#if ENABLED(USB_FLASH_DRIVE_SUPPORT) && DISABLED(USE_UHS3_USB)
#include "masstorage.h"
@ -762,7 +762,7 @@ uint8_t BulkOnly::Page3F(uint8_t lun) {
buf[i] = 0x00;
}
WriteOk[lun] = true;
#if ENABLED(USB_FLASH_DRIVE_SUPPORT) && defined(SKIP_WRITE_PROTECT)
#ifdef SKIP_WRITE_PROTECT
return 0;
#endif
uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);

@ -191,6 +191,15 @@
#define bmSNDTOG1 0x80
#define rHXFR 0xf0 //30<<3
#undef tokSETUP
#undef tokIN
#undef tokOUT
#undef tokINHS
#undef tokOUTHS
#undef tokISOIN
#undef tokISOOUT
/* Host transfer token values for writing the HXFR register (R30) */
/* OR this bit field with the endpoint number in bits 3:0 */
#define tokSETUP 0x10 // HS=0, ISO=0, OUTNIN=0, SETUP=1

@ -25,7 +25,7 @@
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#if ENABLED(USB_FLASH_DRIVE_SUPPORT) && DISABLED(USE_UHS3_USB)
#include "Usb.h"

@ -25,7 +25,7 @@
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#if ENABLED(USB_FLASH_DRIVE_SUPPORT) && DISABLED(USE_UHS3_USB)
#include "Usb.h"

@ -23,12 +23,12 @@
* lib/usbhost.c". This has been rewritten to use SPI routines from the
* Marlin HAL */
#include "../../inc/MarlinConfigPre.h"
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#if ENABLED(USB_FLASH_DRIVE_SUPPORT) && DISABLED(USE_UHS3_USB)
#include "lib/Usb.h"
#include "usb_host.h"
#include "Usb.h"
#include "usbhost.h"
uint8_t MAX3421e::vbusState = 0;

@ -0,0 +1,31 @@
==== USB HOST SHIELD 3.0 LIBRARY ====
The lib-uhs3/ folder contains a subset of the files from the USB Host Shield
3.0 library:
https://github.com/felis/UHS30
==== LICENSE SUMMARY ====
Source Path: Repository: License:
------------ ----------- --------
usb_flashdrive/lib github.com/felis/UHS30 GPLv2 or later
==== MARLIN INTEGRATION WORK ====
All additional work done to integrate USB into Marlin was performed by
AlephObjects, Inc. and is licensed under the GPLv3.
This version of UHS3 has been modified for better compatibility with Marlin.
The upstream version of UHS 3.0 runs a frame timer interrupt every 1 ms to
handle device polling. This timer interrupt interferes with Marlin's stepper
IRQ, so the flag USB_HOST_MANUAL_POLL has been added to move the polling to
the idle task. Additional logic was added to disable and enable the frame
IRQ.
SKIP_PAGE3F and USB_NO_TEST_UNIT_READY were added to work around bugs with
certain devices.
-- marcio@alephobjects.com

@ -0,0 +1,249 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(__UHS_BULK_STORAGE_H__)
#define __UHS_BULK_STORAGE_H__
////////////////////////////////////////////////////////////////////////////////
// Define any of these options at the top of your sketch to override
// the defaults contained herewith. Do NOT do modifications here.
// Macro | Settings and notes | Default
// -----------------------------------------+-----------------------+-----------
// | 1 to 8 |
// | Each LUN needs |
// MASS_MAX_SUPPORTED_LUN | ~13 bytes to be able | 8
// | to track the state of |
// | each unit. |
// -----------------------------------------+-----------------------+-----------
// | Just define to use. |
// DEBUG_PRINTF_EXTRA_HUGE_UHS_BULK_STORAGE | works only if extra |
// | huge debug is on too. |
// -----------------------------------------^-----------------------^-----------
#ifndef MASS_MAX_SUPPORTED_LUN
#define MASS_MAX_SUPPORTED_LUN 8
#endif
#include "UHS_SCSI.h"
#define UHS_BULK_bmREQ_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
#define UHS_BULK_bmREQ_IN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
// Request Codes
#define UHS_BULK_REQ_ADSC 0x00U
#define UHS_BULK_REQ_GET 0xFCU
#define UHS_BULK_REQ_PUT 0xFDU
#define UHS_BULK_REQ_GET_MAX_LUN 0xFEU
#define UHS_BULK_REQ_BOMSR 0xFFU // Mass Storage Reset
#define UHS_BULK_CBW_SIGNATURE 0x43425355LU
#define UHS_BULK_CSW_SIGNATURE 0x53425355LU
#define UHS_BULK_CMD_DIR_OUT 0x00U
#define UHS_BULK_CMD_DIR_IN 0x80U
/* Bulk error codes */
#define UHS_BULK_ERR_SUCCESS UHS_HOST_ERROR_NONE
#define UHS_BULK_ERR_PHASE_ERROR 0x22U
#define UHS_BULK_ERR_UNIT_NOT_READY 0x23U
#define UHS_BULK_ERR_UNIT_BUSY 0x24U
#define UHS_BULK_ERR_STALL 0x25U
#define UHS_BULK_ERR_CMD_NOT_SUPPORTED 0x26U
#define UHS_BULK_ERR_INVALID_CSW 0x27U
#define UHS_BULK_ERR_NO_MEDIA 0x28U
#define UHS_BULK_ERR_BAD_LBA 0x29U
#define UHS_BULK_ERR_MEDIA_CHANGED 0x2AU
#define UHS_BULK_ERR_DEVICE_DISCONNECTED UHS_HOST_ERROR_UNPLUGGED
#define UHS_BULK_ERR_UNABLE_TO_RECOVER 0x32U // Reset recovery error
#define UHS_BULK_ERR_INVALID_LUN 0x33U
#define UHS_BULK_ERR_WRITE_STALL 0x34U
#define UHS_BULK_ERR_READ_NAKS 0x35U
#define UHS_BULK_ERR_WRITE_NAKS 0x36U
#define UHS_BULK_ERR_WRITE_PROTECTED 0x37U
#define UHS_BULK_ERR_NOT_IMPLEMENTED 0xFDU
#define UHS_BULK_ERR_GENERAL_SCSI_ERROR 0xF0U
#define UHS_BULK_ERR_GENERAL_USB_ERROR 0xFFU
#define UHS_BULK_ERR_USER 0xA0U // For subclasses to define their own error codes
#define MASS_MAX_ENDPOINTS 3
struct UHS_BULK_CommandBlockWrapperBase {
volatile uint32_t dCBWSignature;
volatile uint32_t dCBWTag;
volatile uint32_t dCBWDataTransferLength;
volatile uint8_t bmCBWFlags;
public:
UHS_BULK_CommandBlockWrapperBase(void) {
}
UHS_BULK_CommandBlockWrapperBase(uint32_t tag, uint32_t xflen, uint8_t flgs) :
dCBWSignature(UHS_BULK_CBW_SIGNATURE), dCBWTag(tag), dCBWDataTransferLength(xflen), bmCBWFlags(flgs) {
}
} __attribute__((packed));
struct UHS_BULK_CommandBlockWrapper : public UHS_BULK_CommandBlockWrapperBase {
struct {
uint8_t bmCBWLUN : 4;
uint8_t bmReserved1 : 4;
};
struct {
uint8_t bmCBWCBLength : 4;
uint8_t bmReserved2 : 4;
};
uint8_t CBWCB[16];
public:
// All zeroed.
UHS_BULK_CommandBlockWrapper() :
UHS_BULK_CommandBlockWrapperBase(0, 0, 0), bmReserved1(0), bmReserved2(0) {
for(int i = 0; i < 16; i++) CBWCB[i] = 0;
}
// Generic Wrap, CDB zeroed.
UHS_BULK_CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
UHS_BULK_CommandBlockWrapperBase(tag, xflen, flgs),
bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) {
for(int i = 0; i < 16; i++) CBWCB[i] = 0;
SCSI_CDB_BASE_t *x = reinterpret_cast<SCSI_CDB_BASE_t *>(CBWCB);
x->LUN = cmd;
}
// Wrap for CDB of 6
UHS_BULK_CommandBlockWrapper(uint32_t tag, uint32_t xflen, SCSI_CDB6_t *cdb, uint8_t dir) :
UHS_BULK_CommandBlockWrapperBase(tag, xflen, dir),
bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) {
memcpy(&CBWCB, cdb, 6);
}
// Wrap for CDB of 10
UHS_BULK_CommandBlockWrapper(uint32_t tag, uint32_t xflen, SCSI_CDB10_t *cdb, uint8_t dir) :
UHS_BULK_CommandBlockWrapperBase(tag, xflen, dir),
bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) {
memcpy(&CBWCB, cdb, 10);
}
} __attribute__((packed));
struct UHS_BULK_CommandStatusWrapper {
uint32_t dCSWSignature;
uint32_t dCSWTag;
uint32_t dCSWDataResidue;
uint8_t bCSWStatus;
} __attribute__((packed));
class UHS_Bulk_Storage : public UHS_USBInterface {
protected:
static const uint8_t epDataInIndex = 1; // DataIn endpoint index
static const uint8_t epDataOutIndex = 2; // DataOUT endpoint index
static const uint8_t epInterruptInIndex = 3; // InterruptIN endpoint index
uint8_t bMaxLUN; // Max LUN
volatile uint32_t dCBWTag; // Tag
volatile uint8_t bTheLUN; // Active LUN
volatile uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]; // Total sectors
volatile uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
volatile bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
volatile bool WriteOk[MASS_MAX_SUPPORTED_LUN];
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
public:
UHS_Bulk_Storage(UHS_USB_HOST_BASE *p);
volatile UHS_EpInfo epInfo[MASS_MAX_ENDPOINTS];
uint8_t GetbMaxLUN(void) {
return bMaxLUN; // Max LUN
}
uint8_t GetbTheLUN(void) {
return bTheLUN; // Active LUN
}
bool WriteProtected(uint8_t lun);
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 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);
uint8_t SCSITransaction6(SCSI_CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
uint8_t SCSITransaction10(SCSI_CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
// Configure and internal methods, these should never be called by a user's sketch.
uint8_t Start(void);
bool OKtoEnumerate(ENUMERATION_INFO *ei);
uint8_t SetInterface(ENUMERATION_INFO *ei);
uint8_t GetAddress(void) {
return bAddress;
};
void Poll(void);
void DriverDefaults(void);
private:
void Reset(void);
void CheckMedia(void);
bool IsValidCBW(uint8_t size, uint8_t *pcbw);
bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
bool IsValidCSW(UHS_BULK_CommandStatusWrapper *pcsw, UHS_BULK_CommandBlockWrapperBase *pcbw);
bool CheckLUN(uint8_t lun);
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 ModeSense6(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 ResetRecovery();
uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
uint8_t Page3F(uint8_t lun);
uint8_t ClearEpHalt(uint8_t index);
uint8_t Transaction(UHS_BULK_CommandBlockWrapper *cbw, uint16_t bsize, void *buf);
uint8_t HandleUsbError(uint8_t error, uint8_t index);
uint8_t HandleSCSIError(uint8_t status);
};
#if defined(LOAD_UHS_BULK_STORAGE) && !defined(UHS_BULK_STORAGE_LOADED)
#include "UHS_BULK_STORAGE_INLINE.h"
#endif
#endif // __MASSTORAGE_H__

@ -0,0 +1,328 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#ifndef UHS_SCSI_H
#define UHS_SCSI_H
/*
* Reference documents from T10 (http://www.t10.org)
* SCSI Primary Commands - 3 (SPC-3)
* SCSI Block Commands - 2 (SBC-2)
* Multi-Media Commands - 5 (MMC-5)
*/
/* Group 1 commands (CDB's here are should all be 6-bytes) */
#define SCSI_CMD_TEST_UNIT_READY 0x00U
#define SCSI_CMD_REQUEST_SENSE 0x03U
#define SCSI_CMD_FORMAT_UNIT 0x04U
#define SCSI_CMD_READ_6 0x08U
#define SCSI_CMD_WRITE_6 0x0AU
#define SCSI_CMD_INQUIRY 0x12U
#define SCSI_CMD_MODE_SELECT_6 0x15U
#define SCSI_CMD_MODE_SENSE_6 0x1AU
#define SCSI_CMD_START_STOP_UNIT 0x1BU
#define SCSI_CMD_PREVENT_REMOVAL 0x1EU
/* Group 2 Commands (CDB's here are 10-bytes) */
#define SCSI_CMD_READ_FORMAT_CAPACITIES 0x23U
#define SCSI_CMD_READ_CAPACITY_10 0x25U
#define SCSI_CMD_READ_10 0x28U
#define SCSI_CMD_WRITE_10 0x2AU
#define SCSI_CMD_SEEK_10 0x2BU
#define SCSI_CMD_ERASE_10 0x2CU
#define SCSI_CMD_WRITE_AND_VERIFY_10 0x2EU
#define SCSI_CMD_VERIFY_10 0x2FU
#define SCSI_CMD_SYNCHRONIZE_CACHE 0x35U
#define SCSI_CMD_WRITE_BUFFER 0x3BU
#define SCSI_CMD_READ_BUFFER 0x3CU
#define SCSI_CMD_READ_SUBCHANNEL 0x42U
#define SCSI_CMD_READ_TOC 0x43U
#define SCSI_CMD_READ_HEADER 0x44U
#define SCSI_CMD_PLAY_AUDIO_10 0x45U
#define SCSI_CMD_GET_CONFIGURATION 0x46U
#define SCSI_CMD_PLAY_AUDIO_MSF 0x47U
#define SCSI_CMD_PLAY_AUDIO_TI 0x48U
#define SCSI_CMD_PLAY_TRACK_REL_10 0x49U
#define SCSI_CMD_GET_EVENT_STATUS 0x4AU
#define SCSI_CMD_PAUSE_RESUME 0x4BU
#define SCSI_CMD_READ_DISC_INFORMATION 0x51U
#define SCSI_CMD_READ_TRACK_INFORMATION 0x52U
#define SCSI_CMD_RESERVE_TRACK 0x53U
#define SCSI_CMD_SEND_OPC_INFORMATION 0x54U
#define SCSI_CMD_MODE_SELECT_10 0x55U
#define SCSI_CMD_REPAIR_TRACK 0x58U
#define SCSI_CMD_MODE_SENSE_10 0x5AU
#define SCSI_CMD_CLOSE_TRACK_SESSION 0x5BU
#define SCSI_CMD_READ_BUFFER_CAPACITY 0x5CU
#define SCSI_CMD_SEND_CUE_SHEET 0x5DU
/* Group 5 Commands (CDB's here are 12-bytes) */
#define SCSI_CMD_REPORT_LUNS 0xA0U
#define SCSI_CMD_BLANK 0xA1U
#define SCSI_CMD_SECURITY_PROTOCOL_IN 0xA2U
#define SCSI_CMD_SEND_KEY 0xA3U
#define SCSI_CMD_REPORT_KEY 0xA4U
#define SCSI_CMD_PLAY_AUDIO_12 0xA5U
#define SCSI_CMD_LOAD_UNLOAD 0xA6U
#define SCSI_CMD_SET_READ_AHEAD 0xA7U
#define SCSI_CMD_READ_12 0xA8U
#define SCSI_CMD_PLAY_TRACK_REL_12 0xA9U
#define SCSI_CMD_WRITE_12 0xAAU
#define SCSI_CMD_READ_MEDIA_SERIAL_12 0xABU
#define SCSI_CMD_GET_PERFORMANCE 0xACU
#define SCSI_CMD_READ_DVD_STRUCTURE 0xADU
#define SCSI_CMD_SECURITY_PROTOCOL_OUT 0xB5U
#define SCSI_CMD_SET_STREAMING 0xB6U
#define SCSI_CMD_READ_MSF 0xB9U
#define SCSI_CMD_SET_SPEED 0xBBU
#define SCSI_CMD_MECHANISM_STATUS 0xBDU
#define SCSI_CMD_READ_CD 0xBEU
#define SCSI_CMD_SEND_DISC_STRUCTURE 0xBFU
/* Vendor-unique Commands, included for completeness */
#define SCSI_CMD_CD_PLAYBACK_STATUS 0xC4U /* SONY unique */
#define SCSI_CMD_PLAYBACK_CONTROL 0xC9U /* SONY unique */
#define SCSI_CMD_READ_CDDA 0xD8U /* Vendor unique */
#define SCSI_CMD_READ_CDXA 0xDBU /* Vendor unique */
#define SCSI_CMD_READ_ALL_SUBCODES 0xDFU /* Vendor unique */
/* SCSI error codes */
#define SCSI_S_NOT_READY 0x02U
#define SCSI_S_MEDIUM_ERROR 0x03U
#define SCSI_S_ILLEGAL_REQUEST 0x05U
#define SCSI_S_UNIT_ATTENTION 0x06U
#define SCSI_ASC_LBA_OUT_OF_RANGE 0x21U
#define SCSI_ASC_MEDIA_CHANGED 0x28U
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3AU
struct SCSI_Capacity {
uint8_t data[8];
//uint32_t dwBlockAddress;
//uint32_t dwBlockLength;
} __attribute__((packed));
struct SCSI_CDB_BASE {
uint8_t Opcode;
unsigned unused : 5;
unsigned LUN : 3;
uint8_t info[12];
} __attribute__((packed));
typedef SCSI_CDB_BASE SCSI_CDB_BASE_t;
struct SCSI_CDB6 {
uint8_t Opcode;
unsigned LBAMSB : 5;
unsigned LUN : 3;
uint8_t LBAHB;
uint8_t LBALB;
uint8_t AllocationLength;
uint8_t Control;
public:
SCSI_CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
Opcode(_Opcode), LBAMSB(UHS_UINT8_BYTE2(LBA) & 0x1f), LUN(_LUN), LBAHB(UHS_UINT8_BYTE1(LBA)), LBALB(UHS_UINT8_BYTE0(LBA)),
AllocationLength(_AllocationLength), Control(_Control) {
}
SCSI_CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
Opcode(_Opcode), LBAMSB(0), LUN(_LUN), LBAHB(0), LBALB(0),
AllocationLength(_AllocationLength), Control(_Control) {
}
} __attribute__((packed));
typedef SCSI_CDB6 SCSI_CDB6_t;
struct SCSI_CDB10 {
uint8_t Opcode;
unsigned Service_Action : 5;
unsigned LUN : 3;
uint8_t LBA_L_M_MB;
uint8_t LBA_L_M_LB;
uint8_t LBA_L_L_MB;
uint8_t LBA_L_L_LB;
uint8_t Misc2;
uint8_t ALC_MB;
uint8_t ALC_LB;
uint8_t Control;
public:
SCSI_CDB10(uint8_t _Opcode, uint8_t _LUN) :
Opcode(_Opcode), Service_Action(0), LUN(_LUN),
LBA_L_M_MB(0), LBA_L_M_LB(0), LBA_L_L_MB(0), LBA_L_L_LB(0),
Misc2(0), ALC_MB(0), ALC_LB(0), Control(0) {
}
SCSI_CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA) :
Opcode(_Opcode), Service_Action(0), LUN(_LUN),
LBA_L_M_MB(UHS_UINT8_BYTE3(_LBA)), LBA_L_M_LB(UHS_UINT8_BYTE2(_LBA)), LBA_L_L_MB(UHS_UINT8_BYTE1(_LBA)), LBA_L_L_LB(UHS_UINT8_BYTE0(_LBA)),
Misc2(0), ALC_MB(UHS_UINT8_BYTE1(xflen)), ALC_LB(UHS_UINT8_BYTE0(xflen)), Control(0) {
}
} __attribute__((packed));
typedef SCSI_CDB10 SCSI_CDB10_t;
struct SCSI_CDB12 {
uint8_t Opcode;
unsigned Service_Action : 5;
unsigned Misc : 3;
uint8_t LBA_L_M_LB;
uint8_t LBA_L_L_MB;
uint8_t LBA_L_L_LB;
uint8_t ALC_M_LB;
uint8_t ALC_L_MB;
uint8_t ALC_L_LB;
uint8_t Control;
} __attribute__((packed));
typedef SCSI_CDB12 SCSI_CDB12_t;
struct SCSI_CDB_LBA32_16 {
uint8_t Opcode;
unsigned Service_Action : 5;
unsigned Misc : 3;
uint8_t LBA_L_M_MB;
uint8_t LBA_L_M_LB;
uint8_t LBA_L_L_MB;
uint8_t LBA_L_L_LB;
uint8_t A_M_M_MB;
uint8_t A_M_M_LB;
uint8_t A_M_L_MB;
uint8_t A_M_L_LB;
uint8_t ALC_M_MB;
uint8_t ALC_M_LB;
uint8_t ALC_L_MB;
uint8_t ALC_L_LB;
uint8_t Misc2;
uint8_t Control;
} __attribute__((packed));
struct SCSI_CDB_LBA64_16 {
uint8_t Opcode;
uint8_t Misc;
uint8_t LBA_M_M_MB;
uint8_t LBA_M_M_LB;
uint8_t LBA_M_L_MB;
uint8_t LBA_M_L_LB;
uint8_t LBA_L_M_MB;
uint8_t LBA_L_M_LB;
uint8_t LBA_L_L_MB;
uint8_t LBA_L_L_LB;
uint8_t ALC_M_MB;
uint8_t ALC_M_LB;
uint8_t ALC_L_MB;
uint8_t ALC_L_LB;
uint8_t Misc2;
uint8_t Control;
} __attribute__((packed));
struct SCSI_Inquiry_Response {
uint8_t DeviceType : 5;
uint8_t PeripheralQualifier : 3;
unsigned Reserved : 7;
unsigned Removable : 1;
uint8_t Version;
unsigned ResponseDataFormat : 4;
unsigned HISUP : 1;
unsigned NormACA : 1;
unsigned TrmTsk : 1;
unsigned AERC : 1;
uint8_t AdditionalLength;
unsigned PROTECT : 1;
unsigned Res : 2;
unsigned ThreePC : 1;
unsigned TPGS : 2;
unsigned ACC : 1;
unsigned SCCS : 1;
unsigned ADDR16 : 1;
unsigned R1 : 1;
unsigned R2 : 1;
unsigned MCHNGR : 1;
unsigned MULTIP : 1;
unsigned VS : 1;
unsigned ENCSERV : 1;
unsigned BQUE : 1;
unsigned SoftReset : 1;
unsigned CmdQue : 1;
unsigned Reserved4 : 1;
unsigned Linked : 1;
unsigned Sync : 1;
unsigned WideBus16Bit : 1;
unsigned WideBus32Bit : 1;
unsigned RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} __attribute__((packed));
struct SCSI_Request_Sense_Response {
uint8_t bResponseCode;
uint8_t bSegmentNumber;
uint8_t bmSenseKey : 4;
uint8_t bmReserved : 1;
uint8_t bmILI : 1;
uint8_t bmEOM : 1;
uint8_t bmFileMark : 1;
uint8_t Information[4];
uint8_t bAdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t bAdditionalSenseCode;
uint8_t bAdditionalSenseQualifier;
uint8_t bFieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} __attribute__((packed));
#endif /* UHS_SCSI_H */

@ -0,0 +1,33 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#ifndef _UHS_UNOFFICIAL_IDs_h
#define _UHS_UNOFFICIAL_IDs_h
// Bogus unofficial and unregistered VIDs from cloners to be listed here.
#define UHS_VID_UNOFFICIAL_JOYTECH 0x162EU // For unofficial Joytech controllers
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,336 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(_UHS_host_h_) || defined(USBCORE_H)
#error "Never include UHS_UsbCore.h directly; include UHS_Host.h instead"
#else
#define USBCORE_H
#ifndef UHS_HOST_MAX_INTERFACE_DRIVERS
#define UHS_HOST_MAX_INTERFACE_DRIVERS 0x10U // Default maximum number of USB interface drivers
#endif
#if !defined(SYSTEM_OR_SPECIAL_YIELD)
#define SYSTEM_OR_SPECIAL_YIELD(...) VOID0
#endif
#if !defined(SYSTEM_OR_SPECIAL_YIELD_FROM_ISR)
#define SYSTEM_OR_SPECIAL_YIELD_FROM_ISR(...) SYSTEM_OR_SPECIAL_YIELD
#endif
// As we make extensions to a target interface add to UHS_HOST_MAX_INTERFACE_DRIVERS
// This offset gets calculated for supporting wide subclasses, such as HID, BT, etc.
#define UHS_HID_INDEX (UHS_HOST_MAX_INTERFACE_DRIVERS + 1)
/* Common setup data constant combinations */
//get descriptor request type
#define UHS_bmREQ_GET_DESCR (USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE)
//set request type for all but 'set feature' and 'set interface'
#define UHS_bmREQ_SET (USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE)
//get interface request type
#define UHS_bmREQ_CL_GET_INTF (USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE)
// D7 data transfer direction (0 - host-to-device, 1 - device-to-host)
// D6-5 Type (0- standard, 1 - class, 2 - vendor, 3 - reserved)
// D4-0 Recipient (0 - device, 1 - interface, 2 - endpoint, 3 - other, 4..31 - reserved)
// TO-DO: Use the python script to generate these.
// TO-DO: Add _all_ subclasses here.
// USB Device Classes, Subclasses and Protocols
////////////////////////////////////////////////////////////////////////////////
// Use Class Info in the Interface Descriptors
#define UHS_USB_CLASS_USE_CLASS_INFO 0x00U
////////////////////////////////////////////////////////////////////////////////
// Audio
#define UHS_USB_CLASS_AUDIO 0x01U
// Subclasses
#define UHS_USB_SUBCLASS_AUDIOCONTROL 0x01U
#define UHS_USB_SUBCLASS_AUDIOSTREAMING 0x02U
#define UHS_USB_SUBCLASS_MIDISTREAMING 0x03U
////////////////////////////////////////////////////////////////////////////////
// Communications and CDC Control
#define UHS_USB_CLASS_COM_AND_CDC_CTRL 0x02U
////////////////////////////////////////////////////////////////////////////////
// HID
#define UHS_USB_CLASS_HID 0x03U
// Subclasses
#define UHS_HID_BOOT_SUBCLASS 0x01U
// Protocols
#define UHS_HID_PROTOCOL_HIDBOOT_KEYBOARD 0x01U
#define UHS_HID_PROTOCOL_HIDBOOT_MOUSE 0x02U
////////////////////////////////////////////////////////////////////////////////
// Physical
#define UHS_USB_CLASS_PHYSICAL 0x05U
////////////////////////////////////////////////////////////////////////////////
// Image
#define UHS_USB_CLASS_IMAGE 0x06U
////////////////////////////////////////////////////////////////////////////////
// Printer
#define UHS_USB_CLASS_PRINTER 0x07U
////////////////////////////////////////////////////////////////////////////////
// Mass Storage
#define UHS_USB_CLASS_MASS_STORAGE 0x08
// Subclasses
#define UHS_BULK_SUBCLASS_SCSI_NOT_REPORTED 0x00U // De facto use
#define UHS_BULK_SUBCLASS_RBC 0x01U
#define UHS_BULK_SUBCLASS_ATAPI 0x02U // MMC-5 (ATAPI)
#define UHS_BULK_SUBCLASS_OBSOLETE1 0x03U // Was QIC-157
#define UHS_BULK_SUBCLASS_UFI 0x04U // Specifies how to interface Floppy Disk Drives to USB
#define UHS_BULK_SUBCLASS_OBSOLETE2 0x05U // Was SFF-8070i
#define UHS_BULK_SUBCLASS_SCSI 0x06U // SCSI Transparent Command Set
#define UHS_BULK_SUBCLASS_LSDFS 0x07U // Specifies how host has to negotiate access before trying SCSI
#define UHS_BULK_SUBCLASS_IEEE1667 0x08U
// Protocols
#define UHS_STOR_PROTO_CBI 0x00U // CBI (with command completion interrupt)
#define UHS_STOR_PROTO_CBI_NO_INT 0x01U // CBI (without command completion interrupt)
#define UHS_STOR_PROTO_OBSOLETE 0x02U
#define UHS_STOR_PROTO_BBB 0x50U // Bulk Only Transport
#define UHS_STOR_PROTO_UAS 0x62U
////////////////////////////////////////////////////////////////////////////////
// Hub
#define UHS_USB_CLASS_HUB 0x09U
////////////////////////////////////////////////////////////////////////////////
// CDC-Data
#define UHS_USB_CLASS_CDC_DATA 0x0AU
////////////////////////////////////////////////////////////////////////////////
// Smart-Card
#define UHS_USB_CLASS_SMART_CARD 0x0BU
////////////////////////////////////////////////////////////////////////////////
// Content Security
#define UHS_USB_CLASS_CONTENT_SECURITY 0x0DU
////////////////////////////////////////////////////////////////////////////////
// Video
#define UHS_USB_CLASS_VIDEO 0x0EU
////////////////////////////////////////////////////////////////////////////////
// Personal Healthcare
#define UHS_USB_CLASS_PERSONAL_HEALTH 0x0FU
////////////////////////////////////////////////////////////////////////////////
// Diagnostic Device
#define UHS_USB_CLASS_DIAGNOSTIC_DEVICE 0xDCU
////////////////////////////////////////////////////////////////////////////////
// Wireless Controller
#define UHS_USB_CLASS_WIRELESS_CTRL 0xE0U
////////////////////////////////////////////////////////////////////////////////
// Miscellaneous
#define UHS_USB_CLASS_MISC 0xEFU
////////////////////////////////////////////////////////////////////////////////
// Application Specific
#define UHS_USB_CLASS_APP_SPECIFIC 0xFEU
////////////////////////////////////////////////////////////////////////////////
// Vendor Specific
#define UHS_USB_CLASS_VENDOR_SPECIFIC 0xFFU
////////////////////////////////////////////////////////////////////////////////
/* USB state machine states */
#define UHS_USB_HOST_STATE_MASK 0xF0U
// Configure states, MSN == 0 --------------------------V
#define UHS_USB_HOST_STATE_DETACHED 0x00U
#define UHS_USB_HOST_STATE_DEBOUNCE 0x01U
#define UHS_USB_HOST_STATE_DEBOUNCE_NOT_COMPLETE 0x02U
#define UHS_USB_HOST_STATE_RESET_NOT_COMPLETE 0x03U
#define UHS_USB_HOST_STATE_WAIT_SOF 0x04U
#define UHS_USB_HOST_STATE_WAIT_BUS_READY 0x05U
#define UHS_USB_HOST_STATE_RESET_DEVICE 0x0AU
#define UHS_USB_HOST_STATE_CONFIGURING 0x0CU // Looks like "CO"nfig (backwards)
#define UHS_USB_HOST_STATE_CONFIGURING_DONE 0x0DU // Looks like "DO"one (backwards)
#define UHS_USB_HOST_STATE_CHECK 0x0EU
#define UHS_USB_HOST_STATE_ILLEGAL 0x0FU // Foo
// Run states, MSN != 0 --------------------------------V
#define UHS_USB_HOST_STATE_RUNNING 0x60U // Looks like "GO"
#define UHS_USB_HOST_STATE_IDLE 0x1DU // Looks like "ID"le
#define UHS_USB_HOST_STATE_ERROR 0xF0U // Looks like "FO"o
#define UHS_USB_HOST_STATE_INITIALIZE 0x10U // Looks like "I"nit
// Host SE result codes.
// Common SE results are stored in the low nybble, all interface drivers understand these plus 0x1f.
// Extended SE results are 0x10-0x1e. SE code only understands these internal to the hardware.
// Values > 0x1F are driver or other internal error conditions.
// Return these result codes from your host controller driver to match the error condition
// ALL Non-zero values are errors.
// Values not listed in this table are not handled in the base class, or any host driver.
#define UHS_HOST_ERROR_NONE 0x00U // No error
#define UHS_HOST_ERROR_BUSY 0x01U // transfer pending
#define UHS_HOST_ERROR_BADREQ 0x02U // Transfer Launch Request was bad
#define UHS_HOST_ERROR_DMA 0x03U // DMA was too short, or too long
#define UHS_HOST_ERROR_NAK 0x04U // Peripheral returned NAK
#define UHS_HOST_ERROR_STALL 0x05U // Peripheral returned STALL
#define UHS_HOST_ERROR_TOGERR 0x06U // Toggle error/ISO over-underrun
#define UHS_HOST_ERROR_WRONGPID 0x07U // Received wrong Packet ID
#define UHS_HOST_ERROR_BADBC 0x08U // Byte count is bad
#define UHS_HOST_ERROR_PIDERR 0x09U // Received Packet ID is corrupted
#define UHS_HOST_ERROR_BADRQ 0x0AU // Packet error. Increase max packet.
#define UHS_HOST_ERROR_CRC 0x0BU // USB CRC was incorrect
#define UHS_HOST_ERROR_KERR 0x0CU // K-state instead of response, usually indicates wrong speed
#define UHS_HOST_ERROR_JERR 0x0DU // J-state instead of response, usually indicates wrong speed
#define UHS_HOST_ERROR_TIMEOUT 0x0EU // Device did not respond in time
#define UHS_HOST_ERROR_BABBLE 0x0FU // Line noise/unexpected data
#define UHS_HOST_ERROR_MEM_LAT 0x10U // Error caused by memory latency.
#define UHS_HOST_ERROR_NYET 0x11U // OUT transfer accepted with NYET
// Addressing error codes
#define ADDR_ERROR_INVALID_INDEX 0xA0U
#define ADDR_ERROR_INVALID_ADDRESS 0xA1U
// Common Interface Driver error codes
#define UHS_HOST_ERROR_DEVICE_NOT_SUPPORTED 0xD1U // Driver doesn't support the device or interfaces
#define UHS_HOST_ERROR_DEVICE_INIT_INCOMPLETE 0xD2U // Init partially finished, but died.
#define UHS_HOST_ERROR_CANT_REGISTER_DEVICE_CLASS 0xD3U // There was no driver for the interface requested.
#define UHS_HOST_ERROR_ADDRESS_POOL_FULL 0xD4U // No addresses left in the address pool.
#define UHS_HOST_ERROR_HUB_ADDRESS_OVERFLOW 0xD5U // No hub addresses left. The maximum is 7.
#define UHS_HOST_ERROR_NO_ADDRESS_IN_POOL 0xD6U // Address was not allocated in the pool, thus not found.
#define UHS_HOST_ERROR_NULL_EPINFO 0xD7U // The supplied endpoint was NULL, indicates a bug or other problem.
#define UHS_HOST_ERROR_BAD_ARGUMENT 0xD8U // Indicates a range violation bug.
#define UHS_HOST_ERROR_DEVICE_DRIVER_BUSY 0xD9U // The interface driver is busy or out buffer is full, try again later.
#define UHS_HOST_ERROR_BAD_MAX_PACKET_SIZE 0xDAU // The maximum packet size was exceeded. Try again with smaller size.
#define UHS_HOST_ERROR_NO_ENDPOINT_IN_TABLE 0xDBU // The endpoint could not be found in the endpoint table.
#define UHS_HOST_ERROR_UNPLUGGED 0xDEU // Someone removed the USB device, or Vbus was turned off.
#define UHS_HOST_ERROR_NOMEM 0xDFU // Out Of Memory.
// Control request stream errors
#define UHS_HOST_ERROR_FailGetDevDescr 0xE1U
#define UHS_HOST_ERROR_FailSetDevTblEntry 0xE2U
#define UHS_HOST_ERROR_FailGetConfDescr 0xE3U
#define UHS_HOST_ERROR_END_OF_STREAM 0xEFU
// Host base class specific Error codes
#define UHS_HOST_ERROR_NOT_IMPLEMENTED 0xFEU
#define UHS_HOST_ERROR_TRANSFER_TIMEOUT 0xFFU
// SEI interaction defaults
#define UHS_HOST_TRANSFER_MAX_MS 10000 // USB transfer timeout in ms, per section 9.2.6.1 of USB 2.0 spec
#define UHS_HOST_TRANSFER_RETRY_MAXIMUM 3 // 3 retry limit for a transfer
#define UHS_HOST_DEBOUNCE_DELAY_MS 500 // settle delay in milliseconds
#define UHS_HUB_RESET_DELAY_MS 20 // hub port reset delay, 10ms recomended, but can be up to 20ms
//
// We only provide the minimum needed information for enumeration.
// Interface drivers should be able to set up what is needed with nothing more.
// A driver needs to know the following information:
// 1: address on the USB network, parent and port (aka UsbDeviceAddress)
// 2: endpoints
// 3: vid:pid, class, subclass, protocol
//
struct ENDPOINT_INFO {
uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
uint8_t bmAttributes; // Endpoint transfer type.
uint16_t wMaxPacketSize; // Maximum packet size.
uint8_t bInterval; // Polling interval in frames.
} __attribute__((packed));
struct INTERFACE_INFO {
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t numep;
uint8_t klass;
uint8_t subklass;
uint8_t protocol;
ENDPOINT_INFO epInfo[16];
} __attribute__((packed));
struct ENUMERATION_INFO {
uint16_t vid;
uint16_t pid;
uint16_t bcdDevice;
uint8_t klass;
uint8_t subklass;
uint8_t protocol;
uint8_t bMaxPacketSize0;
uint8_t currentconfig;
uint8_t parent;
uint8_t port;
uint8_t address;
INTERFACE_INFO interface;
} __attribute__((packed));
/* USB Setup Packet Structure */
typedef struct {
// offset description
// 0 Bit-map of request type
union {
uint8_t bmRequestType;
struct {
uint8_t recipient : 5; // Recipient of the request
uint8_t type : 2; // Type of request
uint8_t direction : 1; // Direction of data transfer
} __attribute__((packed));
} ReqType_u;
// 1 Request
uint8_t bRequest;
// 2 Depends on bRequest
union {
uint16_t wValue;
struct {
uint8_t wValueLo;
uint8_t wValueHi;
} __attribute__((packed));
} wVal_u;
// 4 Depends on bRequest
uint16_t wIndex;
// 6 Depends on bRequest
uint16_t wLength;
// 8 bytes total
} __attribute__((packed)) SETUP_PKT, *PSETUP_PKT;
// little endian :-) 8 8 8 8 16 16
#define mkSETUP_PKT8(bmReqType, bRequest, wValLo, wValHi, wInd, total) ((uint64_t)(((uint64_t)(bmReqType)))|(((uint64_t)(bRequest))<<8)|(((uint64_t)(wValLo))<<16)|(((uint64_t)(wValHi))<<24)|(((uint64_t)(wInd))<<32)|(((uint64_t)(total)<<48)))
#define mkSETUP_PKT16(bmReqType, bRequest, wVal, wInd, total) ((uint64_t)(((uint64_t)(bmReqType)))|(((uint64_t)(bRequest))<<8)|(((uint64_t)(wVal ))<<16) |(((uint64_t)(wInd))<<32)|(((uint64_t)(total)<<48)))
// Big endian -- but we aren't able to use this :-/
//#define mkSETUP_PKT8(bmReqType, bRequest, wValLo, wValHi, wInd, total) ((uint64_t)(((uint64_t)(bmReqType))<<56)|(((uint64_t)(bRequest))<<48)|(((uint64_t)(wValLo))<<40)|(((uint64_t)(wValHi))<<32)|(((uint64_t)(wInd))<<16)|((uint64_t)(total)))
//#define mkSETUP_PKT16(bmReqType, bRequest, wVal, wInd, total) ((uint64_t)(((uint64_t)(bmReqType))<<56)|(((uint64_t)(bRequest))<<48) |(((uint64_t)(wVal))<<32) |(((uint64_t)(wInd))<<16)|((uint64_t)(total)))
#endif /* USBCORE_H */

@ -0,0 +1,248 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(_UHS_host_h_) || defined(__ADDRESS_H__)
#error "Never include UHS_address.h directly; include UHS_Usb.h instead"
#else
#define __ADDRESS_H__
/* NAK powers. To save space in endpoint data structure, amount of retries before giving up and returning 0x4 is stored in */
/* bmNakPower as a power of 2. The actual nak_limit is then calculated as nak_limit = ( 2^bmNakPower - 1) */
#define UHS_USB_NAK_MAX_POWER 14 // NAK binary order maximum value
#define UHS_USB_NAK_DEFAULT 13 // default 16K-1 NAKs before giving up
#define UHS_USB_NAK_NOWAIT 1 // Single NAK stops transfer
#define UHS_USB_NAK_NONAK 0 // Do not count NAKs, stop retrying after USB Timeout. Try not to use this.
#define bmUSB_DEV_ADDR_PORT 0x07
#define bmUSB_DEV_ADDR_PARENT 0x78
#define bmUSB_DEV_ADDR_HUB 0x40
// TODO: embed parent?
struct UHS_EpInfo {
uint8_t epAddr; // Endpoint address
uint8_t bIface;
uint16_t maxPktSize; // Maximum packet size
union {
uint8_t epAttribs;
struct {
uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise
uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise
uint8_t bmNeedPing : 1; // 1 == ping protocol needed for next out packet
uint8_t bmNakPower : 5; // Binary order for NAK_LIMIT value
} __attribute__((packed));
};
} __attribute__((packed));
// TODO: embed parent address and port into epinfo struct,
// and nuke this address stupidity.
// This is a compact scheme. Should also support full spec.
// This produces a 7 hub limit, 49 devices + 7 hubs, 56 total.
//
// 7 6 5 4 3 2 1 0
// ---------------------------------
// | | H | P | P | P | A | A | A |
// ---------------------------------
//
// H - if 1 the address is a hub address
// P - parent hub number
// A - port number of parent
//
struct UHS_DeviceAddress {
union {
struct {
uint8_t bmAddress : 3; // port number
uint8_t bmParent : 3; // parent hub address
uint8_t bmHub : 1; // hub flag
uint8_t bmReserved : 1; // reserved, must be zero
} __attribute__((packed));
uint8_t devAddress;
};
} __attribute__((packed));
struct UHS_Device {
volatile UHS_EpInfo *epinfo[UHS_HOST_MAX_INTERFACE_DRIVERS]; // endpoint info pointer
UHS_DeviceAddress address;
uint8_t epcount; // number of endpoints
uint8_t speed; // indicates device speed
} __attribute__((packed));
typedef void (*UsbDeviceHandleFunc)(UHS_Device *pdev);
class AddressPool {
UHS_EpInfo dev0ep; //Endpoint data structure used during enumeration for uninitialized device
// In order to avoid hub address duplication, this should use bits
uint8_t hubCounter; // hub counter
UHS_Device thePool[UHS_HOST_MAX_INTERFACE_DRIVERS];
// Initializes address pool entry
void UHS_NI InitEntry(uint8_t index) {
thePool[index].address.devAddress = 0;
thePool[index].epcount = 1;
thePool[index].speed = 0;
for(uint8_t i = 0; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) {
thePool[index].epinfo[i] = &dev0ep;
}
};
// Returns thePool index for a given address
uint8_t UHS_NI FindAddressIndex(uint8_t address = 0) {
for(uint8_t i = 1; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) {
if(thePool[i].address.devAddress == address)
return i;
}
return 0;
};
// Returns thePool child index for a given parent
uint8_t UHS_NI FindChildIndex(UHS_DeviceAddress addr, uint8_t start = 1) {
for(uint8_t i = (start < 1 || start >= UHS_HOST_MAX_INTERFACE_DRIVERS) ? 1 : start; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) {
if(thePool[i].address.bmParent == addr.bmAddress)
return i;
}
return 0;
};
// Frees address entry specified by index parameter
void UHS_NI FreeAddressByIndex(uint8_t index) {
// Zero field is reserved and should not be affected
if(index == 0)
return;
UHS_DeviceAddress uda = thePool[index].address;
// If a hub was switched off all port addresses should be freed
if(uda.bmHub == 1) {
for(uint8_t i = 1; (i = FindChildIndex(uda, i));)
FreeAddressByIndex(i);
// FIXME: use BIT MASKS
// If the hub had the last allocated address, hubCounter should be decremented
if(hubCounter == uda.bmAddress)
hubCounter--;
}
InitEntry(index);
}
void InitAllAddresses(void) {
for(uint8_t i = 1; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) InitEntry(i);
hubCounter = 0;
};
public:
AddressPool() {
hubCounter = 0;
// Zero address is reserved
InitEntry(0);
thePool[0].epinfo[0] = &dev0ep;
dev0ep.epAddr = 0;
#if UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE
dev0ep.maxPktSize = 0x40; //starting at 0x40 and work down
#else
dev0ep.maxPktSize = 0x08;
#endif
dev0ep.epAttribs = 0; //set DATA0/1 toggles to 0
dev0ep.bmNakPower = UHS_USB_NAK_MAX_POWER;
InitAllAddresses();
};
// Returns a pointer to a specified address entry
UHS_Device* UHS_NI GetUsbDevicePtr(uint8_t addr) {
if(!addr)
return thePool;
uint8_t index = FindAddressIndex(addr);
return (!index) ? NULL : &thePool[index];
};
// Allocates new address
uint8_t UHS_NI AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 1) {
/* if (parent != 0 && port == 0)
USB_HOST_SERIAL.println("PRT:0"); */
UHS_DeviceAddress _parent;
_parent.devAddress = parent;
if(_parent.bmReserved || port > 7)
//if(parent > 127 || port > 7)
return 0;
// FIXME: use BIT MASKS
if(is_hub && hubCounter == 7)
return 0;
// finds first empty address entry starting from one
uint8_t index = FindAddressIndex(0);
if(!index) // if empty entry is not found
return 0;
UHS_DeviceAddress addr;
addr.devAddress = port;
addr.bmParent = _parent.bmAddress;
// FIXME: use BIT MASKS
if(is_hub) {
hubCounter++;
addr.bmHub = 1;
addr.bmAddress = hubCounter;
}
thePool[index].address = addr;
#if DEBUG_PRINTF_EXTRA_HUGE
#if defined(UHS_DEBUG_USB_ADDRESS)
printf("Address: %x (%x.%x.%x)\r\n", addr.devAddress, addr.bmHub, addr.bmParent, addr.bmAddress);
#endif
#endif
return thePool[index].address.devAddress;
};
void UHS_NI FreeAddress(uint8_t addr) {
// if the root hub is disconnected all the addresses should be initialized
if(addr == 0x41) {
InitAllAddresses();
return;
}
uint8_t index = FindAddressIndex(addr);
FreeAddressByIndex(index);
};
};
#endif // __ADDRESS_H__

@ -0,0 +1,70 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(_usb_h_) || defined(__HEXDUMP_H__)
#error "Never include UHS_hexdump.h directly; include UHS_Usb.h instead"
#else
#define __HEXDUMP_H__
extern int UsbDEBUGlvl;
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
class HexDumper : public BASE_CLASS {
uint8_t byteCount;
OFFSET_TYPE byteTotal;
public:
HexDumper() : byteCount(0), byteTotal(0) {
};
void Initialize(void) {
byteCount = 0;
byteTotal = 0;
};
virtual void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset);
};
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) {
if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug.
for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
if(!byteCount) {
PrintHex<OFFSET_TYPE > (byteTotal, 0x80);
E_Notify(PSTR(": "), 0x80);
}
PrintHex<uint8_t > (pbuf[j], 0x80);
E_Notify(PSTR(" "), 0x80);
if(byteCount == 15) {
E_Notify(PSTR("\r\n"), 0x80);
byteCount = 0xFF;
}
}
}
}
#endif // __HEXDUMP_H__

@ -0,0 +1,111 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
/* USB functions */
#ifndef _UHS_host_h_
#define _UHS_host_h_
// WARNING: Do not change the order of includes, or stuff will break!
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#if DISABLED(USE_UHS3_USB)
#include <ISR_safe_memory.h>
#include <Wire.h>
#include <SPI.h>
#include <UHS_ByteBuffer.h>
#endif
#include "UHS_macros.h"
// None of these should ever be directly included by a driver, or a user's sketch.
#include "../dyn_SWI/dyn_SWI.h"
#include "UHS_USB_IDs.h"
#include "UHS_settings.h"
#include "UHS_usb_ch9.h"
#include "UHS_UsbCore.h"
#include "UHS_address.h"
#include "UHS_usbhost.h"
#include "UHS_printhex.h"
#include "UHS_message.h"
// Load system components as required
#if defined(LOAD_USB_HOST_SYSTEM) && !defined(USB_HOST_SYSTEM_LOADED)
#include "UHS_util_INLINE.h"
#include "UHS_host_INLINE.h"
#include "UHS_printf_HELPER.h"
#if defined(LOAD_USB_HOST_SHIELD)
#include "USB_HOST_SHIELD/USB_HOST_SHIELD.h"
#endif
#if defined(LOAD_UHS_KINETIS_FS_HOST) && !defined(UHS_KINETIS_FS_HOST_LOADED)
#include "UHS_KINETIS_FS_HOST/UHS_KINETIS_FS_HOST.h"
#endif
#if defined(LOAD_UHS_KINETIS_EHCI) && !defined(UHS_KINETIS_EHCI_LOADED)
#include "UHS_KINETIS_EHCI/UHS_KINETIS_EHCI.h"
#endif
// Load USB drivers and multiplexers
#if defined(LOAD_UHS_HUB)
#include "UHS_HUB/UHS_HUB.h"
#endif // HUB loaded
#if defined(LOAD_UHS_BULK_STORAGE)
#include "UHS_BULK_STORAGE/UHS_BULK_STORAGE.h"
#endif
#if defined(LOAD_GENERIC_STORAGE)
#include "../UHS_FS/UHS_FS.h"
#endif
// Add BT and optionally HID if directed to do so
#if defined(LOAD_UHS_BT)
#include "UHS_BT/UHS_BT.h"
#endif // BT and optionally HID loaded
// Add HID
#if defined(LOAD_UHS_HID)
#include "UHS_HID/UHS_HID.h"
#endif // HID loaded
// Add CDC multiplexers (currently only ACM)
#if defined(LOAD_UHS_CDC_ACM) || defined(LOAD_UHS_CDC_ACM_FTDI) || defined(LOAD_UHS_CDC_ACM_PROLIFIC) || defined(LOAD_UHS_CDC_ACM_XR21B1411)
#include "UHS_CDC/UHS_CDC.h"
#endif // CDC loaded
#if defined(LOAD_UHS_ADK)
#include "UHS_ADK/UHS_ADK.h"
#endif
#if defined(LOAD_UHS_MIDI)
#include "UHS_MIDI/UHS_MIDI.h"
#endif
#endif // System code loaded
#endif // _UHS_host_h_

@ -0,0 +1,393 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(MACROS_H)
#define MACROS_H
#include "macro_logic.h"
/*
* Universal Arduino(tm) "IDE" fixups.
*/
// Just in case...
#ifndef SERIAL_PORT_MONITOR
#define SERIAL_PORT_MONITOR Serial
#endif
#ifndef INT16_MIN
#define INT16_MIN -32768
#endif
// require 10607+
#if defined(ARDUINO) && ARDUINO >=10607
// nop :-)
#else
#error "Arduino version too old, and must be at least 1.6.7"
#endif
// Nuke screwed up macro junk from the IDE.
#ifdef __cplusplus
#if defined(true)
#undef true
#endif
#if defined(false)
#undef false
#endif
#endif
#if !defined(UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE)
#if !defined(UHS_BIG_FLASH)
#if defined(FLASHEND) && defined(FLASHSTART)
#if (FLASHEND - FLASHSTART) > 0x0FFFFU
#define UHS_BIG_FLASH 1
#else
#define UHS_BIG_FLASH 0
#endif
#elif defined(__PIC32_FLASH_SIZE)
#if __PIC32_FLASH_SIZE > 511
#define UHS_BIG_FLASH 1
#else
#define UHS_BIG_FLASH 0
#endif
#elif defined(FLASHEND) && !defined(FLASHSTART)
// Assumes flash starts at 0x00000, is this a safe assumption?
// 192K + should be OK
#if FLASHEND > 0x02FFFFU
#define UHS_BIG_FLASH 1
#else
#define UHS_BIG_FLASH 0
#endif
#elif defined(IFLASH_SIZE)
#if IFLASH_SIZE > 0x0FFFFU
#define UHS_BIG_FLASH 1
#else
#define UHS_BIG_FLASH 0
#endif
#elif defined(ESP8266)
#define UHS_BIG_FLASH 1
#define SYSTEM_OR_SPECIAL_YIELD(...) yield()
#elif defined(__arm__) && defined(CORE_TEENSY)
#define UHS_BIG_FLASH 1
#elif defined(ARDUINO_spresense_ast)
#define UHS_BIG_FLASH 1
#else
// safe default
#warning Small flash?
#define UHS_BIG_FLASH 0
#endif
#endif
#if UHS_BIG_FLASH
#define UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE 1
#else
#define UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE 0
#endif
#endif
#if defined(__arm__) && defined(CORE_TEENSY)
#define UHS_PIN_WRITE(p, v) digitalWriteFast(p, v)
#define UHS_PIN_READ(p) digitalReadFast(p)
#endif
// TODO: Fast inline code for AVR and SAM based microcontrollers
// This can be done pretty easily.
// For now, this will just work out-of-the-box.
#if !defined(UHS_PIN_WRITE)
#define UHS_PIN_WRITE(p, v) digitalWrite(p, v)
#endif
#if !defined(UHS_PIN_READ)
#define UHS_PIN_READ(p) digitalRead(p)
#endif
#if defined( __PIC32MX__ ) && !defined(interrupts) // compiling with Microchip XC32 compiler
#define interrupts() __builtin_enable_interrupts()
#edfine noInterrupts() __builtin_disable_interrupts()
#endif
#if !defined(ARDUINO_SAMD_ZERO)
#if defined(ARDUINO_AVR_ADK)
#define UHS_GET_DPI(x) (x == 54 ? 6 : digitalPinToInterrupt(x))
#else
#define UHS_GET_DPI(x) digitalPinToInterrupt(x)
#endif
#else
#define UHS_GET_DPI(x) (x)
#endif
#ifndef __AVR__
#ifndef __PGMSPACE_H_
// This define should prevent reading the system pgmspace.h if included elsewhere
// This is not normally needed.
#define __PGMSPACE_H_ 1
#endif
#ifndef PROGMEM
#define PROGMEM
#endif
#ifndef PGM_P
#define PGM_P const char *
#endif
#ifndef PSTR
#define PSTR(str) (str)
#endif
#ifndef F
#define F(str) (str)
#endif
#ifndef _SFR_BYTE
#define _SFR_BYTE(n) (n)
#endif
#ifndef memchr_P
#define memchr_P(str, c, len) memchr((str), (c), (len))
#endif
#ifndef memcmp_P
#define memcmp_P(a, b, n) memcmp((a), (b), (n))
#endif
#ifndef memcpy_P
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
#endif
#ifndef memmem_P
#define memmem_P(a, alen, b, blen) memmem((a), (alen), (b), (blen))
#endif
#ifndef memrchr_P
#define memrchr_P(str, val, len) memrchr((str), (val), (len))
#endif
#ifndef strcat_P
#define strcat_P(dest, src) strcat((dest), (src))
#endif
#ifndef strchr_P
#define strchr_P(str, c) strchr((str), (c))
#endif
#ifndef strchrnul_P
#define strchrnul_P(str, c) strchrnul((str), (c))
#endif
#ifndef strcmp_P
#define strcmp_P(a, b) strcmp((a), (b))
#endif
#ifndef strcpy_P
#define strcpy_P(dest, src) strcpy((dest), (src))
#endif
#ifndef strcasecmp_P
#define strcasecmp_P(a, b) strcasecmp((a), (b))
#endif
#ifndef strcasestr_P
#define strcasestr_P(a, b) strcasestr((a), (b))
#endif
#ifndef strlcat_P
#define strlcat_P(dest, src, len) strlcat((dest), (src), (len))
#endif
#ifndef strlcpy_P
#define strlcpy_P(dest, src, len) strlcpy((dest), (src), (len))
#endif
#ifndef strlen_P
#define strlen_P(s) strlen((const char *)(s))
#endif
#ifndef strnlen_P
#define strnlen_P(str, len) strnlen((str), (len))
#endif
#ifndef strncmp_P
#define strncmp_P(a, b, n) strncmp((a), (b), (n))
#endif
#ifndef strncasecmp_P
#define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n))
#endif
#ifndef strncat_P
#define strncat_P(a, b, n) strncat((a), (b), (n))
#endif
#ifndef strncpy_P
#define strncpy_P(a, b, n) strncmp((a), (b), (n))
#endif
#ifndef strpbrk_P
#define strpbrk_P(str, chrs) strpbrk((str), (chrs))
#endif
#ifndef strrchr_P
#define strrchr_P(str, c) strrchr((str), (c))
#endif
#ifndef strsep_P
#define strsep_P(strp, delim) strsep((strp), (delim))
#endif
#ifndef strspn_P
#define strspn_P(str, chrs) strspn((str), (chrs))
#endif
#ifndef strstr_P
#define strstr_P(a, b) strstr((a), (b))
#endif
#ifndef sprintf_P
#define sprintf_P(s, ...) sprintf((s), __VA_ARGS__)
#endif
#ifndef vfprintf_P
#define vfprintf_P(s, ...) vfprintf((s), __VA_ARGS__)
#endif
#ifndef printf_P
#define printf_P(...) printf(__VA_ARGS__)
#endif
#ifndef snprintf_P
#define snprintf_P(s, n, ...) ((s), (n), __VA_ARGS__)
#endif
#ifndef vsprintf_P
#define vsprintf_P(s, ...) ((s),__VA_ARGS__)
#endif
#ifndef vsnprintf_P
#define vsnprintf_P(s, n, ...) ((s), (n),__VA_ARGS__)
#endif
#ifndef fprintf_P
#define fprintf_P(s, ...) ((s), __VA_ARGS__)
#endif
#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#endif
#ifndef pgm_read_word
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#endif
#ifndef pgm_read_dword
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#endif
#ifndef pgm_read_float
#define pgm_read_float(addr) (*(const float *)(addr))
#endif
#ifndef pgm_read_byte_near
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#endif
#ifndef pgm_read_word_near
#define pgm_read_word_near(addr) pgm_read_word(addr)
#endif
#ifndef pgm_read_dword_near
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#endif
#ifndef pgm_read_float_near
#define pgm_read_float_near(addr) pgm_read_float(addr)
#endif
#ifndef pgm_read_byte_far
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#endif
#ifndef pgm_read_word_far
#define pgm_read_word_far(addr) pgm_read_word(addr)
#endif
#ifndef pgm_read_dword_far
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#endif
#ifndef pgm_read_float_far
#define pgm_read_float_far(addr) pgm_read_float(addr)
#endif
#ifndef pgm_read_pointer
#define pgm_read_pointer
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
// HANDY MACROS
////////////////////////////////////////////////////////////////////////////////
// Atmoically set/clear single bits using bitbands.
// Believe it or not, this boils down to a constant,
// and is less code than using |= &= operators.
// Bonus, it makes code easier to read too.
// Bitbanding is a wonderful thing.
#define BITNR(i) (i&0x1?0:i&0x2?1:i&0x4?2:i&0x8?3:i&0x10?4:i&0x20?5:i&0x40?6:i&0x80?7:i&0x100?8:i&0x200?9:i&0x400?10:i&0x800?11:i&0x1000?12:i&0x2000?13:i&0x4000?14:i&0x8000?15:i&0x10000?16:i&0x20000?17:i&0x40000?18:i&0x80000?19:i&0x100000?20:i&0x200000?21:i&0x400000?22:i&0x800000?23:i&0x1000000?24:i&0x2000000?25:i&0x4000000?26:i&0x8000000?27:i&0x10000000?28:i&0x20000000?29:i&0x40000000?30:i&0x80000000?31:32)
#define UHS_KIO_BITBAND_ADDR(r, i) (((uint32_t)&(r) - 0x40000000) * 32 + (i) * 4 + 0x42000000)
#define UHS_KIO_SETBIT_ATOMIC(r, m) (*(uint32_t *)UHS_KIO_BITBAND_ADDR((r), BITNR((m)))) = 1
#define UHS_KIO_CLRBIT_ATOMIC(r, m) (*(uint32_t *)UHS_KIO_BITBAND_ADDR((r), BITNR((m)))) = 0
#define VALUE_BETWEEN(v,l,h) (((v)>(l)) && ((v)<(h)))
#define VALUE_WITHIN(v,l,h) (((v)>=(l)) && ((v)<=(h)))
#define output_pgm_message(wa,fp,mp,el) wa = &mp, fp((char *)pgm_read_pointer(wa), el)
#define output_if_between(v,l,h,wa,fp,mp,el) if(VALUE_BETWEEN(v,l,h)) output_pgm_message(wa,fp,mp[v-(l+1)],el);
#define UHS_SWAP_VALUES(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
#ifndef __BYTE_GRABBING_DEFINED__
#define __BYTE_GRABBING_DEFINED__ 1
#ifdef BROKEN_OPTIMIZER_LITTLE_ENDIAN
// Note: Use this if your compiler generates horrible assembler!
#define UHS_UINT8_BYTE0(__usi__) (((uint8_t *)&(__usi__))[0])
#define UHS_UINT8_BYTE1(__usi__) (((uint8_t *)&(__usi__))[1])
#define UHS_UINT8_BYTE2(__usi__) (((uint8_t *)&(__usi__))[2])
#define UHS_UINT8_BYTE3(__usi__) (((uint8_t *)&(__usi__))[3])
#define UHS_UINT8_BYTE4(__usi__) (((uint8_t *)&(__usi__))[4])
#define UHS_UINT8_BYTE5(__usi__) (((uint8_t *)&(__usi__))[5])
#define UHS_UINT8_BYTE6(__usi__) (((uint8_t *)&(__usi__))[6])
#define UHS_UINT8_BYTE7(__usi__) (((uint8_t *)&(__usi__))[7])
#else
// Note: The cast alone to uint8_t is actually enough.
// GCC throws out the "& 0xff", and the size is no different.
// Some compilers need it.
#define UHS_UINT8_BYTE0(__usi__) ((uint8_t)((__usi__) & 0xff ))
#define UHS_UINT8_BYTE1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xff))
#define UHS_UINT8_BYTE2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xff))
#define UHS_UINT8_BYTE3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xff))
#define UHS_UINT8_BYTE4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xff))
#define UHS_UINT8_BYTE5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xff))
#define UHS_UINT8_BYTE6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xff))
#define UHS_UINT8_BYTE7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xff))
#endif
#define UHS_UINT16_SET_BYTE1(__usi__) ((uint16_t)(__usi__) << 8)
#define UHS_UINT32_SET_BYTE1(__usi__) ((uint32_t)(__usi__) << 8)
#define UHS_UINT64_SET_BYTE1(__usi__) ((uint64_t)(__usi__) << 8)
#define UHS_UINT32_SET_BYTE2(__usi__) ((uint32_t)(__usi__) << 16)
#define UHS_UINT64_SET_BYTE2(__usi__) ((uint64_t)(__usi__) << 16)
#define UHS_UINT32_SET_BYTE3(__usi__) ((uint32_t)(__usi__) << 24)
#define UHS_UINT64_SET_BYTE3(__usi__) ((uint64_t)(__usi__) << 24)
#define UHS_UINT64_SET_BYTE4(__usi__) ((uint64_t)(__usi__) << 32)
#define UHS_UINT64_SET_BYTE5(__usi__) ((uint64_t)(__usi__) << 40)
#define UHS_UINT64_SET_BYTE6(__usi__) ((uint64_t)(__usi__) << 48)
#define UHS_UINT64_SET_BYTE7(__usi__) ((uint64_t)(__usi__) << 56)
// These are the smallest and fastest ways I have found so far in pure C/C++.
#define UHS_BYTES_TO_UINT16(__usc1__,__usc0__) ((uint16_t)((uint16_t)(__usc0__) | (uint16_t)UHS_UINT16_SET_BYTE1(__usc1__)))
#define UHS_BYTES_TO_UINT32(__usc3__,__usc2__,__usc1__,__usc0__) ((uint32_t)((uint32_t)(__usc0__) | UHS_UINT32_SET_BYTE1(__usc1__) | UHS_UINT32_SET_BYTE2(__usc2__) | UHS_UINT32_SET_BYTE3(__usc3__)))
#define UHS_BYTES_TO_UINT64(__usc7__,__usc6__,__usc5__,__usc4__,__usc3__,__usc2__,__usc1__,__usc0__) ((uint64_t)((uint64_t)__usc0__ | UHS_UINT64_SET_BYTE1(__usc1__) | UHS_UINT64_SET_BYTE2(__usc2__) | UHS_UINT64_SET_BYTE3(__usc3__) | UHS_UINT64_SET_BYTE4(__usc4__) | UHS_UINT64_SET_BYTE5(__usc5__) | UHS_UINT64_SET_BYTE6(__usc6__) | UHS_UINT64_SET_BYTE7(__usc7__)))
#endif
/*
* Debug macros.
* Useful when porting from UHS2.
* Do not use these for any new code.
* Change to better debugging after port is completed.
* Strings are stored in progmem (flash) instead of RAM.
*/
#define USBTRACE1(s,l) (Notify(PSTR(s), l))
#define USBTRACE(s) (USBTRACE1((s), 0x80)); USB_HOST_SERIAL.flush()
#define USBTRACE3(s,r,l) (Notify(PSTR(s), l), D_PrintHex((r), l), Notify(PSTR("\r\n"), l))
#define USBTRACE3X(s,r,l) (Notify(PSTR(s), l), D_PrintHex((r), l))
#define USBTRACE2(s,r) (USBTRACE3((s),(r),0x80)); USB_HOST_SERIAL.flush()
#define USBTRACE2X(s,r) (USBTRACE3X((s),(r),0x80)); USB_HOST_SERIAL.flush()
#define VOID0 ((void)0)
#if !defined(NOTUSED)
#define NOTUSED(...) __VA_ARGS__ __attribute__((unused))
#endif
#endif /* MACROS_H */

@ -0,0 +1,91 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(_UHS_host_h_) || defined(__MESSAGE_H__)
#error "Never include UHS_message.h directly; include UHS_Usb.h instead"
#else
#define __MESSAGE_H__
extern int UsbDEBUGlvl;
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);
#ifdef DEBUG_USB_HOST
#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 NotifyFailSetConfDescr(uint8_t reason);
void NotifyFailGetDevDescr(void);
void NotifyFailSetDevTblEntry(void);
void NotifyFailGetConfDescr(void);
void NotifyFailSetConfDescr(void);
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID);
void NotifyFail(uint8_t rcode);
#else
#define Notify(...) VOID0
#define NotifyStr(...) VOID0
#define Notifyc(...) VOID0
#define NotifyFailGetDevDescr(...) VOID0
#define NotifyFailSetDevTblEntry(...) VOID0
#define NotifyFailGetConfDescr(...) VOID0
#define NotifyFailGetDevDescr(...) VOID0
#define NotifyFailSetDevTblEntry(...) VOID0
#define NotifyFailGetConfDescr(...) VOID0
#define NotifyFailSetConfDescr(...) VOID0
#define NotifyFailUnknownDevice(...) VOID0
#define NotifyFail(...) VOID0
#endif
#ifdef DEBUG_USB_HOST
template <class ERROR_TYPE> void ErrorMessage(uint8_t level, char const * msg, ERROR_TYPE rcode = 0) {
Notify(msg, level);
Notify(PSTR(": "), level);
D_PrintHex<ERROR_TYPE > (rcode, level);
Notify(PSTR("\r\n"), level);
#else
template <class ERROR_TYPE> void ErrorMessage(NOTUSED(uint8_t level), NOTUSED(char const * msg), ERROR_TYPE rcode = 0) {
(void)rcode;
#endif
}
#ifdef DEBUG_USB_HOST
template <class ERROR_TYPE> void ErrorMessage(char const * msg, ERROR_TYPE rcode = 0) {
Notify(msg, 0x80);
Notify(PSTR(": "), 0x80);
D_PrintHex<ERROR_TYPE > (rcode, 0x80);
Notify(PSTR("\r\n"), 0x80);
#else
template <class ERROR_TYPE> void ErrorMessage(NOTUSED(char const * msg), ERROR_TYPE rcode = 0) {
(void)rcode;
#endif
}
#endif // __MESSAGE_H__

@ -0,0 +1,201 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#ifndef UHS_PRINTF_HELPER_H
#define UHS_PRINTF_HELPER_H
#if defined(LOAD_UHS_PRINTF_HELPER)
#include <Arduino.h>
#ifdef true
#undef true
#endif
#ifdef false
#undef false
#endif
#if !defined(STDIO_IS_OK_TO_USE_AS_IS)
#if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAM_DUE) || defined(ARDUINO_spresense_ast)
// STDIO patching not required.
#define STDIO_IS_OK_TO_USE_AS_IS
#endif
#endif
#if !defined(STDIO_IS_OK_TO_USE_AS_IS)
// We need to patch STDIO so it can be used.
#ifndef SERIAL_PORT_MONITOR
// Some don't define this.
#define SERIAL_PORT_MONITOR Serial
#endif
#ifndef SERIAL_PORT_HARDWARE
// Some don't define this.
#define SERIAL_PORT_HARDWARE SERIAL_PORT_MONITOR
#endif
#ifndef USB_HOST_SERIAL
#if defined(SERIAL_PORT_USBVIRTUAL) && defined(LOAD_UHS_KINETIS_FS_HOST)
#define USB_HOST_SERIAL SERIAL_PORT_HARDWARE
#else
#define USB_HOST_SERIAL SERIAL_PORT_MONITOR
#endif
#endif
#if !defined(NOTUSED)
#define NOTUSED(...) __VA_ARGS__ __attribute__((unused))
#endif
#ifndef __AVR__
#ifndef printf_P
#define printf_P(...) printf(__VA_ARGS__)
#endif
#endif
#if defined(ARDUINO_ARCH_PIC32)
/*
* For printf() output with pic32 Arduino
*/
extern "C" {
void _mon_putc(char s) {
USB_HOST_SERIAL.write(s);
}
int _mon_getc() {
while(!USB_HOST_SERIAL.available());
return USB_HOST_SERIAL.read();
}
}
#elif defined(__AVR__)
extern "C" {
static FILE tty_stdio;
static FILE tty_stderr;
static int NOTUSED(tty_stderr_putc(char c, NOTUSED(FILE *t)));
static int NOTUSED(tty_stderr_flush(NOTUSED(FILE *t)));
static int NOTUSED(tty_std_putc(char c, NOTUSED(FILE *t)));
static int NOTUSED(tty_std_getc(NOTUSED(FILE *t)));
static int NOTUSED(tty_std_flush(NOTUSED(FILE *t)));
static int tty_stderr_putc(char c, NOTUSED(FILE *t)) {
USB_HOST_SERIAL.write(c);
return 0;
}
static int tty_stderr_flush(NOTUSED(FILE *t)) {
USB_HOST_SERIAL.flush();
return 0;
}
static int tty_std_putc(char c, NOTUSED(FILE *t)) {
USB_HOST_SERIAL.write(c);
return 0;
}
static int tty_std_getc(NOTUSED(FILE *t)) {
while(!USB_HOST_SERIAL.available());
return USB_HOST_SERIAL.read();
}
static int tty_std_flush(NOTUSED(FILE *t)) {
USB_HOST_SERIAL.flush();
return 0;
}
}
#elif defined(CORE_TEENSY)
extern "C" {
int _write(int fd, const char *ptr, int len) {
int j;
for(j = 0; j < len; j++) {
if(fd == 1)
USB_HOST_SERIAL.write(*ptr++);
else if(fd == 2)
USB_HOST_SERIAL.write(*ptr++);
}
return len;
}
int _read(int fd, char *ptr, int len) {
if(len > 0 && fd == 0) {
while(!USB_HOST_SERIAL.available());
*ptr = USB_HOST_SERIAL.read();
return 1;
}
return 0;
}
#include <sys/stat.h>
int _fstat(int fd, struct stat *st) {
memset(st, 0, sizeof (*st));
st->st_mode = S_IFCHR;
st->st_blksize = 1024;
return 0;
}
int _isatty(int fd) {
return (fd < 3) ? 1 : 0;
}
}
#else
#error no STDIO
#endif // defined(ARDUINO_ARCH_PIC32)
#if defined(__AVR__)
// The only wierdo in the bunch...
void UHS_AVR_printf_HELPER_init(void) {
// Set up stdio/stderr
tty_stdio.put = tty_std_putc;
tty_stdio.get = tty_std_getc;
tty_stdio.flags = _FDEV_SETUP_RW;
tty_stdio.udata = 0;
tty_stderr.put = tty_stderr_putc;
tty_stderr.get = NULL;
tty_stderr.flags = _FDEV_SETUP_WRITE;
tty_stderr.udata = 0;
stdout = &tty_stdio;
stdin = &tty_stdio;
stderr = &tty_stderr;
}
#define UHS_printf_HELPER_init() UHS_AVR_printf_HELPER_init()
#endif
#endif /* STDIO_IS_OK_TO_USE_AS_IS */
#endif /* load.... */
#if !defined(UHS_printf_HELPER_init)
#define UHS_printf_HELPER_init() (void(0))
#endif
#endif /* UHS_PRINTF_HELPER_H */

@ -0,0 +1,96 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(_UHS_host_h_) || defined(__PRINTHEX_H__)
#error "Never include UHS_printhex.h directly; include UHS_Usb.h instead"
#else
#define __PRINTHEX_H__
void E_Notifyc(char c, int lvl);
template <class T>
void PrintHex(T val, int lvl) {
int num_nibbles = sizeof (T) * 2;
do {
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
if(v > 57) v += 7;
E_Notifyc(v, lvl);
} while(--num_nibbles);
}
template <class T>
void PrintBin(T val, int lvl) {
for(T mask = (((T)1) << ((sizeof (T) << 3) - 1)); mask; mask >>= 1)
if(val & mask)
E_Notifyc('1', lvl);
else
E_Notifyc('0', lvl);
}
template <class T>
void SerialPrintHex(T val) {
int num_nibbles = sizeof (T) * 2;
do {
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
if(v > 57) v += 7;
USB_HOST_SERIAL.print(v);
} while(--num_nibbles);
}
template <class T>
void PrintHex2(Print *prn, T val) {
T mask = (((T)1) << (((sizeof (T) << 1) - 1) << 2));
while(mask > 1) {
if(val < mask)
prn->print("0");
mask >>= 4;
}
prn->print((T)val, HEX);
}
#ifdef DEBUG_USB_HOST
template <class T> void D_PrintHex(T val, int lvl) {
PrintHex<T > (val, lvl);
#else
template <class T> void D_PrintHex(NOTUSED(T val), NOTUSED(int lvl)) {
#endif
}
#ifdef DEBUG_USB_HOST
template <class T> void D_PrintBin(T val, int lvl) {
PrintBin<T > (val, lvl);
#else
template <class T> void D_PrintBin(NOTUSED(T val), NOTUSED(int lvl)) {
#endif
}
#endif // __PRINTHEX_H__

@ -0,0 +1,141 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#ifndef UHS_SETTINGS_H
#define UHS_SETTINGS_H
// TO-DO: Move specific settings to modules which use them.
////////////////////////////////////////////////////////////////////////////////
// Define any of these options at the top of your sketch to override
// the defaults contained herewith. Do NOT do modifications here.
// Individual Components have their own settings.
//
// Macro | Settings and notes | Default
// -----------------------------+-----------------------+-----------------------
// | Any class that does |
// USB_HOST_SERIAL | text streaming | SERIAL_PORT_MONITOR
// | e.g. Serial2 |
// -----------------------------+-----------------------+-----------------------
// ENABLE_UHS_DEBUGGING | 0 = off, 1 = on | 0
// -----------------------------+-----------------------+-----------------------
// | 0 = off, 1 = on |
// | Caution! Can make |
// DEBUG_PRINTF_EXTRA_HUGE | program too large! | 0
// | Other modules depend |
// | on this setting. |
// -----------------------------+-----------------------+-----------------------
// USE_UHS_BLACK_WIDDOW | 0 = no, 1 = yes | 0
// -----------------------------+-----------------------+-----------------------
// ENABLE_WII_IR_CAMERA | 0 = no, 1 = yes | 0
// -----------------------------^-----------------------^-----------------------
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// DEBUGGING
////////////////////////////////////////////////////////////////////////////////
#ifndef USB_HOST_SERIAL
#if defined(SERIAL_PORT_USBVIRTUAL) && defined(LOAD_UHS_KINETIS_FS_HOST)
#define USB_HOST_SERIAL SERIAL_PORT_HARDWARE
#else
#define USB_HOST_SERIAL SERIAL_PORT_MONITOR
#endif
#endif
#ifndef ENABLE_UHS_DEBUGGING
#define ENABLE_UHS_DEBUGGING 0
#endif
#ifndef DEBUG_PRINTF_EXTRA_HUGE
#define DEBUG_PRINTF_EXTRA_HUGE 0
#endif
////////////////////////////////////////////////////////////////////////////////
// Manual board activation
////////////////////////////////////////////////////////////////////////////////
/* Set this to 1 if you are using a Black Widdow */
#ifndef USE_UHS_BLACK_WIDDOW
#define USE_UHS_BLACK_WIDDOW 0
#endif
////////////////////////////////////////////////////////////////////////////////
// Wii IR camera
////////////////////////////////////////////////////////////////////////////////
/* Set this to 1 to activate code for the Wii IR camera */
#ifndef ENABLE_WII_IR_CAMERA
#define ENABLE_WII_IR_CAMERA 0
#endif
////////////////////////////////////////////////////////////////////////////////
// Set to 1 to use the faster spi4teensy3 driver. (not used yet))
////////////////////////////////////////////////////////////////////////////////
#ifndef USE_SPI4TEENSY3
#define USE_SPI4TEENSY3 0
#endif
////////////////////////////////////////////////////////////////////////////////
// AUTOMATIC Settings
////////////////////////////////////////////////////////////////////////////////
// No user serviceable parts below this line.
// DO NOT change anything below here unless you are a developer!
#if defined(__GNUC__) && defined(__AVR__)
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#if GCC_VERSION < 40602 // Test for GCC < 4.6.2
#ifdef PROGMEM
#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4
#ifdef PSTR
#undef PSTR
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) // Copied from pgmspace.h in avr-libc source
#endif
#endif
#endif
#endif
#if !defined(DEBUG_USB_HOST) && ENABLE_UHS_DEBUGGING
#define DEBUG_USB_HOST
#endif
#if !defined(WIICAMERA) && ENABLE_WII_IR_CAMERA
#define WIICAMERA
#endif
#define UHS_SLEEP_MS(v) pUsb->sof_delay(v)
#ifndef UHS_NI
#define UHS_NI __attribute__((noinline))
#endif
#endif /* SETTINGS_H */

@ -0,0 +1,222 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(_UHS_host_h_) || defined(_UHS_ch9_h_)
#error "Never include UHS_usb_ch9.h directly; include UHS_Usb.h instead"
#else
/* USB chapter 9 structures */
#define _UHS_ch9_h_
/* Misc.USB constants */
#define DEV_DESCR_LEN 18 //device descriptor length
#define CONF_DESCR_LEN 9 //configuration descriptor length
#define INTR_DESCR_LEN 9 //interface descriptor length
#define EP_DESCR_LEN 7 //endpoint descriptor length
/* Standard Device Requests */
#define USB_REQUEST_GET_STATUS 0 // Standard Device Request - GET STATUS
#define USB_REQUEST_CLEAR_FEATURE 1 // Standard Device Request - CLEAR FEATURE
#define USB_REQUEST_SET_FEATURE 3 // Standard Device Request - SET FEATURE
#define USB_REQUEST_SET_ADDRESS 5 // Standard Device Request - SET ADDRESS
#define USB_REQUEST_GET_DESCRIPTOR 6 // Standard Device Request - GET DESCRIPTOR
#define USB_REQUEST_SET_DESCRIPTOR 7 // Standard Device Request - SET DESCRIPTOR
#define USB_REQUEST_GET_CONFIGURATION 8 // Standard Device Request - GET CONFIGURATION
#define USB_REQUEST_SET_CONFIGURATION 9 // Standard Device Request - SET CONFIGURATION
#define USB_REQUEST_GET_INTERFACE 10 // Standard Device Request - GET INTERFACE
#define USB_REQUEST_SET_INTERFACE 11 // Standard Device Request - SET INTERFACE
#define USB_REQUEST_SYNCH_FRAME 12 // Standard Device Request - SYNCH FRAME
/* Wireless USB Device Requests */
#define USB_REQ_SET_ENCRYPTION 0x0D
#define USB_REQ_GET_ENCRYPTION 0x0E
#define USB_REQ_RPIPE_ABORT 0x0E
#define USB_REQ_SET_HANDSHAKE 0x0F
#define USB_REQ_RPIPE_RESET 0x0F
#define USB_REQ_GET_HANDSHAKE 0x10
#define USB_REQ_SET_CONNECTION 0x11
#define USB_REQ_SET_SECURITY_DATA 0x12
#define USB_REQ_GET_SECURITY_DATA 0x13
#define USB_REQ_SET_WUSB_DATA 0x14
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
#define USB_REQ_LOOPBACK_DATA_READ 0x16
#define USB_REQ_SET_INTERFACE_DS 0x17
/* USB feature flags */
#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */
#define USB_DEVICE_BATTERY 2 /* (wireless) */
#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */
#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/
#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */
#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */
#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
#define USB_FEATURE_ENDPOINT_HALT 0 // CLEAR/SET FEATURE - Endpoint Halt
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // CLEAR/SET FEATURE - Device remote wake-up
#define USB_FEATURE_TEST_MODE 2 // CLEAR/SET FEATURE - Test mode
/* OTG SET FEATURE Constants */
#define OTG_FEATURE_B_HNP_ENABLE 3 // SET FEATURE OTG - Enable B device to perform HNP
#define OTG_FEATURE_A_HNP_SUPPORT 4 // SET FEATURE OTG - A device supports HNP
#define OTG_FEATURE_A_ALT_HNP_SUPPORT 5 // SET FEATURE OTG - Another port on the A device supports HNP
/* Setup Data Constants */
#define USB_SETUP_HOST_TO_DEVICE 0x00 // Device Request bmRequestType transfer direction - host to device transfer
#define USB_SETUP_DEVICE_TO_HOST 0x80 // Device Request bmRequestType transfer direction - device to host transfer
#define USB_SETUP_TYPE_STANDARD 0x00 // Device Request bmRequestType type - standard
#define USB_SETUP_TYPE_CLASS 0x20 // Device Request bmRequestType type - class
#define USB_SETUP_TYPE_VENDOR 0x40 // Device Request bmRequestType type - vendor
#define USB_SETUP_RECIPIENT_DEVICE 0x00 // Device Request bmRequestType recipient - device
#define USB_SETUP_RECIPIENT_INTERFACE 0x01 // Device Request bmRequestType recipient - interface
#define USB_SETUP_RECIPIENT_ENDPOINT 0x02 // Device Request bmRequestType recipient - endpoint
#define USB_SETUP_RECIPIENT_OTHER 0x03 // Device Request bmRequestType recipient - other
#define USB_SETUP_RECIPIENT_PORT 0x04 // Wireless USB 1.0
#define USB_SETUP_RECIPIENT_RPIPE 0x05 // Wireless USB 1.0
/* USB descriptors */
#define USB_DESCRIPTOR_DEVICE 0x01 // bDescriptorType for a Device Descriptor.
#define USB_DESCRIPTOR_CONFIGURATION 0x02 // bDescriptorType for a Configuration Descriptor.
#define USB_DESCRIPTOR_STRING 0x03 // bDescriptorType for a String Descriptor.
#define USB_DESCRIPTOR_INTERFACE 0x04 // bDescriptorType for an Interface Descriptor.
#define USB_DESCRIPTOR_ENDPOINT 0x05 // bDescriptorType for an Endpoint Descriptor.
#define USB_DESCRIPTOR_DEVICE_QUALIFIER 0x06 // bDescriptorType for a Device Qualifier.
#define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration.
#define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power.
#define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor.
#define USB_DESCRIPTOR_DEBUG 0x0a
#define USB_DESCRIPTOR_INTERFACE_ASSOCIATION 0x0b
#define USB_DESCRIPTOR_SECURITY 0x0c
#define USB_DESCRIPTOR_KEY 0x0d
#define USB_DESCRIPTOR_ENCRYPTION_TYPE 0x0e
#define USB_DESCRIPTOR_BOS 0x0f
#define USB_DESCRIPTOR_DEVICE_CAPABILITY 0x10
#define USB_DESCRIPTOR_WIRELESS_ENDPOINT_COMP 0x11
#define USB_DESCRIPTOR_WIRE_ADAPTER 0x21
#define USB_DESCRIPTOR_RPIPE 0x22
#define USB_DESCRIPTOR_CS_RADIO_CONTROL 0x23
#define USB_DESCRIPTOR_SS_ENDPOINT_COMP 0x30
#define USB_HID_DESCRIPTOR 0x21
// Conventional codes for class-specific descriptors. "Common Class" Spec (3.11)
#define USB_DESCRIPTOR_CS_DEVICE 0x21
#define USB_DESCRIPTOR_CS_CONFIG 0x22
#define USB_DESCRIPTOR_CS_STRING 0x23
#define USB_DESCRIPTOR_CS_INTERFACE 0x24
#define USB_DESCRIPTOR_CS_ENDPOINT 0x25
/* USB Endpoint Transfer Types */
#define USB_TRANSFER_TYPE_CONTROL 0x00 // Endpoint is a control endpoint.
#define USB_TRANSFER_TYPE_ISOCHRONOUS 0x01 // Endpoint is an isochronous endpoint.
#define USB_TRANSFER_TYPE_BULK 0x02 // Endpoint is a bulk endpoint.
#define USB_TRANSFER_TYPE_INTERRUPT 0x03 // Endpoint is an interrupt endpoint.
#define bmUSB_TRANSFER_TYPE 0x03 // bit mask to separate transfer type from ISO attributes
#define USB_TRANSFER_DIRECTION_IN 0x80 // Indicate direction is IN
/* Standard Feature Selectors for CLEAR_FEATURE Requests */
#define USB_FEATURE_ENDPOINT_STALL 0 // Endpoint recipient
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // Device recipient
#define USB_FEATURE_TEST_MODE 2 // Device recipient
/* descriptor data structures */
/* Device descriptor structure */
typedef struct {
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
uint16_t bcdUSB; // USB Spec Release Number (BCD).
uint8_t bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bDeviceSubClass; // Subclass code (assigned by the USB-IF).
uint8_t bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bMaxPacketSize0; // Maximum packet size for endpoint 0.
uint16_t idVendor; // Vendor ID (assigned by the USB-IF).
uint16_t idProduct; // Product ID (assigned by the manufacturer).
uint16_t bcdDevice; // Device release number (BCD).
uint8_t iManufacturer; // Index of String Descriptor describing the manufacturer.
uint8_t iProduct; // Index of String Descriptor describing the product.
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
uint8_t bNumConfigurations; // Number of possible configurations.
} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
/* Configuration descriptor structure */
typedef struct {
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
uint16_t wTotalLength; // Total length of all descriptors for this configuration.
uint8_t bNumInterfaces; // Number of interfaces in this configuration.
uint8_t bConfigurationValue; // Value of this configuration (1 based).
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
uint8_t bmAttributes; // Configuration characteristics.
uint8_t bMaxPower; // Maximum power consumed by this configuration.
} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
/* Interface descriptor structure */
typedef struct {
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
uint8_t bInterfaceNumber; // Number of this interface (0 based).
uint8_t bAlternateSetting; // Value of this alternate interface setting.
uint8_t bNumEndpoints; // Number of endpoints in this interface.
uint8_t bInterfaceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t iInterface; // Index of String Descriptor describing the interface.
} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
/* Endpoint descriptor structure */
typedef struct {
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
uint8_t bmAttributes; // Endpoint transfer type.
uint16_t wMaxPacketSize; // Maximum packet size.
uint8_t bInterval; // Polling interval in frames.
} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
/* HID descriptor */
/*
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID; // HID class specification release
uint8_t bCountryCode;
uint8_t bNumDescriptors; // Number of additional class specific descriptors
uint8_t bDescrType; // Type of class descriptor
uint16_t wDescriptorLength; // Total size of the Report descriptor
} __attribute__((packed)) USB_HID_DESCRIPTOR;
*/
typedef struct {
uint8_t bDescrType; // Type of class descriptor
uint16_t wDescriptorLength; // Total size of the Report descriptor
} __attribute__((packed)) HID_CLASS_DESCRIPTOR_LEN_AND_TYPE;
#endif // _ch9_h_

@ -0,0 +1,452 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if !defined(_UHS_host_h_)
#error "Never include UHS_usbhost.h directly; include UHS_host.h instead"
#else
#if !defined(_USBHOST_H_)
#define _USBHOST_H_
// Very early prototypes
#if defined(UHS_LOAD_BT)
void UHS_BT_SetUSBInterface(UHS_USB_HOST_BASE *host, ENUMERATION_INFO *ei);
void UHS_BT_ScanUninitialized(UHS_USB_HOST_BASE *host);
void UHS_BT_Poll(UHS_USB_HOST_BASE *host);
#endif
#if defined(UHS_LOAD_HID)
void UHS_HID_SetUSBInterface(UHS_USB_HOST_BASE *host, ENUMERATION_INFO *ei);
void UHS_HID_ScanUninitialized(UHS_USB_HOST_BASE *host);
void UHS_HID_Poll(UHS_USB_HOST_BASE *host);
#endif
//#if defined(LOAD_UHS_CDC_ACM) || defined(LOAD_UHS_CDC_ACM_FTDI) || defined(LOAD_UHS_CDC_ACM_PROLIFIC) || defined(LOAD_UHS_CDC_ACM_XR21B1411)
//void UHS_CDC_ACM_SetUSBInterface(UHS_USB_HOST_BASE *host, ENUMERATION_INFO *ei);
//void UHS_CDC_ACM_ScanUninitialized(UHS_USB_HOST_BASE *host);
//void UHS_CDC_ACM_Poll(UHS_USB_HOST_BASE *host);
//#endif
class UHS_USBInterface; // forward class declaration
// enumerator to turn the VBUS on/off
typedef enum {
vbus_on = 0,
vbus_off = 1
} VBUS_t;
// All host SEI use this base class
class UHS_USB_HOST_BASE {
public:
AddressPool addrPool;
UHS_USBInterface* devConfig[UHS_HOST_MAX_INTERFACE_DRIVERS];
volatile uint8_t usb_error;
volatile uint8_t usb_task_state;
volatile uint8_t usb_task_polling_disabled;
volatile uint8_t usb_host_speed;
volatile uint8_t hub_present;
UHS_USB_HOST_BASE(void) {
for(uint16_t i = 0; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) {
devConfig[i] = NULL;
}
usb_task_polling_disabled = 0;
usb_task_state = UHS_USB_HOST_STATE_INITIALIZE; //set up state machine
usb_host_speed = 0;
usb_error = 0;
};
/////////////////////////////////////////////
//
// Virtual methods that interface to the SIE
// Overriding each is mandatory.
//
/////////////////////////////////////////////
/**
* Delay for x milliseconds
* Override if your controller provides an SOF IRQ, which may involve
* some sort of reentrant ISR or workaround with interrupts enabled.
*
* @param x how many milliseconds to delay
* @return true if delay completed without a state change, false if delay aborted
*/
virtual bool UHS_NI sof_delay(uint16_t x) {
if(!(usb_task_state & UHS_USB_HOST_STATE_MASK)) return false;
uint8_t current_state = usb_task_state;
while(current_state == usb_task_state && x--) {
delay(1);
}
return (current_state == usb_task_state);
};
virtual UHS_EpInfo * UHS_NI ctrlReqOpen(NOTUSED(uint8_t addr), NOTUSED(uint64_t Request), NOTUSED(uint8_t* dataptr)) {
return NULL;
};
virtual void UHS_NI vbusPower(NOTUSED(VBUS_t state)) {
};
virtual void UHS_NI Task(void) {
};
virtual uint8_t UHS_NI SetAddress(NOTUSED(uint8_t addr), NOTUSED(uint8_t ep), NOTUSED(UHS_EpInfo **ppep), NOTUSED(uint16_t &nak_limit)) {
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
virtual uint8_t UHS_NI OutTransfer(NOTUSED(UHS_EpInfo *pep), NOTUSED(uint16_t nak_limit), NOTUSED(uint16_t nbytes), NOTUSED(uint8_t *data)) {
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
virtual uint8_t UHS_NI InTransfer(NOTUSED(UHS_EpInfo *pep), NOTUSED(uint16_t nak_limit), NOTUSED(uint16_t *nbytesptr), NOTUSED(uint8_t *data)) {
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
virtual uint8_t UHS_NI ctrlReqClose(NOTUSED(UHS_EpInfo *pep), NOTUSED(uint8_t bmReqType), NOTUSED(uint16_t left), NOTUSED(uint16_t nbytes), NOTUSED(uint8_t *dataptr)) {
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
virtual uint8_t UHS_NI ctrlReqRead(NOTUSED(UHS_EpInfo *pep), NOTUSED(uint16_t *left), NOTUSED(uint16_t *read), NOTUSED(uint16_t nbytes), NOTUSED(uint8_t *dataptr)) {
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
virtual uint8_t UHS_NI dispatchPkt(NOTUSED(uint8_t token), NOTUSED(uint8_t ep), NOTUSED(uint16_t nak_limit)) {
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
virtual uint8_t UHS_NI init(void) {
return 0;
};
virtual void UHS_NI doHostReset(void) {
};
virtual int16_t UHS_NI Init(NOTUSED(int16_t mseconds)) {
return -1;
};
virtual int16_t UHS_NI Init(void) {
return Init(INT16_MIN);
};
virtual uint8_t hwlPowerUp(void) {
/* This is for machine specific support to enable/power up the USB HW to operate*/
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
virtual uint8_t hwPowerDown(void) {
/* This is for machine specific support to disable/powerdown the USB Hw */
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
virtual bool IsHub(uint8_t klass) {
return (klass == UHS_USB_CLASS_HUB);
};
virtual void UHS_NI suspend_host(void) {
// Used on MCU that lack control of IRQ priority (AVR).
// Suspends ISRs, for critical code. IRQ will be serviced after it is resumed.
// NOTE: you must track the state yourself!
};
virtual void UHS_NI resume_host(void) {
// Used on MCU that lack control of IRQ priority (AVR).
// Resumes ISRs.
// NOTE: you must track the state yourself!
};
/////////////////////////////////////////////
//
// Built-ins, No need to override
//
/////////////////////////////////////////////
// these two probably will go away, and won't be used, TBD
inline void Poll_Others(void) {
#if defined(UHS_LOAD_BT)
UHS_BT_Poll(this);
#endif
#if defined(UHS_LOAD_HID)
UHS_HID_Poll(this);
#endif
}
inline void DisablePoll(void) {
noInterrupts();
usb_task_polling_disabled++;
DDSB();
interrupts();
}
inline void EnablePoll(void) {
noInterrupts();
usb_task_polling_disabled--;
DDSB();
interrupts();
}
uint8_t UHS_NI seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_CONFIGURATION_DESCRIPTOR *ucd);
uint8_t UHS_NI setEpInfoEntry(uint8_t addr, uint8_t iface, uint8_t epcount, volatile UHS_EpInfo* eprecord_ptr);
uint8_t UHS_NI EPClearHalt(uint8_t addr, uint8_t ep);
uint8_t UHS_NI ctrlReq(uint8_t addr, uint64_t Request, uint16_t nbytes, uint8_t* dataptr);
uint8_t UHS_NI getDevDescr(uint8_t addr, uint16_t nbytes, uint8_t* dataptr);
uint8_t UHS_NI getConfDescr(uint8_t addr, uint16_t nbytes, uint8_t conf, uint8_t* dataptr);
uint8_t UHS_NI setAddr(uint8_t oldaddr, uint8_t newaddr);
uint8_t UHS_NI setConf(uint8_t addr, uint8_t conf_value);
uint8_t UHS_NI getStrDescr(uint8_t addr, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr);
void UHS_NI ReleaseDevice(uint8_t addr);
uint8_t UHS_NI Configuring(uint8_t parent, uint8_t port, uint8_t speed);
void UHS_NI DeviceDefaults(uint8_t maxep, UHS_USBInterface *device);
UHS_EpInfo* UHS_NI getEpInfoEntry(uint8_t addr, uint8_t ep);
inline uint8_t getUsbTaskState(void) {
return ( usb_task_state);
};
inline AddressPool* GetAddressPool(void) {
return &addrPool;
};
int UHS_NI RegisterDeviceClass(UHS_USBInterface *pdev) {
for(uint8_t i = 0; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) {
if(!devConfig[i]) {
devConfig[i] = pdev;
return i;
}
}
//return UHS_HOST_ERROR_CANT_REGISTER_DEVICE_CLASS;
return -1;
};
#if 0
inline void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
addrPool.ForEachUsbDevice(pfunc);
};
#endif
uint8_t TestInterface(ENUMERATION_INFO *ei);
uint8_t enumerateInterface(ENUMERATION_INFO *ei);
uint8_t getNextInterface(ENUMERATION_INFO *ei, UHS_EpInfo *pep, uint8_t data[], uint16_t *left, uint16_t *read, uint8_t *offset);
uint8_t initDescrStream(ENUMERATION_INFO *ei, USB_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset);
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data);
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data);
uint8_t doSoftReset(uint8_t parent, uint8_t port, uint8_t address);
uint8_t getone(UHS_EpInfo *pep, uint16_t *left, uint16_t *read, uint8_t *dataptr, uint8_t *offset);
uint8_t eat(UHS_EpInfo *pep, uint16_t *left, uint16_t *read, uint8_t *dataptr, uint8_t *offset, uint16_t *yum);
};
// All device interface drivers use this subclass
class UHS_USBInterface {
public:
UHS_USB_HOST_BASE *pUsb; // Parent USB host
volatile uint8_t bNumEP; // total number of EP in this interface
volatile UHS_EpInfo epInfo[16]; // This is a stub, override in the driver.
volatile uint8_t bAddress; // address of the device
volatile uint8_t bConfNum; // configuration number
volatile uint8_t bIface; // interface value
volatile bool bPollEnable; // poll enable flag, operating status
volatile uint32_t qNextPollTime; // next poll time
/**
* Resets interface driver to unused state. You should override this in
* your driver if it requires extra class variable cleanup.
*/
virtual void DriverDefaults(void) {
printf("Default driver defaults.\r\n");
pUsb->DeviceDefaults(bNumEP, this);
};
/**
* Checks if this interface is supported.
* Executed called when new devices are connected.
*
* @param ei
* @return true if the interface is supported
*/
virtual bool OKtoEnumerate(NOTUSED(ENUMERATION_INFO *ei)) {
return false;
};
/**
* Configures any needed endpoint information for an interface.
* You must provide this in your driver.
* Executed when new devices are connected and OKtoEnumerate()
* returned true.
*
* @param ei
* @return zero on success
*/
virtual uint8_t SetInterface(NOTUSED(ENUMERATION_INFO *ei)) {
return UHS_HOST_ERROR_NOT_IMPLEMENTED;
};
/**
* Interface specific additional setup and enumeration that
* can't occur when the descriptor stream is open.
* Also used for collection of unclaimed interfaces, to link to the master.
*
* @return zero on success
*/
virtual uint8_t Finalize(void) {
return 0;
};
/**
* Executed after interface is finalized but, before polling has started.
*
* @return 0 on success
*/
virtual uint8_t OnStart(void) {
return 0;
};
/**
* Start interface polling
* @return
*/
virtual uint8_t Start(void) {
uint8_t rcode = OnStart();
if(!rcode) bPollEnable = true;
return rcode;
};
/**
* Executed before anything else in Release().
*
*/
virtual void OnRelease(void) {
return;
};
/**
* Release resources when device is disconnected.
* Normally this does not need to be overridden.
*/
virtual void Release(void) {
OnRelease();
DriverDefaults();
return;
};
/**
* Executed After driver polls.
* Can be used when there is an important change detected during polling
* and you want to handle it elsewhere.
* Examples:
* Media status change for bulk, e.g. ready, not-ready, media changed, door opened.
* Button state/joystick position/etc changes on a HID device.
* Flow control status change on a communication device, e.g. CTS on serial
*/
virtual void OnPoll(void) {
return;
};
/**
* Poll interface driver. You should override this in your driver if you
* require polling faster or slower than every 100 milliseconds, or your
* driver requires special housekeeping.
*/
virtual void Poll() {
OnPoll();
qNextPollTime = millis() + 100;
};
virtual bool UHS_NI Polling(void) {
return bPollEnable;
}
/**
* This is only for a hub.
* @param port
*/
virtual void ResetHubPort(NOTUSED(uint8_t port)) {
return;
};
#if 0
/**
*
* @return true if this interface is Vendor Specific.
*/
virtual bool IsVSI() {
return false;
}
#endif
};
#if 0
/**
*
* Vendor Specific interface class.
* This is used by a partner interface.
* It can also be used to force-enumerate an interface that
* can use this interface directly.
* You can also add an instance of this class within the interface constructor
* if you expect the interface.
*
* If this is not needed, it may be removed. Nothing I have written needs this.
* Let me know if it is not required, then IsVSI method can also be shit-canned.
* -- AJK
*/
class UHS_VSI : public UHS_USBInterface {
public:
volatile UHS_EpInfo epInfo[1];
volatile ENUMERATION_INFO eInfo;
UHS_VSI(UHS_USB_HOST_BASE *p);
bool OKtoEnumerate(ENUMERATION_INFO *ei);
uint8_t SetInterface(ENUMERATION_INFO *ei);
virtual void DriverDefaults(void);
virtual void Release(void);
uint8_t GetAddress(void) {
return bAddress;
};
virtual bool IsVSI() {
return true;
}
};
#endif
#endif //_USBHOST_H_
#endif

@ -0,0 +1,129 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact information
-------------------
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
#if defined(LOAD_USB_HOST_SYSTEM) && !defined(USB_HOST_SYSTEM_UTIL_LOADED)
#define USB_HOST_SYSTEM_UTIL_LOADED
// 0x80 is the default (i.e. trace) to turn off set this global to something lower.
// this allows for 126 other debugging levels.
// TO-DO: Allow assignment to a different serial port by software
int UsbDEBUGlvl = 0x80;
void E_Notifyc(char c, int lvl) {
if(UsbDEBUGlvl < lvl) return;
#if defined(ARDUINO) && ARDUINO >=100
USB_HOST_SERIAL.print(c);
#else
USB_HOST_SERIAL.print(c, BYTE);
#endif
//USB_HOST_SERIAL.flush();
}
void E_Notify(char const * msg, int lvl) {
if(UsbDEBUGlvl < lvl) return;
if(!msg) return;
char c;
while((c = pgm_read_byte(msg++))) E_Notifyc(c, lvl);
}
void E_NotifyStr(char const * msg, int lvl) {
if(UsbDEBUGlvl < lvl) return;
if(!msg) return;
char c;
while((c = *msg++)) E_Notifyc(c, lvl);
}
void E_Notify(uint8_t b, int lvl) {
if(UsbDEBUGlvl < lvl) return;
#if defined(ARDUINO) && ARDUINO >=100
USB_HOST_SERIAL.print(b);
#else
USB_HOST_SERIAL.print(b, DEC);
#endif
}
void E_Notify(double d, int lvl) {
if(UsbDEBUGlvl < lvl) return;
USB_HOST_SERIAL.print(d);
}
#ifdef DEBUG_USB_HOST
void NotifyFailGetDevDescr(void) {
Notify(PSTR("\r\ngetDevDescr "), 0x80);
}
void NotifyFailSetDevTblEntry(void) {
Notify(PSTR("\r\nsetDevTblEn "), 0x80);
}
void NotifyFailGetConfDescr(void) {
Notify(PSTR("\r\ngetConf "), 0x80);
}
void NotifyFailSetConfDescr(void) {
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);
}
void NotifyFailSetConfDescr(uint8_t reason) {
NotifyFailSetConfDescr();
NotifyFail(reason);
}
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID) {
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
D_PrintHex<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
D_PrintHex<uint16_t > (PID, 0x80);
}
void NotifyFail(uint8_t rcode) {
D_PrintHex<uint8_t > (rcode, 0x80);
Notify(PSTR("\r\n"), 0x80);
}
#endif
#else
#error "Never include UHS_util_INLINE.h, include UHS_host.h instead"
#endif

@ -0,0 +1,226 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
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(USB_HOST_SHIELD_H) || defined(_max3421e_h_)
#error "Never include UHS_max3421e.h directly; include USB_HOST_SHIELD.h instead"
#else
#define _max3421e_h_
/* MAX3421E register/bit names and bitmasks */
#define SE0 0
#define SE1 1
#define FSHOST 2
#define LSHOST 3
/* MAX3421E command byte format: rrrrr0wa where 'r' is register number */
//
// MAX3421E Registers in HOST mode.
//
#define rRCVFIFO 0x08 // Receive FIFO Register
#define rSNDFIFO 0x10 // Send FIFO Register
#define rSUDFIFO 0x20 // Set Up Data FIFO Register
#define rRCVBC 0x30 // Receive FIFO Byte Count Register
#define rSNDBC 0x38 // Send FIFO Byte Count Register
// USB Interrupt Request Status (USBIRQ)
#define rUSBIRQ 0x68 // USB Interrupt Request Register
#define bmVBUSIRQ 0x40 // Vbus Present Interrupt Request
#define bmNOVBUSIRQ 0x20 // Vbus Absent Interrupt Request
#define bmOSCOKIRQ 0x01 // Oscillator OK Interrupt Request
// USB Interrupt Request Control (USBIEN)
#define rUSBIEN 0x70 // USB Interrupt Request Enable Register
#define bmVBUSIE bmVBUSIRQ // Vbus Present Interrupt Request Enable
#define bmNOVBUSIE bmNOVBUSIRQ // Vbus Absent Interrupt Request Enable
#define bmOSCOKIE bmOSCOKIRQ // Oscillator OK Interrupt Request Enable
// (USBCTL)
#define rUSBCTL 0x78 //15<<3
#define bmCHIPRES 0x20 //b5
#define bmPWRDOWN 0x10 //b4
// (CPUCTL)
#define rCPUCTL 0x80 //16<<3
#define bmPUSLEWID1 0x80 //b7
#define bmPULSEWID0 0x40 //b6
#define bmIE 0x01 //b0
// bmPUSLEWID1 bmPULSEWID0 Pulse width
// 0 0 10.6uS
// 0 1 5.3uS
// 1 0 2.6uS
// 1 1 1.3uS
#define PUSLEWIDTH10_6 (0)
#define PUSLEWIDTH5_3 (bmPULSEWID0)
#define PUSLEWIDTH2_6 (bmPUSLEWID1)
#define PUSLEWIDTH1_3 (bmPULSEWID0 | bmPUSLEWID1)
// (PINCTL)
#define rPINCTL 0x88 //17<<3
#define bmFDUPSPI 0x10 //b4
#define bmINTLEVEL 0x08 //b3
#define bmPOSINT 0x04 //b2
#define bmGPXB 0x02 //b1
#define bmGPXA 0x01 //b0
// GPX pin selections
#define GPX_OPERATE 0x00 //
#define GPX_VBDET 0x01 //
#define GPX_BUSACT 0x02 //
#define GPX_SOF 0x03 //
#define rREVISION 0x90 //18<<3
// (IOPINS1)
#define rIOPINS1 0xa0 //20<<3
#define bmGPOUT0 0x01 //
#define bmGPOUT1 0x02 //
#define bmGPOUT2 0x04 //
#define bmGPOUT3 0x08 //
#define bmGPIN0 0x10 //
#define bmGPIN1 0x20 //
#define bmGPIN2 0x40 //
#define bmGPIN3 0x80 //
// (IOPINS2)
#define rIOPINS2 0xa8 //21<<3
#define bmGPOUT4 0x01 //
#define bmGPOUT5 0x02 //
#define bmGPOUT6 0x04 //
#define bmGPOUT7 0x08 //
#define bmGPIN4 0x10 //
#define bmGPIN5 0x20 //
#define bmGPIN6 0x40 //
#define bmGPIN7 0x80 //
// (GPINIRQ)
#define rGPINIRQ 0xb0 //22<<3
#define bmGPINIRQ0 0x01 //
#define bmGPINIRQ1 0x02 //
#define bmGPINIRQ2 0x04 //
#define bmGPINIRQ3 0x08 //
#define bmGPINIRQ4 0x10 //
#define bmGPINIRQ5 0x20 //
#define bmGPINIRQ6 0x40 //
#define bmGPINIRQ7 0x80 //
// (GPINIEN)
#define rGPINIEN 0xb8 //23<<3
#define bmGPINIEN0 0x01 //
#define bmGPINIEN1 0x02 //
#define bmGPINIEN2 0x04 //
#define bmGPINIEN3 0x08 //
#define bmGPINIEN4 0x10 //
#define bmGPINIEN5 0x20 //
#define bmGPINIEN6 0x40 //
#define bmGPINIEN7 0x80 //
// (GPINPOL)
#define rGPINPOL 0xc0 //24<<3
#define bmGPINPOL0 0x01 //
#define bmGPINPOL1 0x02 //
#define bmGPINPOL2 0x04 //
#define bmGPINPOL3 0x08 //
#define bmGPINPOL4 0x10 //
#define bmGPINPOL5 0x20 //
#define bmGPINPOL6 0x40 //
#define bmGPINPOL7 0x80 //
//
// If any data transfer errors occur, the HXFRDNIRQ asserts, while the RCVDAVIRQ does not.
//
// The CPU clears the SNDBAVIRQ by writing the SNDBC register.
// The CPU should never directly clear the SNDBAVIRQ bit.
// Host Interrupt Request Status (HIRQ)
#define rHIRQ 0xc8 // Host Interrupt Request Register
#define bmBUSEVENTIRQ 0x01 // BUS Reset Done or BUS Resume Interrupt Request
#define bmRWUIRQ 0x02 // Remote Wakeup Interrupt Request
#define bmRCVDAVIRQ 0x04 // Receive FIFO Data Available Interrupt Request
#define bmSNDBAVIRQ 0x08 // Send Buffer Available Interrupt Request
#define bmSUSDNIRQ 0x10 // Suspend operation Done Interrupt Request
#define bmCONDETIRQ 0x20 // Peripheral Connect/Disconnect Interrupt Request
#define bmFRAMEIRQ 0x40 // Frame Generator Interrupt Request
#define bmHXFRDNIRQ 0x80 // Host Transfer Done Interrupt Request
// IRQs that are OK for the CPU to clear
#define ICLRALLBITS (bmBUSEVENTIRQ | bmRWUIRQ | bmRCVDAVIRQ | bmSUSDNIRQ | bmCONDETIRQ | bmFRAMEIRQ | bmHXFRDNIRQ)
// Host Interrupt Request Control (HIEN)
#define rHIEN 0xd0 //
#define bmBUSEVENTIE bmBUSEVENTIRQ // BUS Reset Done or BUS Resume Interrupt Request Enable
#define bmRWUIE bmRWUIRQ // Remote Wakeup Interrupt Request Enable
#define bmRCVDAVIE bmRCVDAVIRQ // Receive FIFO Data Available Interrupt Request Enable
#define bmSNDBAVIE bmSNDBAVIRQ // Send Buffer Available Interrupt Request Enable
#define bmSUSDNIE bmSUSDNIRQ // Suspend operation Done Interrupt Request Enable
#define bmCONDETIE bmCONDETIRQ // Peripheral Connect/Disconnect Interrupt Request Enable
#define bmFRAMEIE bmFRAMEIRQ // Frame Generator Interrupt Request Enable
#define bmHXFRDNIE bmHXFRDNIRQ // Host Transfer Done Interrupt Request Enable
// (MODE))
#define rMODE 0xd8 //27<<3
#define bmHOST 0x01 //
#define bmLOWSPEED 0x02 //
#define bmHUBPRE 0x04 //
#define bmSOFKAENAB 0x08 //
#define bmSEPIRQ 0x10 //
#define bmDELAYISO 0x20 //
#define bmDMPULLDN 0x40 //
#define bmDPPULLDN 0x80 //
#define rPERADDR 0xe0 //28<<3
// (HCTL)
#define rHCTL 0xe8 //29<<3
#define bmBUSRST 0x01 //
#define bmFRMRST 0x02 //
#define bmSAMPLEBUS 0x04 //
#define bmSIGRSM 0x08 //
#define bmRCVTOG0 0x10 //
#define bmRCVTOG1 0x20 //
#define bmSNDTOG0 0x40 //
#define bmSNDTOG1 0x80 //
// Host transfer (HXFR)
#define rHXFR 0xf0 //30<<3
/* Host transfer token values for writing the HXFR register (R30) */
/* OR this bit field with the endpoint number in bits 3:0 */
#define MAX3421E_tokSETUP 0x10 // HS=0, ISO=0, OUTNIN=0, SETUP=1
#define MAX3421E_tokIN 0x00 // HS=0, ISO=0, OUTNIN=0, SETUP=0
#define MAX3421E_tokOUT 0x20 // HS=0, ISO=0, OUTNIN=1, SETUP=0
#define MAX3421E_tokINHS 0x80 // HS=1, ISO=0, OUTNIN=0, SETUP=0
#define MAX3421E_tokOUTHS 0xA0 // HS=1, ISO=0, OUTNIN=1, SETUP=0
#define MAX3421E_tokISOIN 0x40 // HS=0, ISO=1, OUTNIN=0, SETUP=0
#define MAX3421E_tokISOOUT 0x60 // HS=0, ISO=1, OUTNIN=1, SETUP=0
// (HRSL)
#define rHRSL 0xf8 //31<<3
#define bmRCVTOGRD 0x10 //
#define bmSNDTOGRD 0x20 //
#define bmKSTATUS 0x40 //
#define bmJSTATUS 0x80 //
#define bmSE0 0x00 //SE0 - disconnect state
#define bmSE1 0xc0 //SE1 - illegal state
#define MODE_FS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB)
#define MODE_LS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB)
#endif //_max3421e_h_

@ -0,0 +1,519 @@
/* Copyright (C) 2015-2016 Andrew J. Kroll
and
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
*/
#ifndef USB_HOST_SHIELD_H
#define USB_HOST_SHIELD_H
// uncomment to get 'printf' console debugging. NOT FOR UNO!
//#define DEBUG_PRINTF_EXTRA_HUGE_USB_HOST_SHIELD
#ifdef LOAD_USB_HOST_SHIELD
#include "UHS_max3421e.h"
#include <SPI.h>
#if !defined(SPI_HAS_TRANSACTION)
#error "Your SPI library installation is too old."
#else
#if !defined(SPI_ATOMIC_VERSION)
#warning "Your SPI library installation lacks 'SPI_ATOMIC_VERSION'. Please complain to the maintainer."
#elif SPI_ATOMIC_VERSION < 1
#error "Your SPI library installation is too old."
#endif
#endif
#if DEBUG_PRINTF_EXTRA_HUGE
#ifdef DEBUG_PRINTF_EXTRA_HUGE_USB_HOST_SHIELD
#define MAX_HOST_DEBUG(...) printf_P(__VA_ARGS__)
#else
#define MAX_HOST_DEBUG(...) VOID0
#endif
#else
#define MAX_HOST_DEBUG(...) VOID0
#endif
#if !defined(USB_HOST_SHIELD_USE_ISR)
#if defined(USE_MULTIPLE_APP_API)
#define USB_HOST_SHIELD_USE_ISR 0
#else
#define USB_HOST_SHIELD_USE_ISR 1
#endif
#else
#define USB_HOST_SHIELD_USE_ISR 1
#endif
#if !USB_HOST_SHIELD_USE_ISR
#error NOISR Polled mode _NOT SUPPORTED YET_
//
// Polled defaults
//
#if defined(BOARD_BLACK_WIDDOW)
#define UHS_MAX3421E_SS_ 6
#define UHS_MAX3421E_INT_ 3
#elif defined(CORE_TEENSY) && (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
#if EXT_RAM
// Teensy++ 2.0 with XMEM2
#define UHS_MAX3421E_SS_ 20
#define UHS_MAX3421E_INT_ 7
#else
#define UHS_MAX3421E_SS_ 9
#define UHS_MAX3421E_INT_ 8
#endif
#define UHS_MAX3421E_SPD
#elif defined(ARDUINO_AVR_ADK)
#define UHS_MAX3421E_SS_ 53
#define UHS_MAX3421E_INT_ 54
#elif defined(ARDUINO_AVR_BALANDUINO)
#define UHS_MAX3421E_SS_ 20
#define UHS_MAX3421E_INT_ 19
#else
#define UHS_MAX3421E_SS_ 10
#define UHS_MAX3421E_INT_ 9
#endif
#else
#if defined(ARDUINO_ARCH_PIC32)
// PIC32 only allows edge interrupts, isn't that lovely? We'll emulate it...
#if CHANGE < 2
#error core too old.
#endif
#define IRQ_IS_EDGE 0
#ifndef digitalPinToInterrupt
// great, this isn't implemented.
#warning digitalPinToInterrupt is not defined, complain here https://github.com/chipKIT32/chipKIT-core/issues/114
#if defined(_BOARD_UNO_) || defined(_BOARD_UC32_)
#define digitalPinToInterrupt(p) ((p) == 2 ? 1 : ((p) == 7 ? 2 : ((p) == 8 ? 3 : ((p) == 35 ? 4 : ((p) == 38 ? 0 : NOT_AN_INTERRUPT)))))
#warning digitalPinToInterrupt is now defined until this is taken care of.
#else
#error digitalPinToInterrupt not defined for your board, complain here https://github.com/chipKIT32/chipKIT-core/issues/114
#endif
#endif
#else
#define IRQ_IS_EDGE 0
#endif
// More stupidity from our friends @ Sony...
#if defined(ARDUINO_spresense_ast)
#if !defined(NOT_AN_INTERRUPT)
#define NOT_AN_INTERRUPT -1
#endif
#endif
// SAMD uses an enum for this instead of a define. Isn't that just dandy?
#if !defined(NOT_AN_INTERRUPT) && !defined(ARDUINO_ARCH_SAMD)
#warning NOT_AN_INTERRUPT not defined, possible problems ahead.
#warning If NOT_AN_INTERRUPT is an enum or something else, complain to UHS30 developers on github.
#warning Otherwise complain to your board core developer/maintainer.
#define NOT_AN_INTERRUPT -1
#endif
//
// Interrupt defaults. Int0 or Int1
//
#ifdef BOARD_BLACK_WIDDOW
#error "HELP! Please send us an email, I don't know the values for Int0 and Int1 on the Black Widow board!"
#elif defined(ARDUINO_AVR_ADK)
#define UHS_MAX3421E_SS_ 53
#define UHS_MAX3421E_INT_ 54
#elif defined(ARDUINO_spresense_ast)
#define UHS_MAX3421E_SS_ 21
#define UHS_MAX3421E_INT_ 20
#define SPIclass SPI5
//#define UHS_MAX3421E_SPD 100000
#elif defined(CORE_TEENSY) && (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
// TO-DO!
#if EXT_RAM
// Teensy++ 2.0 with XMEM2
#define UHS_MAX3421E_SS_ 20
#define UHS_MAX3421E_INT_ 7
#else
#define UHS_MAX3421E_SS_ 9
#define UHS_MAX3421E_INT_ 8
#endif
#elif defined(ARDUINO_AVR_BALANDUINO)
#error "ISR mode is currently not supported on the Balanduino. Please set USB_HOST_SHIELD_USE_ISR to 0."
#else
#define UHS_MAX3421E_SS_ 10
#ifdef __AVR__
#if defined(__AVR_ATmega32U4__)
#define INT_FOR_PIN2 1
#define INT_FOR_PIN3 0
#else
// Everybody else???
#define INT_FOR_PIN2 0
#define INT_FOR_PIN3 1
#endif
#define UHS_MAX3421E_INT_ 3
#else
// Non-avr
#if defined(ARDUINO_ARCH_PIC32)
// UNO32 External Interrupts:
// Pin 38 (INT0), Pin 2 (INT1), Pin 7 (INT2), Pin 8 (INT3), Pin 35 (INT4)
#define UHS_MAX3421E_INT_ 7
#else
#define UHS_MAX3421E_INT_ 9
#endif
#endif
#endif
#endif
#if defined(NO_AUTO_SPEED)
// Ugly details section...
// MAX3421E characteristics
// SPI Serial - Clock Input. An external SPI master supplies SCLK with frequencies up to 26MHz. The
// logic level is referenced to the voltage on VL. Data is clocked into the SPI slave inter face on the
// rising edge of SCLK. Data is clocked out of the SPI slave interface on the falling edge of SCLK.
// Serial Clock (SCLK) Period 38.4ns minimum. 17ns minimum pulse width. VL >2.5V
// SCLK Fall to MISO Propagation Delay 14.2ns
// SCLK Fall to MOSI Propagation Delay 14.2ns
// SCLK Fall to MOSI Drive 3.5ns
// Theoretical deadline for reply 17.7ns
// 26MHz 38.4615ns period <-- MAX3421E theoretical maximum
#if !defined(UHS_MAX3421E_SPD)
#if defined(ARDUINO_SAMD_ZERO)
// Zero violates spec early, needs a long setup time, or doesn't like high latency.
#define UHS_MAX3421E_SPD 10000000
#elif defined(ARDUINO_ARCH_PIC32)
// PIC MX 5/6/7 characteristics
// 25MHZ 40ns period <-- PIC MX 5/6/7 theoretical maximum
// pulse width minimum Tsclk/2ns
// Trise/fall 10ns maximum. 5ns is typical but not guaranteed.
// Tsetup minimum for MISO 10ns.
// We are in violation by 7.7ns @ 25MHz due to latency alone.
// Even reading at end of data cycle, we only have a 2.3ns window.
// This is too narrow to to compensate for capacitance, trace lengths, and noise.
// 17.7ns + 10ns = 27.7ns
// 18MHz fits and has enough slack time to compensate for capacitance, trace lengths, and noise.
// For high speeds the SMP bit is recommended too, which samples at the end instead of the middle.
// 20Mhz seems to work.
#define UHS_MAX3421E_SPD 20000000
#else
#define UHS_MAX3421E_SPD 25000000
#endif
#endif
#else
// We start at 25MHz, and back down until hardware can take it.
// Of course, SPI library can adjust this for us too.
// Why not 26MHz? Because I have not found any MCU board that
// can actually go that fast without problems.
// Could be a shield limitation too.
#if !defined(UHS_MAX3421E_SPD)
#define UHS_MAX3421E_SPD 25000000
#endif
#endif
#ifndef UHS_MAX3421E_INT
#define UHS_MAX3421E_INT UHS_MAX3421E_INT_
#endif
#ifndef UHS_MAX3421E_SS
#define UHS_MAX3421E_SS UHS_MAX3421E_SS_
#endif
// NOTE: On the max3421e the irq enable and irq bits are in the same position.
// IRQs used if CPU polls
#define ENIBITSPOLLED (bmCONDETIE | bmBUSEVENTIE | bmFRAMEIE)
// IRQs used if CPU is interrupted
#define ENIBITSISR (bmCONDETIE | bmBUSEVENTIE | bmFRAMEIE /* | bmRCVDAVIRQ | bmSNDBAVIRQ | bmHXFRDNIRQ */ )
#if !USB_HOST_SHIELD_USE_ISR
#define IRQ_CHECK_MASK (ENIBITSPOLLED & ICLRALLBITS)
#define IRQ_IS_EDGE 0
#else
#define IRQ_CHECK_MASK (ENIBITSISR & ICLRALLBITS)
#endif
#if IRQ_IS_EDGE
// Note: UNO32 Interrupts can only be RISING, or FALLING.
// This poses an interesting problem, since we want to use a LOW level.
// The MAX3421E provides for pulse width control for an IRQ.
// We do need to watch the timing on this, as a second IRQ could cause
// a missed IRQ, since we read the level of the line to check if the IRQ
// is actually for this chip. The only other alternative is to add a capacitor
// and an NPN transistor, and use two lines. We can try this first, though.
// Worse case, we can ignore reading the pin for verification on UNO32.
// Too bad there is no minimum low width setting.
//
// Single Clear First Second Clear first Clear last
// IRQ Single IRQ IRQ Second active pending IRQ
// | | | | | |
// V V V V V V
// _____ _________ _ _ _______
// |______| |______| |______| |______________|
//
#define IRQ_SENSE FALLING
#if defined(ARDUINO_ARCH_PIC32)
//#define bmPULSEWIDTH PUSLEWIDTH10_6
#define bmPULSEWIDTH 0
#define bmIRQ_SENSE 0
#else
#define bmPULSEWIDTH PUSLEWIDTH1_3
#define bmIRQ_SENSE 0
#endif
#else
#if !defined(IRQ_SENSE)
#define IRQ_SENSE LOW
#endif
#if !defined(bmPULSEWIDTH)
#define bmPULSEWIDTH 0
#endif
#if !defined(bmIRQ_SENSE)
#define bmIRQ_SENSE bmINTLEVEL
#endif
#endif
class MAX3421E_HOST :
public UHS_USB_HOST_BASE
#if defined(SWI_IRQ_NUM)
, public dyn_SWI
#endif
{
// TO-DO: move these into the parent class.
volatile uint8_t vbusState;
volatile uint16_t sof_countdown;
// TO-DO: pack into a struct/union and use one byte
volatile bool busevent;
volatile bool sofevent;
volatile bool counted;
volatile bool condet;
volatile bool doingreset;
#ifdef USB_HOST_MANUAL_POLL
volatile bool frame_irq_enabled = false;
bool enable_frame_irq(bool enable) {
const bool prev_state = frame_irq_enabled;
if(prev_state != enable) {
if(enable)
regWr(rHIEN, regRd(rHIEN) | bmFRAMEIE);
else
regWr(rHIEN, regRd(rHIEN) & ~bmFRAMEIE);
frame_irq_enabled = enable;
}
return prev_state;
}
#endif
public:
SPISettings MAX3421E_SPI_Settings;
uint8_t ss_pin;
uint8_t irq_pin;
// Will use the defaults UHS_MAX3421E_SS, UHS_MAX3421E_INT and speed
UHS_NI MAX3421E_HOST(void) {
sof_countdown = 0;
busevent = false;
doingreset = false;
sofevent = false;
condet = false;
ss_pin = UHS_MAX3421E_SS;
irq_pin = UHS_MAX3421E_INT;
MAX3421E_SPI_Settings = SPISettings(UHS_MAX3421E_SPD, MSBFIRST, SPI_MODE0);
hub_present = 0;
};
// Will use user supplied pins, and UHS_MAX3421E_SPD
UHS_NI MAX3421E_HOST(uint8_t pss, uint8_t pirq) {
sof_countdown = 0;
busevent = false;
doingreset = false;
sofevent = false;
condet = false;
ss_pin = pss;
irq_pin = pirq;
MAX3421E_SPI_Settings = SPISettings(UHS_MAX3421E_SPD, MSBFIRST, SPI_MODE0);
hub_present = 0;
};
// Will use user supplied pins, and speed
UHS_NI MAX3421E_HOST(uint8_t pss, uint8_t pirq, uint32_t pspd) {
sof_countdown = 0;
doingreset = false;
busevent = false;
sofevent = false;
condet = false;
ss_pin = pss;
irq_pin = pirq;
MAX3421E_SPI_Settings = SPISettings(pspd, MSBFIRST, SPI_MODE0);
hub_present = 0;
};
virtual bool UHS_NI sof_delay(uint16_t x) {
#ifdef USB_HOST_MANUAL_POLL
const bool saved_irq_state = enable_frame_irq(true);
#endif
sof_countdown = x;
while((sof_countdown != 0) && !condet) {
SYSTEM_OR_SPECIAL_YIELD();
#if !USB_HOST_SHIELD_USE_ISR
Task();
#endif
}
#ifdef USB_HOST_MANUAL_POLL
enable_frame_irq(saved_irq_state);
#endif
// Serial.println("...Wake");
return (!condet);
};
virtual UHS_EpInfo *ctrlReqOpen(uint8_t addr, uint64_t Request, uint8_t* dataptr);
virtual void UHS_NI vbusPower(VBUS_t state) {
regWr(rPINCTL, (bmFDUPSPI | bmIRQ_SENSE) | (uint8_t)(state));
};
void UHS_NI Task(void);
virtual uint8_t SetAddress(uint8_t addr, uint8_t ep, UHS_EpInfo **ppep, uint16_t &nak_limit);
virtual uint8_t OutTransfer(UHS_EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data);
virtual uint8_t InTransfer(UHS_EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data);
virtual uint8_t ctrlReqClose(UHS_EpInfo *pep, uint8_t bmReqType, uint16_t left, uint16_t nbytes, uint8_t *dataptr);
virtual uint8_t ctrlReqRead(UHS_EpInfo *pep, uint16_t *left, uint16_t *read, uint16_t nbytes, uint8_t *dataptr);
virtual uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit);
void UHS_NI ReleaseChildren(void) {
for(uint8_t i = 0; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++)
if(devConfig[i])
devConfig[i]->Release();
hub_present = 0;
};
virtual bool IsHub(uint8_t klass) {
if(klass == UHS_USB_CLASS_HUB) {
hub_present = bmHUBPRE;
return true;
}
return false;
};
virtual void VBUS_changed(void);
virtual void UHS_NI doHostReset(void) {
#if USB_HOST_SHIELD_USE_ISR
// Enable interrupts
noInterrupts();
#endif
doingreset = true;
busevent = true;
regWr(rHIRQ, bmBUSEVENTIRQ); // see data sheet.
regWr(rHCTL, bmBUSRST); //issue bus reset
#if USB_HOST_SHIELD_USE_ISR
DDSB();
// Enable interrupts
interrupts();
#endif
while(busevent) {
DDSB();
SYSTEM_OR_SPECIAL_YIELD();
}
#endif
#if USB_HOST_SHIELD_USE_ISR
// Enable interrupts
noInterrupts();
#endif
#ifdef USB_HOST_MANUAL_POLL
enable_frame_irq(true);
#endif
sofevent = true;
#if USB_HOST_SHIELD_USE_ISR
DDSB();
// Enable interrupts
interrupts();
#endif
// Wait for SOF
while(sofevent) {
}
#if USB_HOST_SHIELD_USE_ISR
// Enable interrupts
noInterrupts();
#endif
doingreset = false;
#if USB_HOST_SHIELD_USE_ISR
DDSB();
// Enable interrupts
interrupts();
};
int16_t UHS_NI Init(int16_t mseconds);
int16_t UHS_NI Init(void) {
return Init(INT16_MIN);
};
void ISRTask(void);
void ISRbottom(void);
void busprobe(void);
uint16_t reset(void);
// MAX3421e specific
void regWr(uint8_t reg, uint8_t data);
void gpioWr(uint8_t data);
uint8_t regRd(uint8_t reg);
uint8_t gpioRd(void);
uint8_t* bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
uint8_t* bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
// ARM/NVIC specific, used to emulate reentrant ISR.
#if defined(SWI_IRQ_NUM)
void dyn_SWISR(void) {
ISRbottom();
};
#endif
virtual void UHS_NI suspend_host(void) {
// Used on MCU that lack control of IRQ priority (AVR).
// Suspends ISRs, for critical code. IRQ will be serviced after it is resumed.
// NOTE: you must track the state yourself!
#if defined(__AVR__)
noInterrupts();
detachInterrupt(UHS_GET_DPI(irq_pin));
interrupts();
#endif
};
virtual void UHS_NI resume_host(void);
};
#if !defined(SPIclass)
#define SPIclass SPI
#endif
#if !defined(USB_HOST_SHIELD_LOADED)
#include "USB_HOST_SHIELD_INLINE.h"
#endif
#else
#error "define LOAD_USB_HOST_SHIELD in your sketch, never include USB_HOST_SHIELD.h in a driver."
#endif
#endif /* USB_HOST_SHIELD_H */

@ -0,0 +1,153 @@
/*
* File: macro_logic.h
* Author: root
*
* Created on December 22, 2018, 4:49 AM
*
* To test:
* gcc -DAJK_TEST_MACRO_LOGIC -E macro_logic.h
*
*/
#ifndef MACRO_LOGIC_H
#define MACRO_LOGIC_H
#define AJK_CAT(a, ...) AJK_PRIMITIVE_CAT(a, __VA_ARGS__)
#define AJK_PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define AJK_COMPL(b) AJK_PRIMITIVE_CAT(AJK_COMPL_, b)
#define AJK_COMPL_0 1
#define AJK_COMPL_1 0
#define AJK_BITAND(x) AJK_PRIMITIVE_CAT(AJK_BITAND_, x)
#define AJK_BITAND_0(y) 0
#define AJK_BITAND_1(y) y
#define AJK_INC(x) AJK_PRIMITIVE_CAT(AJK_INC_, x)
#define AJK_INC_0 1
#define AJK_INC_1 2
#define AJK_INC_2 3
#define AJK_INC_3 4
#define AJK_INC_4 5
#define AJK_INC_5 6
#define AJK_INC_6 7
#define AJK_INC_7 8
#define AJK_INC_8 9
#define AJK_INC_9 10
#define AJK_INC_10 10
#define AJK_DEC(x) AJK_PRIMITIVE_CAT(AJK_DEC_, x)
#define AJK_DEC_0 0
#define AJK_DEC_1 0
#define AJK_DEC_2 1
#define AJK_DEC_3 2
#define AJK_DEC_4 3
#define AJK_DEC_5 4
#define AJK_DEC_6 5
#define AJK_DEC_7 6
#define AJK_DEC_8 7
#define AJK_DEC_9 8
#define AJK_DEC_10 9
#define AJK_CHECK_N(x, n, ...) n
#define AJK_CHECK(...) AJK_CHECK_N(__VA_ARGS__, 0,)
#define AJK_PROBE(x) x, 1,
#define AJK_IS_PAREN(x) AJK_CHECK(AJK_IS_PAREN_PROBE x)
#define AJK_IS_PAREN_PROBE(...) AJK_PROBE(~)
#define AJK_NOT(x) AJK_CHECK(AJK_PRIMITIVE_CAT(AJK_NOT_, x))
#define AJK_NOT_0 AJK_PROBE(~)
#define AJK_COMPL(b) AJK_PRIMITIVE_CAT(AJK_COMPL_, b)
#define AJK_COMPL_0 1
#define AJK_COMPL_1 0
#define AJK_BOOL(x) AJK_COMPL(AJK_NOT(x))
#define AJK_IIF(c) AJK_PRIMITIVE_CAT(AJK_IIF_, c)
#define AJK_IIF_0(t, ...) __VA_ARGS__
#define AJK_IIF_1(t, ...) t
#define AJK_IF(c) AJK_IIF(AJK_BOOL(c))
#define AJK_EAT(...)
#define AJK_EXPAND(...) __VA_ARGS__
#define AJK_WHEN(c) AJK_IF(c)(AJK_EXPAND, AJK_EAT)
#define AJK_EMPTY()
#define AJK_DEFER(id) id AJK_EMPTY()
#define AJK_OBSTRUCT(id) id AJK_DEFER(AJK_EMPTY)()
#define AJK_EVAL(...) AJK_EVAL1(AJK_EVAL1(AJK_EVAL1(__VA_ARGS__)))
#define AJK_EVAL1(...) AJK_EVAL2(AJK_EVAL2(AJK_EVAL2(__VA_ARGS__)))
#define AJK_EVAL2(...) AJK_EVAL3(AJK_EVAL3(AJK_EVAL3(__VA_ARGS__)))
#define AJK_EVAL3(...) AJK_EVAL4(AJK_EVAL4(AJK_EVAL4(__VA_ARGS__)))
#define AJK_EVAL4(...) AJK_EVAL5(AJK_EVAL5(AJK_EVAL5(__VA_ARGS__)))
#define AJK_EVAL5(...) __VA_ARGS__
#define AJK_REPEAT(AJK_count, AJK_macro, ...) \
AJK_WHEN(AJK_count) \
( \
AJK_OBSTRUCT(AJK_REPEAT_INDIRECT) () \
( \
AJK_DEC(AJK_count), AJK_macro, __VA_ARGS__ \
) \
AJK_OBSTRUCT(AJK_macro) \
( \
AJK_DEC(AJK_count), __VA_ARGS__ \
) \
)
#define AJK_REPEAT_INDIRECT() AJK_REPEAT
#define AJK_WHILE(AJK_pred, AJK_op, ...) \
IF(AJK_pred(__VA_ARGS__)) \
( \
AJK_OBSTRUCT(AJK_WHILE_INDIRECT) () \
( \
AJK_pred, AJK_op, AJK_op(__VA_ARGS__) \
), \
__VA_ARGS__ \
)
#define AJK_WHILE_INDIRECT() AJK_WHILE
#define AJK_PRIMITIVE_COMPARE(x, y) AJK_IS_PAREN \
( \
AJK_COMPARE_ ## x ( AJK_COMPARE_ ## y) (()) \
)
#define AJK_IS_COMPARABLE(x) AJK_IS_PAREN( AJK_CAT(AJK_COMPARE_, x) (()) )
#define AJK_NOT_EQUAL(x, y) \
AJK_IIF(AJK_BITAND(AJK_IS_COMPARABLE(x))(AJK_IS_COMPARABLE(y)) ) \
( \
AJK_PRIMITIVE_COMPARE, \
1 AJK_EAT \
)(x, y)
#define AJK_EQUAL(x, y) AJK_COMPL(AJK_NOT_EQUAL(x, y))
#define AJK_COMMA() ,
#define AJK_COMMA_IF(n) AJK_IF(n)(AJK_COMMA, AJK_EAT)()
#define AJK_COMMA_VAR(AJK_count, AJK_v) AJK_COMMA_IF(AJK_count) AJK_v ## AJK_count
#define AJK_MAKE_LIST(AJK_v, AJK_count) AJK_EVAL(AJK_REPEAT(AJK_count, AJK_COMMA_VAR, AJK_v))
#define AJK_FUN(AJK_count, AJK_v, AJK_args, AJK_body) AJK_v ## AJK_count (AJK_args) { AJK_body(AJK_count) }
#define AJK_MAKE_FUNS(AJK_v, AJK_args, AJK_count, AJK_body) AJK_EVAL(AJK_REPEAT(AJK_count, AJK_FUN, AJK_v, AJK_args, AJK_body))
#if defined(AJK_TEST_MACRO_LOGIC)
#define BODY(AJKindex) some(C, statement); contaning(a, test[AJKindex]);
#define ZERO_TIMES_TEST 0
#define THREE_TIMES_TEST 3
blank > AJK_MAKE_LIST(VARIABLE_, ZERO_TIMES_TEST) < because zero repeats
Make 3 comma separated indexed variables : AJK_MAKE_LIST(VARIABLE_, THREE_TIMES_TEST)
Make 3 bogus function bodies
AJK_MAKE_FUNS(unsigned Cfunc,(arg1, arg2),3,BODY)
#endif
#endif /* MACRO_LOGIC_H */

@ -0,0 +1,246 @@
/*
* File: SWI_INLINE.h
* Author: xxxajk@gmail.com
*
* Created on December 5, 2014, 9:40 AM
*
* This is the actual library.
* There are no 'c' or 'cpp' files.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef DYN_SWI_H
#ifndef SWI_INLINE_H
#define SWI_INLINE_H
#ifndef SWI_MAXIMUM_ALLOWED
#define SWI_MAXIMUM_ALLOWED 4
#endif
#if defined(__arm__) || defined(ARDUINO_ARCH_PIC32)
static char dyn_SWI_initied = 0;
static dyn_SWI* dyn_SWI_LIST[SWI_MAXIMUM_ALLOWED];
static dyn_SWI* dyn_SWI_EXEC[SWI_MAXIMUM_ALLOWED];
#if defined(__arm__)
#if defined(__USE_CMSIS_VECTORS__)
extern "C" {
void (*_VectorsRam[VECTORTABLE_SIZE])(void)__attribute__((aligned(VECTORTABLE_ALIGNMENT)));
}
#else
__attribute__((always_inline)) static inline void __DSB(void) {
__asm__ volatile ("dsb");
}
#endif // defined(__USE_CMSIS_VECTORS__)
#else // defined(__arm__)
__attribute__((always_inline)) static inline void __DSB(void) {
__asm__ volatile ("sync" : : : "memory");
}
#endif // defined(__arm__)
/**
* Execute queued class ISR routines.
*/
#if defined(ARDUINO_ARCH_PIC32)
static p32_regset *ifs = ((p32_regset *) & IFS0) + (SWI_IRQ_NUM / 32); //interrupt flag register set
static p32_regset *iec = ((p32_regset *) & IEC0) + (SWI_IRQ_NUM / 32); //interrupt enable control reg set
static uint32_t swibit = 1 << (SWI_IRQ_NUM % 32);
void
#if defined(__PIC32MZXX__)
__attribute__((nomips16,at_vector(SWI_VECTOR),interrupt(SWI_IPL)))
#else
__attribute__((interrupt(),nomips16))
#endif
softISR(void) {
#else
#if defined(ARDUINO_spresense_ast)
unsigned int softISR(void) {
#else
void softISR(void) {
#endif
#endif
//
// TO-DO: Perhaps limit to 8, and inline this?
//
// Make a working copy, while clearing the queue.
noInterrupts();
#if defined(ARDUINO_ARCH_PIC32)
//ifs->clr = swibit;
#endif
for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) {
dyn_SWI_EXEC[i] = dyn_SWI_LIST[i];
dyn_SWI_LIST[i] = NULL;
}
__DSB();
interrupts();
// Execute each class SWI
for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) {
if(dyn_SWI_EXEC[i]) {
#if defined(__DYN_SWI_DEBUG_LED__)
digitalWrite(__DYN_SWI_DEBUG_LED__, HIGH);
#endif
dyn_SWI_EXEC[i]->dyn_SWISR();
#if defined(__DYN_SWI_DEBUG_LED__)
digitalWrite(__DYN_SWI_DEBUG_LED__, LOW);
#endif
}
}
#if defined(ARDUINO_ARCH_PIC32)
noInterrupts();
if(!dyn_SWI_EXEC[0]) ifs->clr = swibit;
interrupts();
#endif
#if defined(ARDUINO_spresense_ast)
return 0;
#endif
}
#define DDSB() __DSB()
#endif
#if defined(__arm__)
#ifndef interruptsStatus
#define interruptsStatus() __interruptsStatus()
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
static inline unsigned char __interruptsStatus(void) {
unsigned int primask;
asm volatile ("mrs %0, primask" : "=r" (primask));
if(primask) return 0;
return 1;
}
#endif
/**
* Initialize the Dynamic (class) Software Interrupt
*/
static void Init_dyn_SWI(void) {
if(!dyn_SWI_initied) {
#if defined(__USE_CMSIS_VECTORS__)
uint32_t *X_Vectors = (uint32_t*)SCB->VTOR;
for(int i = 0; i < VECTORTABLE_SIZE; i++) {
_VectorsRam[i] = reinterpret_cast<void (*)()>(X_Vectors[i]); /* copy vector table to RAM */
}
/* relocate vector table */
noInterrupts();
SCB->VTOR = reinterpret_cast<uint32_t>(&_VectorsRam);
DDSB();
interrupts();
#endif
#if !defined(ARDUINO_spresense_ast)
for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) dyn_SWI_LIST[i] = NULL;
noInterrupts();
_VectorsRam[SWI_IRQ_NUM + 16] = reinterpret_cast<void (*)()>(softISR);
DDSB();
interrupts();
NVIC_SET_PRIORITY(SWI_IRQ_NUM, 255);
NVIC_ENABLE_IRQ(SWI_IRQ_NUM);
#endif
#if defined(__DYN_SWI_DEBUG_LED__)
pinMode(__DYN_SWI_DEBUG_LED__, OUTPUT);
digitalWrite(__DYN_SWI_DEBUG_LED__, LOW);
#endif
dyn_SWI_initied = 1;
}
}
/**
*
* @param klass class that extends dyn_SWI
* @return 0 on queue full, else returns queue position (ones based)
*/
int exec_SWI(const dyn_SWI* klass) {
int rc = 0;
uint8_t irestore = interruptsStatus();
// Allow use from inside a critical section...
// ... and prevent races if also used inside an ISR
noInterrupts();
for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) {
if(!dyn_SWI_LIST[i]) {
rc = 1 + i; // Success!
dyn_SWI_LIST[i] = (dyn_SWI*)klass;
#if !defined(ARDUINO_spresense_ast)
if(!NVIC_GET_PENDING(SWI_IRQ_NUM)) NVIC_SET_PENDING(SWI_IRQ_NUM);
#else
// Launch 1-shot timer as an emulated SWI
// Hopefully the value of Zero is legal.
// 1 microsecond latency would suck!
attachTimerInterrupt(softISR, 100);
#endif
DDSB();
break;
}
}
// Restore interrupts, if they were on.
if(irestore) interrupts();
return rc;
}
#elif defined(ARDUINO_ARCH_PIC32)
/**
* Initialize the Dynamic (class) Software Interrupt
*/
static void Init_dyn_SWI(void) {
if(!dyn_SWI_initied) {
uint32_t sreg = disableInterrupts();
setIntVector(SWI_VECTOR, softISR);
setIntPriority(SWI_VECTOR, 1, 1); // Lowest priority, ever.
ifs->clr = swibit;
iec->clr = swibit;
iec->set = swibit;
restoreInterrupts(sreg);
#if defined(__DYN_SWI_DEBUG_LED__)
pinMode(__DYN_SWI_DEBUG_LED__, OUTPUT);
UHS_PIN_WRITE(__DYN_SWI_DEBUG_LED__, LOW);
#endif
}
}
/**
*
* @param klass class that extends dyn_SWI
* @return 0 on queue full, else returns queue position (ones based)
*/
int exec_SWI(const dyn_SWI* klass) {
int rc = 0;
uint32_t sreg = disableInterrupts();
for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) {
if(!dyn_SWI_LIST[i]) {
rc = 1 + i; // Success!
dyn_SWI_LIST[i] = (dyn_SWI*)klass;
if(!(ifs->reg & swibit)) ifs->set = swibit;
;
break;
}
}
restoreInterrupts(sreg);
return rc;
}
#endif /* defined(__arm__) */
#endif /* SWI_INLINE_H */
#else
#error "Never include SWI_INLINE.h directly, include dyn_SWI.h instead"
#endif

@ -0,0 +1,172 @@
/*
* File: dyn_SWI.h
* Author: xxxajk@gmail.com
*
* Created on December 5, 2014, 9:12 AM
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DYN_SWI_H
#define DYN_SWI_H
#if defined(__arm__) || defined(ARDUINO_ARCH_PIC32)
#if defined(ARDUINO_ARCH_PIC32)
#include <p32xxxx.h>
#endif
#ifdef __cplusplus
#if defined(true)
#undef true
#endif
#if defined(false)
#undef false
#endif
#endif
#if defined(ARDUINO_spresense_ast)
#define SWI_IRQ_NUM 666 // because this board is totally evil.
#elif defined(ARDUINO_ARCH_PIC32)
#ifndef SWI_IRQ_NUM
#if defined(_DSPI0_IPL_ISR)
#define SWI_IPL _DSPI0_IPL_ISR
#define SWI_VECTOR _DSPI0_ERR_IRQ
#define SWI_IRQ_NUM _DSPI0_ERR_IRQ
#elif defined(_PMP_ERROR_IRQ)
#define SWI_IRQ_NUM _PMP_ERROR_IRQ
#define SWI_VECTOR _PMP_VECTOR
#else
#error SWI_IRQ_NUM and SWI_VECTOR need a definition
#endif
#ifdef __cplusplus
extern "C"
{
void
#if defined(__PIC32MZXX__)
__attribute__((nomips16,at_vector(SWI_VECTOR),interrupt(SWI_IPL)))
#else
__attribute__((interrupt(),nomips16))
#endif
softISR(void);
}
#endif
#endif
#elif !defined(NVIC_NUM_INTERRUPTS)
// Assume CMSIS
#define __USE_CMSIS_VECTORS__
#if defined(NUMBER_OF_INT_VECTORS)
#define NVIC_NUM_INTERRUPTS (NUMBER_OF_INT_VECTORS-16)
#else
#define NVIC_NUM_INTERRUPTS ((int)PERIPH_COUNT_IRQn)
#endif
#define VECTORTABLE_SIZE (NVIC_NUM_INTERRUPTS+16)
#define VECTORTABLE_ALIGNMENT (0x100ul)
#define NVIC_GET_ACTIVE(n) NVIC_GetActive((IRQn_Type)n)
#define NVIC_GET_PENDING(n) NVIC_GetPendingIRQ((IRQn_Type)n)
#define NVIC_SET_PENDING(n) NVIC_SetPendingIRQ((IRQn_Type)n)
#define NVIC_ENABLE_IRQ(n) NVIC_EnableIRQ((IRQn_Type)n)
#define NVIC_SET_PRIORITY(n ,p) NVIC_SetPriority((IRQn_Type)n, (uint32_t) p)
//extern "C" {
// extern uint32_t _VectorsRam[VECTORTABLE_SIZE] __attribute__((aligned(VECTORTABLE_ALIGNMENT)));
//}
#ifndef SWI_IRQ_NUM
#if defined(__SAM3X8E__) && defined(_VARIANT_ARDUINO_DUE_X_)
// DUE
// Choices available:
// HSMCI_IRQn Multimedia Card Interface (HSMCI)
// EMAC_IRQn Ethernet MAC (EMAC)
// EMAC is not broken out on the official DUE, but is on clones.
// SPI0_IRQn Serial Peripheral Interface (SPI0)
// SPI0_IRQn seems to be the best choice, as long as nobody uses an ISR based master
#define SWI_IRQ_NUM SPI0_IRQn
#elif defined(ARDUINO_SAMD_ZERO)
// Just use sercom4's unused IRQ vector.
#define SWI_IRQ_NUM I2S_IRQn
//#define SWI_IRQ_NUM SERCOM4_IRQn
#endif
#endif
#ifndef SWI_IRQ_NUM
#error SWI_IRQ_NUM not defined (CMSIS)
#endif
#elif defined(CORE_TEENSY)
#ifndef NVIC_GET_ACTIVE
#define NVIC_GET_ACTIVE(n) (*((volatile uint32_t *)0xE000E300 + ((n) >> 5)) & (1 << ((n) & 31)))
#endif
#ifndef NVIC_GET_PENDING
#define NVIC_GET_PENDING(n) (*((volatile uint32_t *)0xE000E200 + ((n) >> 5)) & (1 << ((n) & 31)))
#ifndef SWI_IRQ_NUM
#if defined(__MK20DX256__)
#define SWI_IRQ_NUM 17
#elif defined(__MK20DX128__)
#define SWI_IRQ_NUM 5
#elif defined(__MKL26Z64__)
#define SWI_IRQ_NUM 4
#elif defined(__MK66FX1M0__)
#define SWI_IRQ_NUM 30
#elif defined(__MK64FX512__)
#define SWI_IRQ_NUM 30
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
#define SWI_IRQ_NUM 71
#else
#error Do not know how to relocate IRQ vectors for this pjrc product
#endif
#endif
#endif
#else // Not CMSIS or PJRC CORE_TEENSY or PIC32 or SPRESENSE
#error Do not know how to relocate IRQ vectors or perform SWI
#endif // SWI_IRQ_NUM
#ifndef SWI_IRQ_NUM
#error SWI_IRQ_NUM not defined
#else
/**
* Use this class to extend your class, in order to provide
* a C++ context callable SWI.
*/
class dyn_SWI {
public:
/**
* Override this method with your code.
*/
virtual void dyn_SWISR(void) {
};
};
extern int exec_SWI(const dyn_SWI* klass);
#include "SWI_INLINE.h"
// IMPORTANT! Define this so that you do NOT end up with a NULL stub!
#define SWI_NO_STUB
#endif /* SWI_IRQ_NUM */
#endif /* __arm__ */
// if no SWI for CPU (e.g. AVR) make a void stub.
#ifndef SWI_NO_STUB
#define Init_dyn_SWI() (void(0))
#if !defined(DDSB)
#define DDSB() (void(0))
#endif
#endif
#endif /* DYN_SWI_H */

@ -1,187 +0,0 @@
diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/masstorage.cpp lib/masstorage.cpp
--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/masstorage.cpp 2018-09-21 10:19:36.107502252 -0600
+++ lib/masstorage.cpp 2018-09-21 09:46:19.620175519 -0600
@@ -24,6 +24,8 @@
#include "masstorage.h"
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
+
const uint8_t BulkOnly::epDataInIndex = 1;
const uint8_t BulkOnly::epDataOutIndex = 2;
const uint8_t BulkOnly::epInterruptInIndex = 3;
@@ -796,6 +798,9 @@
buf[i] = 0x00;
}
WriteOk[lun] = true;
+ #if ENABLED(USB_FLASH_DRIVE_SUPPORT) && defined(SKIP_WRITE_PROTECT)
+ return 0;
+ #endif
uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
if(!rc) {
WriteOk[lun] = ((buf[2] & 0x80) == 0);
@@ -1271,3 +1276,5 @@
return MASS_ERR_NOT_IMPLEMENTED;
#endif
}
+
+#endif // USB_FLASH_DRIVE_SUPPORT
\ No newline at end of file
diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/message.cpp lib/message.cpp
--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/message.cpp 2018-09-21 10:20:15.995647957 -0600
+++ lib/message.cpp 2018-09-19 07:43:46.520339375 -0600
@@ -23,6 +23,9 @@
*/
#include "Usb.h"
+
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
+
// 0x80 is the default (i.e. trace) to turn off set this global to something lower.
// this allows for 126 other debugging levels.
// TO-DO: Allow assignment to a different serial port by software
@@ -120,4 +123,6 @@
D_PrintHex<uint8_t > (rcode, 0x80);
Notify(PSTR("\r\n"), 0x80);
}
-#endif
+#endif // DEBUG_USB_HOST
+
+#endif // USB_FLASH_DRIVE_SUPPORT
\ No newline at end of file
diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/parsetools.cpp lib/parsetools.cpp
--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/parsetools.cpp 2018-09-21 10:21:16.215867769 -0600
+++ lib/parsetools.cpp 2018-09-19 07:43:46.520339375 -0600
@@ -23,6 +23,8 @@
*/
#include "Usb.h"
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
+
bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
if(!pBuf) {
Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80);
@@ -72,3 +74,5 @@
}
return true;
}
+
+#endif // USB_FLASH_DRIVE_SUPPORT
\ No newline at end of file
diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/settings.h lib/settings.h
--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/settings.h 2018-09-21 10:22:21.792106872 -0600
+++ lib/settings.h 2018-09-21 10:01:53.383594081 -0600
@@ -25,7 +25,21 @@
#ifndef USB_HOST_SHIELD_SETTINGS_H
#define USB_HOST_SHIELD_SETTINGS_H
#include "macros.h"
-
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
+ ////////////////////////////////////////////////////////////////////////////////
+ /* Added by Bill Greiman to speed up mass storage initialization with USB
+ * flash drives and simple USB hard drives.
+ * Disable this by defining DELAY(x) to be delay(x).
+ */
+ #define delay(x) if((x) < 200) safe_delay(x)
+ /* Almost all USB flash drives and simple USB hard drives fail the write
+ * protect test and add 20 - 30 seconds to USB init. Set SKIP_WRITE_PROTECT
+ * to nonzero to skip the test and assume the drive is writable.
+ */
+ #define SKIP_WRITE_PROTECT 1
+ /* Since Marlin only cares about USB flash drives, we only need one LUN. */
+ #define MASS_MAX_SUPPORTED_LUN 1
+#endif
////////////////////////////////////////////////////////////////////////////////
// SPI Configuration
////////////////////////////////////////////////////////////////////////////////
@@ -45,6 +59,10 @@
* multiple serial ports are available.
* For example Serial3.
*/
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
+ #define USB_HOST_SERIAL MYSERIAL0
+#endif
+
#ifndef USB_HOST_SERIAL
#define USB_HOST_SERIAL Serial
#endif
@@ -99,7 +117,7 @@
// No user serviceable parts below this line.
// DO NOT change anything below here unless you are a developer!
-#include "version_helper.h"
+//#include "version_helper.h"
#if defined(__GNUC__) && defined(__AVR__)
#ifndef GCC_VERSION
@@ -149,7 +167,6 @@
#else
#define USING_SPI4TEENSY3 0
#endif
-
#if ((defined(ARDUINO_SAM_DUE) && defined(__SAM3X8E__)) || defined(__ARDUINO_X86__) || ARDUINO >= 10600) && !USING_SPI4TEENSY3
#include <SPI.h> // Use the Arduino SPI library for the Arduino Due, Intel Galileo 1 & 2, Intel Edison or if the SPI library with transaction is available
#endif
diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/UsbCore.h lib/UsbCore.h
--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/UsbCore.h 2018-09-21 10:23:09.348280107 -0600
+++ lib/UsbCore.h 2018-09-19 07:43:46.520339375 -0600
@@ -32,7 +32,10 @@
//#define USB_METHODS_INLINE
/* shield pins. First parameter - SS pin, second parameter - INT pin */
-#ifdef BOARD_BLACK_WIDDOW
+
+#if defined(__MARLIN_H__)
+typedef MAX3421e MAX3421E; // Marlin redefines this class in "../usb_host.h"
+#elif defined(BOARD_BLACK_WIDDOW)
typedef MAX3421e<P6, P3> MAX3421E; // Black Widow
#elif defined(CORE_TEENSY) && (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
#if EXT_RAM
diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/Usb.cpp lib/Usb.cpp
--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/Usb.cpp 2018-09-21 10:23:20.732321559 -0600
+++ lib/Usb.cpp 2018-09-19 07:43:46.520339375 -0600
@@ -25,6 +25,8 @@
#include "Usb.h"
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
+
static uint8_t usb_error = 0;
static uint8_t usb_task_state;
@@ -825,3 +827,4 @@
}
#endif // defined(USB_METHODS_INLINE)
+#endif // USB_FLASH_DRIVE_SUPPORT
diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/Usb.h lib/Usb.h
--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/Usb.h 2018-09-21 10:23:33.756368972 -0600
+++ lib/Usb.h 2018-09-19 07:43:46.520339375 -0600
@@ -25,6 +25,8 @@
#ifndef _usb_h_
#define _usb_h_
+#include "../../../Marlin.h"
+
// WARNING: Do not change the order of includes, or stuff will break!
#include <inttypes.h>
#include <stddef.h>
@@ -34,13 +36,15 @@
#include "settings.h"
#include "printhex.h"
#include "message.h"
+
#include "hexdump.h"
-#include "sink_parser.h"
+//#include "sink_parser.h"
#include "max3421e.h"
#include "address.h"
-#include "avrpins.h"
+//#include "avrpins.h"
#include "usb_ch9.h"
-#include "usbhost.h"
+//#include "usbhost.h"
+#include "../usb_host.h"
#include "UsbCore.h"
#include "parsetools.h"
#include "confdescparser.h"

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is required for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1021,17 +1021,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1022,17 +1022,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1026,17 +1026,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1017,17 +1017,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1017,17 +1017,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1017,17 +1017,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1017,17 +1017,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1022,17 +1022,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1022,17 +1022,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

@ -1018,17 +1018,31 @@
* equivalent MAX3421E breakout board. The USB thumb drive will appear
* to Marlin as an SD card.
*
* The MAX3421E must be assigned the same pins as the SD card reader, with
* The MAX3421E can be assigned the same pins as the SD card reader, with
* the following pin mapping:
*
* SCLK, MOSI, MISO --> SCLK, MOSI, MISO
* INT --> SD_DETECT_PIN
* INT --> SD_DETECT_PIN [1]
* SS --> SDSS
*
* [1] On AVR an interrupt-capable pin is best for UHS3 compatibility.
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
* - UHS2 uses no interrupts and has been production-tested
* on a LulzBot TAZ Pro with a 32-bit Archim board.
*
* - UHS3 is newer code with better USB compatibility. But it
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS3_USB
#endif
/**

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save