diff --git a/boards.txt b/boards.txt index 024218f6f..f291d1044 100644 --- a/boards.txt +++ b/boards.txt @@ -28,5 +28,5 @@ wifio.build.f_cpu=80000000L wifio.build.board=ESP8266_WIFIO wifio.build.core=esp8266 # TODO: add board variant for WIFIO -wifio.build.variant=esp01 +wifio.build.variant=wifio diff --git a/variants/esp01/pins_arduino.h b/variants/esp01/pins_arduino.h index 3ecc7a83a..5b36c0010 100644 --- a/variants/esp01/pins_arduino.h +++ b/variants/esp01/pins_arduino.h @@ -3,6 +3,7 @@ Part of Arduino - http://www.arduino.cc/ Copyright (c) 2007 David A. Mellis + Modified for ESP8266 platform by Ivan Grokhotkov, 2014-2015. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/variants/wifio/WifioProtocol.h b/variants/wifio/WifioProtocol.h new file mode 100644 index 000000000..42d52f4d2 --- /dev/null +++ b/variants/wifio/WifioProtocol.h @@ -0,0 +1,161 @@ +/* + WifioProtocol.h - virtual IO protocol for the WIFIO board + + Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef WIFIO_PROTOCOL_H +#define WIFIO_PROTOCOL_H + +#include +#include "Arduino.h" + +inline void protocolError() +{ + delay(5); + Serial.flush(); +} + +namespace wifio { + +const uint8_t MAGIC = 0x05; + +enum Command { + CMD_NONE, + CMD_SYNC, + CMD_PINMODE, + CMD_DIGITALWRITE, + CMD_DIGITALREAD, + CMD_DIGITALREADRESULT, + CMD_ANALOGWRITE, + CMD_ANALOGREAD, + CMD_ANALOGREADRESULT, + CMD_INVALID, +}; + +struct CommandHeader { + uint8_t magic : 4; + uint8_t cmd : 4; +}; + +struct SyncCommand { + CommandHeader header; + uint8_t val : 7; + uint8_t parity : 1; +}; + +struct PinModeCommand { + CommandHeader header; + uint8_t pin : 5; + uint8_t mode : 2; + uint8_t parity : 1; +}; + +struct DigitalWriteCommand { + CommandHeader header; + uint8_t pin : 5; + uint8_t value : 1; + uint8_t unused : 1; + uint8_t parity : 1; +}; + +struct DigitalReadCommand { + CommandHeader header; + uint8_t pin : 5; + uint8_t unused : 2; + uint8_t parity : 1; +}; + +struct DigitalReadResultCommand { + CommandHeader header; + uint8_t pin : 5; + uint8_t value : 1; + uint8_t unused : 1; + uint8_t parity : 1; +}; + +struct AnalogWriteCommand { + CommandHeader header; + uint8_t value; + uint8_t pin : 5; + uint8_t unused : 2; + uint8_t parity : 1; +}; + +struct AnalogReadCommand { + CommandHeader header; + uint8_t pin : 5; + uint8_t unused : 2; + uint8_t parity : 1; +}; + +struct AnalogReadResultCommand { + CommandHeader header; + uint8_t pin : 5; + uint8_t val_h : 3; + uint8_t val_l : 7; + uint8_t parity : 1; +}; + +template +void sendCommand(Stream& stream, T& t) +{ + // TODO: calculate parity + t.parity = 1; + stream.write(reinterpret_cast(&t), sizeof(T)); +} + +template +bool expectCommand(Stream& stream, enum Command cmd, T& t) +{ + size_t nIt = 0; + t = { 0 }; + while (stream.available() < sizeof(T)) + { + if (++nIt == 100) { + return false; + } + delayMicroseconds(10); + } + uint8_t* p = reinterpret_cast(&t); + for (size_t i = 0; i < sizeof(T); ++i) + p[i] = stream.read(); + // TODO : check parity + if (static_cast(cmd) != t.header.cmd) { + protocolError(); + return false; + } + return true; +} + +inline Command peekCommand(Stream& stream) +{ + if (!stream.available()) + return CMD_NONE; + + uint8_t b = stream.peek(); + CommandHeader* h = reinterpret_cast(&b); + if (h->magic != MAGIC) + return CMD_INVALID; + return static_cast(h->cmd); +} + +}// namespace wifio + +#endif//WIFIO_PROTOCOL_H + diff --git a/variants/wifio/WifioWiring.cpp b/variants/wifio/WifioWiring.cpp new file mode 100644 index 000000000..1555e13d1 --- /dev/null +++ b/variants/wifio/WifioWiring.cpp @@ -0,0 +1,128 @@ +/* + WifioWiring.cpp - Wiring API implementation for the WIFIO board + + Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "wiring_private.h" +#include "WifioProtocol.h" + + +namespace wifio { + + void pinMode(int avrPin, int mode) { + PinModeCommand cmd { MAGIC, CMD_PINMODE, static_cast(avrPin), static_cast(mode) }; + sendCommand(Serial, cmd); + } + + void digitalWrite(int avrPin, int value) { + DigitalWriteCommand cmd { MAGIC, CMD_DIGITALWRITE, static_cast(avrPin), static_cast(value) }; + sendCommand(Serial, cmd); + } + + int digitalRead(int avrPin) { + DigitalReadCommand cmd { MAGIC, CMD_DIGITALREAD, static_cast(avrPin) }; + sendCommand(Serial, cmd); + DigitalReadResultCommand reply; + if (!expectCommand(Serial, CMD_DIGITALREADRESULT, reply) || reply.pin != avrPin) { + protocolError(); + return 0; + } + return reply.value; + } + + void analogWrite(int avrPin, int value) { + AnalogWriteCommand cmd { MAGIC, CMD_ANALOGWRITE, static_cast(value), static_cast(avrPin) }; + sendCommand(Serial, cmd); + } + + int analogRead(int avrPin) { + AnalogReadCommand cmd { MAGIC, CMD_ANALOGREAD, static_cast(avrPin) }; + sendCommand(Serial, cmd); + AnalogReadResultCommand reply; + if (!expectCommand(Serial, CMD_ANALOGREADRESULT, reply) || reply.pin != avrPin) { + protocolError(); + return 0; + } + return ((reply.val_h << 7) | reply.val_l); + } + +} // namespace wifio + +extern "C" void __pinMode(uint8_t pin, uint8_t mode); +extern "C" void __digitalWrite(uint8_t pin, uint8_t val); +extern "C" int __digitalRead(uint8_t pin); +extern "C" void __analogWrite(uint8_t pin, int val); +// extern "C" void __attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode); +// extern "C" void __detachInterrupt(uint8_t pin); +extern "C" void __initPins(); +extern "C" int __analogRead(uint8_t pin); + + +extern "C" void pinMode(uint8_t pin, uint8_t mode){ + if (pin >= ESP_PINS_OFFSET) { // esp pin + __pinMode(pin - ESP_PINS_OFFSET, mode); + } + else { // AVR pin + wifio::pinMode(pin, mode); + } +} + +extern "C" void digitalWrite(uint8_t pin, uint8_t value) { + if (pin >= ESP_PINS_OFFSET) { // esp pin + __digitalWrite(pin - ESP_PINS_OFFSET, value); + } + else { // AVR pin + wifio::digitalWrite(pin, value); + } +} + +extern "C" int digitalRead(uint8_t pin) { + if (pin >= ESP_PINS_OFFSET) { + return __digitalRead(pin - ESP_PINS_OFFSET); + } + else { + return wifio::digitalRead(pin); + } +} + +extern "C" int analogRead(uint8_t pin) { + if (pin >= ESP_PINS_OFFSET) { + return __analogRead(pin - ESP_PINS_OFFSET); + } + else { + return wifio::analogRead(pin); + } +} + +extern "C" void analogWrite(uint8_t pin, int value) { + if (pin >= ESP_PINS_OFFSET) { + __analogWrite(pin - ESP_PINS_OFFSET, value); + } + else { + wifio::analogWrite(pin, value); + } +} + +extern "C" void initPins() +{ + __initPins(); + // sync here +} + + diff --git a/variants/wifio/pins_arduino.h b/variants/wifio/pins_arduino.h new file mode 100644 index 000000000..1217c7de2 --- /dev/null +++ b/variants/wifio/pins_arduino.h @@ -0,0 +1,57 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + Modified for ESP8266 WIFIO board by Ivan Grokhotkov, 2015. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#define NUM_DIGITAL_PINS 36 +#define NUM_ANALOG_INPUTS 1 +#define ESP_PINS_OFFSET 20 + +static const uint8_t SDA = 4; +static const uint8_t SCL = 5; + +static const uint8_t SS = 12; +static const uint8_t MOSI = 13; +static const uint8_t MISO = 14; +static const uint8_t SCK = 15; + +static const uint8_t A0 = 14; +static const uint8_t A1 = 15; +static const uint8_t A2 = 16; +static const uint8_t A3 = 17; +static const uint8_t A4 = 18; +static const uint8_t A5 = 19; +static const uint8_t A6 = 20; +static const uint8_t A7 = 21; + +static const uint8_t BUILTIN_LED = 2; + +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_HARDWARE Serial +#define SERIAL_PORT_HARDWARE_OPEN Serial + +#endif /* Pins_Arduino_h */