Merge pull request #263 from felis/ESP8266

Added support for ESP8266
This commit is contained in:
Kristian Sloth Lauszus 2017-06-14 13:31:53 +02:00 committed by GitHub
commit ff8bdb24c1
11 changed files with 139 additions and 34 deletions

View file

@ -25,7 +25,7 @@ env:
- PLATFORMIO_CI_SRC=examples/Bluetooth/SPPMulti
- PLATFORMIO_CI_SRC=examples/Bluetooth/Wii
- PLATFORMIO_CI_SRC=examples/Bluetooth/WiiBalanceBoard
- PLATFORMIO_CI_SRC=examples/Bluetooth/WiiIRCamera
- PLATFORMIO_CI_SRC=examples/Bluetooth/WiiIRCamera PLATFORMIO_BUILD_FLAGS="-DWIICAMERA"
- PLATFORMIO_CI_SRC=examples/Bluetooth/WiiMulti
- PLATFORMIO_CI_SRC=examples/Bluetooth/WiiUProController
- PLATFORMIO_CI_SRC=examples/board_qc
@ -63,7 +63,7 @@ env:
install:
- pip install -U platformio
- export PLATFORMIO_BUILD_FLAGS="-DDEBUG_USB_HOST -DWIICAMERA -Wall -Werror"
- export PLATFORMIO_BUILD_FLAGS="$PLATFORMIO_BUILD_FLAGS -DDEBUG_USB_HOST -Wall -Werror"
#
# Libraries from PlatformIO Library Registry:
@ -74,4 +74,5 @@ install:
- platformio lib install 62 416 417
script:
- platformio ci --board=uno --board=due --board=genuino101 --board=teensy30 --board=teensy31 --board=teensy35 --board=teensy36 --board=teensylc --lib="."
- platformio ci --lib="." --board=uno --board=due --board=genuino101 --board=teensy30 --board=teensy31 --board=teensy35 --board=teensy36 --board=teensylc
- platformio ci --lib="." --board=esp12e --board=nodemcu --project-option="build_flags=-Wno-unused-function" # Workaround https://github.com/esp8266/Arduino/pull/2881

View file

@ -123,6 +123,11 @@ Currently the following boards are supported by the library:
* Please see: <http://www.circuitsathome.com/mcu/usb/running-usb-host-code-on-digilent-chipkit-board>.
* STM32F4
* Currently the [NUCLEO-F446RE](http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF262063) is supported featuring the STM32F446. Take a look at the following example code: <https://github.com/Lauszus/Nucleo_F446RE_USBHost>.
* ESP8266 is supported using the [ESP8266 Arduino core](https://github.com/esp8266/Arduino)
* Note it uses pin 15 and 5 for SS and INT respectively
* Also please be aware that:
* GPIO16 is **NOT** usable, as it will be used for some other purposes. For example, reset the SoC itself from sleep mode.
* GPIO6 to 11 is also **NOT** usable, as they are used to connect SPI flash chip and it is used for storing the executable binary content.
The following boards need to be activated manually in [settings.h](settings.h):

View file

@ -39,6 +39,8 @@ typedef MAX3421e<P53, P54> MAX3421E; // Arduino Mega ADK
typedef MAX3421e<P20, P19> MAX3421E; // Balanduino
#elif defined(__ARDUINO_X86__) && PLATFORM_ID == 0x06
typedef MAX3421e<P3, P2> MAX3421E; // The Intel Galileo supports much faster read and write speed at pin 2 and 3
#elif defined(ESP8266)
typedef MAX3421e<P15, P5> MAX3421E; // ESP8266 boards
#else
typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560, Leonardo, Due etc.), Intel Edison, Intel Galileo 2 or Teensy 2.0 and 3.x
#endif

View file

@ -1326,6 +1326,47 @@ MAKE_PIN(P13, 13); //
#undef MAKE_PIN
#elif defined(ESP8266)
#define pgm_read_pointer(p) pgm_read_ptr(p)
#define MAKE_PIN(className, pin) \
class className { \
public: \
static void Set() { \
digitalWrite(pin, HIGH);\
} \
static void Clear() { \
digitalWrite(pin, LOW); \
} \
static void SetDirRead() { \
pinMode(pin, INPUT); \
} \
static void SetDirWrite() { \
pinMode(pin, OUTPUT); \
} \
static uint8_t IsSet() { \
return digitalRead(pin); \
} \
};
// Pinout for ESP-12 module
// 0 .. 16 - Digital pins
// GPIO 6 to 11 and 16 are not usable in this library.
MAKE_PIN(P0, 0);
MAKE_PIN(P1, 1); // TX0
MAKE_PIN(P2, 2); // TX1
MAKE_PIN(P3, 3); // RX0
MAKE_PIN(P4, 4); // SDA
MAKE_PIN(P5, 5); // SCL
MAKE_PIN(P12, 12); // MISO
MAKE_PIN(P13, 13); // MOSI
MAKE_PIN(P14, 14); // SCK
MAKE_PIN(P15, 15); // SS
#undef MAKE_PIN
#else
#error "Please define board in avrpins.h"

View file

@ -67,7 +67,8 @@ void MIDI_poll()
pid = Midi.pid;
}
if (Midi.RecvData( &rcvd, bufMidi) == 0 ) {
sprintf(buf, "%08lX: ", (uint32_t)millis());
uint32_t time = (uint32_t)millis();
sprintf(buf, "%04X%04X: ", (uint16_t)(time >> 16), (uint16_t)(time & 0xFFFF)); // Split variable to prevent warnings on the ESP8266 platform
Serial.print(buf);
Serial.print(rcvd);
Serial.print(':');

View file

@ -104,7 +104,11 @@ void loop()
Usb.ForEachUsbDevice(&PrintAllDescriptors);
Usb.ForEachUsbDevice(&PrintAllAddresses);
while ( 1 ); //stop
while ( 1 ) { // stop
#ifdef ESP8266
yield(); // needed in order to reset the watchdog timer on the ESP8266
#endif
}
}
}

View file

@ -60,6 +60,9 @@ void setup() {
uint8_t sample_rd = 0;
uint8_t gpinpol_copy = Usb.regRd(rGPINPOL);
for(uint8_t i = 0; i < 16; i++) {
#ifdef ESP8266
yield(); // needed in order to reset the watchdog timer on the ESP8266
#endif
for(uint16_t j = 0; j < 65535; j++) {
Usb.regWr(rGPINPOL, sample_wr);
sample_rd = Usb.regRd(rGPINPOL);
@ -85,6 +88,9 @@ void setup() {
uint8_t tmpbyte;
E_Notify(PSTR("\r\nGPIO test. Connect GPIN0 to GPOUT7, GPIN1 to GPOUT6, and so on"), 0x80);
for(uint8_t sample_gpio = 0; sample_gpio < 255; sample_gpio++) {
#ifdef ESP8266
yield(); // needed in order to reset the watchdog timer on the ESP8266
#endif
Usb.gpioWr(sample_gpio);
tmpbyte = Usb.gpioRd();
/* bit reversing code copied vetbatim from http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious */
@ -112,6 +118,9 @@ void setup() {
/* Restart oscillator */
E_Notify(PSTR("\r\nResetting oscillator\r\n"), 0x80);
for(uint16_t i = 0; i < 100; i++) {
#ifdef ESP8266
yield(); // needed in order to reset the watchdog timer on the ESP8266
#endif
E_Notify(PSTR("\rReset number "), 0x80);
Serial.print(i, DEC);
Usb.regWr(rUSBCTL, bmCHIPRES); //reset
@ -206,7 +215,11 @@ void loop() {
print_hex(buf.bNumConfigurations, 8);
/**/
E_Notify(PSTR("\r\n\nAll tests passed. Press RESET to restart test"), 0x80);
while(1);
while(1) {
#ifdef ESP8266
yield(); // needed in order to reset the watchdog timer on the ESP8266
#endif
}
}
break;
case( USB_STATE_ERROR):
@ -228,6 +241,9 @@ void halt55() {
while(1) {
Usb.regWr(0x55, 0x55);
#ifdef ESP8266
yield(); // needed in order to reset the watchdog timer on the ESP8266
#endif
}
}
@ -253,7 +269,11 @@ void print_hex(int v, int num_places) {
/* prints "Press any key" and returns when key is pressed */
void press_any_key() {
E_Notify(PSTR("\r\nPress any key to continue..."), 0x80);
while(Serial.available() <= 0); //wait for input
while(Serial.available() <= 0) { // wait for input
#ifdef ESP8266
yield(); // needed in order to reset the watchdog timer on the ESP8266
#endif
}
Serial.read(); //empty input buffer
return;
}

View file

@ -150,12 +150,12 @@ void printFloat(double number, int16_t digits)
void gpsdump(TinyGPS &gps)
{
int32_t lat, lon;
long lat, lon;
float flat, flon;
uint32_t age, date, time, chars;
int16_t year;
unsigned long age, date, time, chars;
int year;
uint8_t month, day, hour, minute, second, hundredths;
uint16_t sentences, failed;
unsigned short sentences, failed;
gps.get_position(&lat, &lon, &age);
Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon);
@ -175,7 +175,7 @@ void gpsdump(TinyGPS &gps)
feedgps();
gps.crack_datetime((int*)&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
Serial.print(" Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print("."); Serial.print(static_cast<int>(hundredths));
Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
@ -189,7 +189,7 @@ void gpsdump(TinyGPS &gps)
feedgps();
gps.stats(&chars, (unsigned short*)&sentences, (unsigned short*)&failed);
gps.stats(&chars, &sentences, &failed);
Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
}

View file

@ -50,6 +50,7 @@
"teensy",
"atmelsam",
"nordicnrf51",
"ststm32"
"ststm32",
"espressif8266"
]
}

View file

@ -177,4 +177,20 @@ extern SPI_HandleTypeDef SPI_Handle; // Needed to be declared in your main.cpp
#define MFK_CASTUINT8T
#endif
// Workaround issue: https://github.com/esp8266/Arduino/issues/2078
#ifdef ESP8266
#undef PROGMEM
#define PROGMEM
#undef PSTR
#define PSTR(s) (s)
#undef pgm_read_byte
#define pgm_read_byte(addr) (*reinterpret_cast<const uint8_t*>(addr))
#undef pgm_read_word
#define pgm_read_word(addr) (*reinterpret_cast<const uint16_t*>(addr))
#endif
#ifdef ARDUINO_ESP8266_WIFIO
#error "This board is currently not supported"
#endif
#endif /* SETTINGS_H */

View file

@ -39,7 +39,7 @@ public:
SPI_SS::SetDirWrite();
SPI_SS::Set();
}
#elif SPI_HAS_TRANSACTION
#elif defined(SPI_HAS_TRANSACTION)
static void init() {
SPI.begin(); // The SPI library with transaction will take care of setting up the pins - settings is set in beginTransaction()
SPI_SS::SetDirWrite();
@ -85,7 +85,19 @@ public:
};
/* SPI pin definitions. see avrpins.h */
#if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#if defined(PIN_SPI_SCK) && defined(PIN_SPI_MOSI) && defined(PIN_SPI_MISO) && defined(PIN_SPI_SS)
// Use pin defines: https://github.com/arduino/Arduino/pull/4814
// Based on: https://www.mikeash.com/pyblog/friday-qa-2015-03-20-preprocessor-abuse-and-optional-parentheses.html
#define NOTHING_EXTRACT
#define EXTRACT(...) EXTRACT __VA_ARGS__
#define PASTE(x, ...) x ## __VA_ARGS__
#define EVALUATING_PASTE(x, ...) PASTE(x, __VA_ARGS__)
#define UNPAREN(x) EVALUATING_PASTE(NOTHING_, EXTRACT x)
#define APPEND_PIN(pin) P ## pin // Appends the pin to 'P', e.g. 1 becomes P1
#define MAKE_PIN(x) EVALUATING_PASTE(APPEND_, PIN(UNPAREN(x)))
typedef SPi< MAKE_PIN(PIN_SPI_SCK), MAKE_PIN(PIN_SPI_MOSI), MAKE_PIN(PIN_SPI_MISO), MAKE_PIN(PIN_SPI_SS) > spi;
#undef MAKE_PIN
#elif defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
typedef SPi< Pb1, Pb2, Pb3, Pb0 > spi;
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
typedef SPi< Pb5, Pb3, Pb4, Pb2 > spi;
@ -97,6 +109,8 @@ typedef SPi< P13, P11, P12, P10 > spi;
typedef SPi< P76, P75, P74, P10 > spi;
#elif defined(RBL_NRF51822)
typedef SPi< P16, P18, P17, P10 > spi;
#elif defined(ESP8266)
typedef SPi< P14, P13, P12, P15 > spi;
#else
#error "No SPI entry in usbhost.h"
#endif
@ -152,7 +166,7 @@ MAX3421e< SPI_SS, INTR >::MAX3421e() {
template< typename SPI_SS, typename INTR >
void MAX3421e< SPI_SS, INTR >::regWr(uint8_t reg, uint8_t data) {
XMEM_ACQUIRE_SPI();
#if SPI_HAS_TRANSACTION
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0
#endif
SPI_SS::Clear();
@ -162,7 +176,7 @@ void MAX3421e< SPI_SS, INTR >::regWr(uint8_t reg, uint8_t data) {
c[0] = reg | 0x02;
c[1] = data;
spi4teensy3::send(c, 2);
#elif SPI_HAS_TRANSACTION
#elif defined(SPI_HAS_TRANSACTION) && !defined(ESP8266)
uint8_t c[2];
c[0] = reg | 0x02;
c[1] = data;
@ -172,7 +186,7 @@ void MAX3421e< SPI_SS, INTR >::regWr(uint8_t reg, uint8_t data) {
c[0] = reg | 0x02;
c[1] = data;
HAL_SPI_Transmit(&SPI_Handle, c, 2, HAL_MAX_DELAY);
#elif !defined(SPDR)
#elif !defined(SPDR) // ESP8266
SPI.transfer(reg | 0x02);
SPI.transfer(data);
#else
@ -183,7 +197,7 @@ void MAX3421e< SPI_SS, INTR >::regWr(uint8_t reg, uint8_t data) {
#endif
SPI_SS::Set();
#if SPI_HAS_TRANSACTION
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
XMEM_RELEASE_SPI();
@ -195,7 +209,7 @@ void MAX3421e< SPI_SS, INTR >::regWr(uint8_t reg, uint8_t data) {
template< typename SPI_SS, typename INTR >
uint8_t* MAX3421e< SPI_SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
XMEM_ACQUIRE_SPI();
#if SPI_HAS_TRANSACTION
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0
#endif
SPI_SS::Clear();
@ -204,7 +218,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t*
spi4teensy3::send(reg | 0x02);
spi4teensy3::send(data_p, nbytes);
data_p += nbytes;
#elif SPI_HAS_TRANSACTION
#elif defined(SPI_HAS_TRANSACTION) && !defined(ESP8266)
SPI.transfer(reg | 0x02);
SPI.transfer(data_p, nbytes);
data_p += nbytes;
@ -217,7 +231,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t*
HAL_SPI_Transmit(&SPI_Handle, &data, 1, HAL_MAX_DELAY);
HAL_SPI_Transmit(&SPI_Handle, data_p, nbytes, HAL_MAX_DELAY);
data_p += nbytes;
#elif !defined(SPDR)
#elif !defined(SPDR) // ESP8266
SPI.transfer(reg | 0x02);
while(nbytes) {
SPI.transfer(*data_p);
@ -236,7 +250,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t*
#endif
SPI_SS::Set();
#if SPI_HAS_TRANSACTION
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
XMEM_RELEASE_SPI();
@ -258,7 +272,7 @@ void MAX3421e< SPI_SS, INTR >::gpioWr(uint8_t data) {
template< typename SPI_SS, typename INTR >
uint8_t MAX3421e< SPI_SS, INTR >::regRd(uint8_t reg) {
XMEM_ACQUIRE_SPI();
#if SPI_HAS_TRANSACTION
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0
#endif
SPI_SS::Clear();
@ -272,7 +286,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::regRd(uint8_t reg) {
uint8_t rv = 0;
HAL_SPI_Receive(&SPI_Handle, &rv, 1, HAL_MAX_DELAY);
SPI_SS::Set();
#elif !defined(SPDR) || SPI_HAS_TRANSACTION
#elif !defined(SPDR) || defined(SPI_HAS_TRANSACTION)
SPI.transfer(reg);
uint8_t rv = SPI.transfer(0); // Send empty byte
SPI_SS::Set();
@ -285,7 +299,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::regRd(uint8_t reg) {
uint8_t rv = SPDR;
#endif
#if SPI_HAS_TRANSACTION
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
XMEM_RELEASE_SPI();
@ -297,7 +311,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::regRd(uint8_t reg) {
template< typename SPI_SS, typename INTR >
uint8_t* MAX3421e< SPI_SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
XMEM_ACQUIRE_SPI();
#if SPI_HAS_TRANSACTION
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0
#endif
SPI_SS::Clear();
@ -306,7 +320,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t*
spi4teensy3::send(reg);
spi4teensy3::receive(data_p, nbytes);
data_p += nbytes;
#elif SPI_HAS_TRANSACTION
#elif defined(SPI_HAS_TRANSACTION) && !defined(ESP8266)
SPI.transfer(reg);
memset(data_p, 0, nbytes); // Make sure we send out empty bytes
SPI.transfer(data_p, nbytes);
@ -320,7 +334,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t*
memset(data_p, 0, nbytes); // Make sure we send out empty bytes
HAL_SPI_Receive(&SPI_Handle, data_p, nbytes, HAL_MAX_DELAY);
data_p += nbytes;
#elif !defined(SPDR)
#elif !defined(SPDR) // ESP8266
SPI.transfer(reg);
while(nbytes) {
*data_p++ = SPI.transfer(0);
@ -348,7 +362,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t*
#endif
SPI_SS::Set();
#if SPI_HAS_TRANSACTION
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
XMEM_RELEASE_SPI();