added arduino, modified build
This commit is contained in:
3
arduino/libraries/Firmata/utility/BLEStream.cpp
Normal file
3
arduino/libraries/Firmata/utility/BLEStream.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
/*
|
||||
* Implementation is in BLEStream.h to avoid linker issues.
|
||||
*/
|
||||
243
arduino/libraries/Firmata/utility/BLEStream.h
Normal file
243
arduino/libraries/Firmata/utility/BLEStream.h
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
BLEStream.h
|
||||
|
||||
Based on BLESerial.cpp by Voita Molda
|
||||
https://github.com/sandeepmistry/arduino-BLEPeripheral/blob/master/examples/serial/BLESerial.h
|
||||
|
||||
Last updated April 4th, 2016
|
||||
*/
|
||||
|
||||
#ifndef _BLE_STREAM_H_
|
||||
#define _BLE_STREAM_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
#if defined(_VARIANT_ARDUINO_101_X_)
|
||||
#include <CurieBLE.h>
|
||||
#define _MAX_ATTR_DATA_LEN_ BLE_MAX_ATTR_DATA_LEN
|
||||
#else
|
||||
#include <BLEPeripheral.h>
|
||||
#define _MAX_ATTR_DATA_LEN_ BLE_ATTRIBUTE_MAX_VALUE_LENGTH
|
||||
#endif
|
||||
|
||||
#define BLESTREAM_TXBUFFER_FLUSH_INTERVAL 80
|
||||
#define BLESTREAM_MIN_FLUSH_INTERVAL 8 // minimum interval for flushing the TX buffer
|
||||
|
||||
// #define BLE_SERIAL_DEBUG
|
||||
|
||||
class BLEStream : public BLEPeripheral, public Stream
|
||||
{
|
||||
public:
|
||||
BLEStream(unsigned char req = 0, unsigned char rdy = 0, unsigned char rst = 0);
|
||||
|
||||
void begin(...);
|
||||
bool poll();
|
||||
void end();
|
||||
void setFlushInterval(int);
|
||||
|
||||
virtual int available(void);
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
virtual void flush(void);
|
||||
virtual size_t write(uint8_t byte);
|
||||
using Print::write;
|
||||
virtual operator bool();
|
||||
|
||||
private:
|
||||
bool _connected;
|
||||
unsigned long _flushed;
|
||||
int _flushInterval;
|
||||
static BLEStream* _instance;
|
||||
|
||||
size_t _rxHead;
|
||||
size_t _rxTail;
|
||||
size_t _rxCount() const;
|
||||
unsigned char _rxBuffer[256];
|
||||
size_t _txCount;
|
||||
unsigned char _txBuffer[_MAX_ATTR_DATA_LEN_];
|
||||
|
||||
BLEService _uartService = BLEService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
|
||||
BLEDescriptor _uartNameDescriptor = BLEDescriptor("2901", "UART");
|
||||
BLECharacteristic _rxCharacteristic = BLECharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse, _MAX_ATTR_DATA_LEN_);
|
||||
BLEDescriptor _rxNameDescriptor = BLEDescriptor("2901", "RX - Receive Data (Write)");
|
||||
BLECharacteristic _txCharacteristic = BLECharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, _MAX_ATTR_DATA_LEN_);
|
||||
BLEDescriptor _txNameDescriptor = BLEDescriptor("2901", "TX - Transfer Data (Notify)");
|
||||
|
||||
void _received(const unsigned char* data, size_t size);
|
||||
static void _received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* BLEStream.cpp
|
||||
* Copied here as a hack to avoid having to install the BLEPeripheral libarary even if it's
|
||||
* not needed.
|
||||
*/
|
||||
|
||||
BLEStream* BLEStream::_instance = NULL;
|
||||
|
||||
BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) :
|
||||
#if defined(_VARIANT_ARDUINO_101_X_)
|
||||
BLEPeripheral()
|
||||
#else
|
||||
BLEPeripheral(req, rdy, rst)
|
||||
#endif
|
||||
{
|
||||
this->_txCount = 0;
|
||||
this->_rxHead = this->_rxTail = 0;
|
||||
this->_flushed = 0;
|
||||
this->_flushInterval = BLESTREAM_TXBUFFER_FLUSH_INTERVAL;
|
||||
BLEStream::_instance = this;
|
||||
|
||||
addAttribute(this->_uartService);
|
||||
addAttribute(this->_uartNameDescriptor);
|
||||
setAdvertisedServiceUuid(this->_uartService.uuid());
|
||||
addAttribute(this->_rxCharacteristic);
|
||||
addAttribute(this->_rxNameDescriptor);
|
||||
this->_rxCharacteristic.setEventHandler(BLEWritten, BLEStream::_received);
|
||||
addAttribute(this->_txCharacteristic);
|
||||
addAttribute(this->_txNameDescriptor);
|
||||
}
|
||||
|
||||
void BLEStream::begin(...)
|
||||
{
|
||||
BLEPeripheral::begin();
|
||||
#ifdef BLE_SERIAL_DEBUG
|
||||
Serial.println(F("BLEStream::begin()"));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool BLEStream::poll()
|
||||
{
|
||||
// BLEPeripheral::poll is called each time connected() is called
|
||||
this->_connected = BLEPeripheral::connected();
|
||||
if (millis() > this->_flushed + this->_flushInterval) {
|
||||
flush();
|
||||
}
|
||||
return this->_connected;
|
||||
}
|
||||
|
||||
void BLEStream::end()
|
||||
{
|
||||
this->_rxCharacteristic.setEventHandler(BLEWritten, (void(*)(BLECentral&, BLECharacteristic&))NULL);
|
||||
this->_rxHead = this->_rxTail = 0;
|
||||
flush();
|
||||
BLEPeripheral::disconnect();
|
||||
}
|
||||
|
||||
int BLEStream::available(void)
|
||||
{
|
||||
// BLEPeripheral::poll only calls delay(1) in CurieBLE so skipping it here to avoid the delay
|
||||
#ifndef _VARIANT_ARDUINO_101_X_
|
||||
// TODO Need to do more testing to determine if all of these calls to BLEPeripheral::poll are
|
||||
// actually necessary. Seems to run fine without them, but only minimal testing so far.
|
||||
BLEPeripheral::poll();
|
||||
#endif
|
||||
int retval = (this->_rxHead - this->_rxTail + sizeof(this->_rxBuffer)) % sizeof(this->_rxBuffer);
|
||||
#ifdef BLE_SERIAL_DEBUG
|
||||
if (retval > 0) {
|
||||
Serial.print(F("BLEStream::available() = "));
|
||||
Serial.println(retval);
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
int BLEStream::peek(void)
|
||||
{
|
||||
#ifndef _VARIANT_ARDUINO_101_X_
|
||||
BLEPeripheral::poll();
|
||||
#endif
|
||||
if (this->_rxTail == this->_rxHead) return -1;
|
||||
uint8_t byte = this->_rxBuffer[this->_rxTail];
|
||||
#ifdef BLE_SERIAL_DEBUG
|
||||
Serial.print(F("BLEStream::peek() = 0x"));
|
||||
Serial.println(byte, HEX);
|
||||
#endif
|
||||
return byte;
|
||||
}
|
||||
|
||||
int BLEStream::read(void)
|
||||
{
|
||||
#ifndef _VARIANT_ARDUINO_101_X_
|
||||
BLEPeripheral::poll();
|
||||
#endif
|
||||
if (this->_rxTail == this->_rxHead) return -1;
|
||||
this->_rxTail = (this->_rxTail + 1) % sizeof(this->_rxBuffer);
|
||||
uint8_t byte = this->_rxBuffer[this->_rxTail];
|
||||
#ifdef BLE_SERIAL_DEBUG
|
||||
Serial.print(F("BLEStream::read() = 0x"));
|
||||
Serial.println(byte, HEX);
|
||||
#endif
|
||||
return byte;
|
||||
}
|
||||
|
||||
void BLEStream::flush(void)
|
||||
{
|
||||
if (this->_txCount == 0) return;
|
||||
#ifndef _VARIANT_ARDUINO_101_X_
|
||||
// ensure there are available packets before sending
|
||||
while(!this->_txCharacteristic.canNotify()) {
|
||||
BLEPeripheral::poll();
|
||||
}
|
||||
#endif
|
||||
this->_txCharacteristic.setValue(this->_txBuffer, this->_txCount);
|
||||
this->_flushed = millis();
|
||||
this->_txCount = 0;
|
||||
#ifdef BLE_SERIAL_DEBUG
|
||||
Serial.println(F("BLEStream::flush()"));
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t BLEStream::write(uint8_t byte)
|
||||
{
|
||||
#ifndef _VARIANT_ARDUINO_101_X_
|
||||
BLEPeripheral::poll();
|
||||
#endif
|
||||
if (this->_txCharacteristic.subscribed() == false) return 0;
|
||||
this->_txBuffer[this->_txCount++] = byte;
|
||||
if (this->_txCount == sizeof(this->_txBuffer)) flush();
|
||||
#ifdef BLE_SERIAL_DEBUG
|
||||
Serial.print(F("BLEStream::write( 0x"));
|
||||
Serial.print(byte, HEX);
|
||||
Serial.println(F(") = 1"));
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
BLEStream::operator bool()
|
||||
{
|
||||
bool retval = this->_connected = BLEPeripheral::connected();
|
||||
#ifdef BLE_SERIAL_DEBUG
|
||||
Serial.print(F("BLEStream::operator bool() = "));
|
||||
Serial.println(retval);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
void BLEStream::setFlushInterval(int interval)
|
||||
{
|
||||
if (interval > BLESTREAM_MIN_FLUSH_INTERVAL) {
|
||||
this->_flushInterval = interval;
|
||||
}
|
||||
}
|
||||
|
||||
void BLEStream::_received(const unsigned char* data, size_t size)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
this->_rxHead = (this->_rxHead + 1) % sizeof(this->_rxBuffer);
|
||||
this->_rxBuffer[this->_rxHead] = data[i];
|
||||
}
|
||||
#ifdef BLE_SERIAL_DEBUG
|
||||
Serial.print(F("BLEStream::received("));
|
||||
for (int i = 0; i < size; i++) Serial.print(data[i], HEX);
|
||||
Serial.println(F(")"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void BLEStream::_received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic)
|
||||
{
|
||||
BLEStream::_instance->_received(rxCharacteristic.value(), rxCharacteristic.valueLength());
|
||||
}
|
||||
|
||||
|
||||
#endif // _BLE_STREAM_H_
|
||||
@@ -0,0 +1,3 @@
|
||||
/*
|
||||
* Implementation is in BluefruitLE_SPI_Stream.h to avoid linker issues.
|
||||
*/
|
||||
157
arduino/libraries/Firmata/utility/BluefruitLE_SPI_Stream.h
Normal file
157
arduino/libraries/Firmata/utility/BluefruitLE_SPI_Stream.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
BluefruitLE_SPI_Stream.h
|
||||
|
||||
Documentation for the various AT commands used below is available at
|
||||
https://learn.adafruit.com/adafruit-feather-m0-bluefruit-le/at-commands
|
||||
*/
|
||||
|
||||
#ifndef _BLUEFRUIT_LE_SPI_STREAM_H_
|
||||
#define _BLUEFRUIT_LE_SPI_STREAM_H_
|
||||
|
||||
#include <Adafruit_BluefruitLE_SPI.h>
|
||||
|
||||
|
||||
class BluefruitLE_SPI_Stream : public Stream
|
||||
{
|
||||
public:
|
||||
BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin);
|
||||
|
||||
void setLocalName(const char *localName);
|
||||
void setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval);
|
||||
void setFlushInterval(int flushInterval);
|
||||
|
||||
void begin();
|
||||
bool poll();
|
||||
void end();
|
||||
|
||||
// Print overrides
|
||||
size_t write(uint8_t byte);
|
||||
using Print::write; // Expose other write variants
|
||||
|
||||
// Stream overrides
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
|
||||
private:
|
||||
Adafruit_BluefruitLE_SPI ble;
|
||||
|
||||
String localName;
|
||||
unsigned short minConnInterval;
|
||||
unsigned short maxConnInterval;
|
||||
|
||||
uint8_t txBuffer[SDEP_MAX_PACKETSIZE];
|
||||
size_t txCount;
|
||||
};
|
||||
|
||||
|
||||
BluefruitLE_SPI_Stream::BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin) :
|
||||
ble(csPin, irqPin, rstPin),
|
||||
minConnInterval(0),
|
||||
maxConnInterval(0),
|
||||
txCount(0)
|
||||
{ }
|
||||
|
||||
void BluefruitLE_SPI_Stream::setLocalName(const char *localName)
|
||||
{
|
||||
this->localName = localName;
|
||||
}
|
||||
|
||||
void BluefruitLE_SPI_Stream::setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval)
|
||||
{
|
||||
this->minConnInterval = minConnInterval;
|
||||
this->maxConnInterval = maxConnInterval;
|
||||
}
|
||||
|
||||
void BluefruitLE_SPI_Stream::setFlushInterval(int flushInterval)
|
||||
{
|
||||
// Not used
|
||||
}
|
||||
|
||||
void BluefruitLE_SPI_Stream::begin()
|
||||
{
|
||||
// Initialize the SPI interface
|
||||
ble.begin();
|
||||
|
||||
// Perform a factory reset to make sure everything is in a known state
|
||||
ble.factoryReset();
|
||||
|
||||
// Disable command echo from Bluefruit
|
||||
ble.echo(false);
|
||||
|
||||
// Change the MODE LED to indicate BLE UART activity
|
||||
ble.println("AT+HWMODELED=BLEUART");
|
||||
|
||||
// Set local name
|
||||
if (localName.length() > 0) {
|
||||
ble.print("AT+GAPDEVNAME=");
|
||||
ble.println(localName);
|
||||
}
|
||||
|
||||
// Set connection interval
|
||||
if (minConnInterval > 0 && maxConnInterval > 0) {
|
||||
ble.print("AT+GAPINTERVALS=");
|
||||
ble.print(minConnInterval);
|
||||
ble.print(",");
|
||||
ble.print(maxConnInterval);
|
||||
ble.println(",,,");
|
||||
}
|
||||
|
||||
// Disable real and simulated mode switch (i.e. "+++") command
|
||||
ble.println("AT+MODESWITCHEN=local,0");
|
||||
ble.enableModeSwitchCommand(false);
|
||||
|
||||
// Switch to data mode
|
||||
ble.setMode(BLUEFRUIT_MODE_DATA);
|
||||
}
|
||||
|
||||
bool BluefruitLE_SPI_Stream::poll()
|
||||
{
|
||||
// If there's outgoing data in the buffer, just send it. The firmware on
|
||||
// the nRF51822 will decide when to transmit the data in its TX FIFO.
|
||||
if (txCount) flush();
|
||||
|
||||
// In order to check for a connection, we would need to switch from data to
|
||||
// command mode and back again. However, due to the internal workings of
|
||||
// Adafruit_BluefruitLE_SPI, this can lead to unread incoming data being
|
||||
// lost. Therefore, we always return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
void BluefruitLE_SPI_Stream::end()
|
||||
{
|
||||
flush();
|
||||
ble.end();
|
||||
}
|
||||
|
||||
size_t BluefruitLE_SPI_Stream::write(uint8_t byte)
|
||||
{
|
||||
txBuffer[txCount++] = byte;
|
||||
if (txCount == sizeof(txBuffer)) flush();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BluefruitLE_SPI_Stream::available()
|
||||
{
|
||||
return ble.available();
|
||||
}
|
||||
|
||||
int BluefruitLE_SPI_Stream::read()
|
||||
{
|
||||
return ble.read();
|
||||
}
|
||||
|
||||
int BluefruitLE_SPI_Stream::peek()
|
||||
{
|
||||
return ble.peek();
|
||||
}
|
||||
|
||||
void BluefruitLE_SPI_Stream::flush()
|
||||
{
|
||||
ble.write(txBuffer, txCount);
|
||||
txCount = 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // _BLUEFRUIT_LE_SPI_STREAM_H_
|
||||
@@ -0,0 +1,3 @@
|
||||
/*
|
||||
* Implementation is in EthernetClientStream.h to avoid linker issues.
|
||||
*/
|
||||
141
arduino/libraries/Firmata/utility/EthernetClientStream.h
Normal file
141
arduino/libraries/Firmata/utility/EthernetClientStream.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
EthernetClientStream.h
|
||||
An Arduino-Stream that wraps an instance of Client reconnecting to
|
||||
the remote-ip in a transparent way. A disconnected client may be
|
||||
recognized by the returnvalues -1 from calls to peek or read and
|
||||
a 0 from calls to write.
|
||||
|
||||
Copyright (C) 2013 Norbert Truchsess. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
|
||||
Last updated June 18th, 2016
|
||||
*/
|
||||
|
||||
#ifndef ETHERNETCLIENTSTREAM_H
|
||||
#define ETHERNETCLIENTSTREAM_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <Stream.h>
|
||||
|
||||
//#define SERIAL_DEBUG
|
||||
#include "firmataDebug.h"
|
||||
|
||||
#define MILLIS_RECONNECT 5000
|
||||
|
||||
class EthernetClientStream : public Stream
|
||||
{
|
||||
public:
|
||||
EthernetClientStream(Client &client, IPAddress localip, IPAddress ip, const char* host, uint16_t port);
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
size_t write(uint8_t);
|
||||
void maintain(IPAddress localip);
|
||||
|
||||
private:
|
||||
Client &client;
|
||||
IPAddress localip;
|
||||
IPAddress ip;
|
||||
const char* host;
|
||||
uint16_t port;
|
||||
bool connected;
|
||||
uint32_t time_connect;
|
||||
bool maintain();
|
||||
void stop();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* EthernetClientStream.cpp
|
||||
* Copied here as a hack to linker issues with 3rd party board packages that don't properly
|
||||
* implement the Arduino network APIs.
|
||||
*/
|
||||
EthernetClientStream::EthernetClientStream(Client &client, IPAddress localip, IPAddress ip, const char* host, uint16_t port)
|
||||
: client(client),
|
||||
localip(localip),
|
||||
ip(ip),
|
||||
host(host),
|
||||
port(port),
|
||||
connected(false)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
EthernetClientStream::available()
|
||||
{
|
||||
return maintain() ? client.available() : 0;
|
||||
}
|
||||
|
||||
int
|
||||
EthernetClientStream::read()
|
||||
{
|
||||
return maintain() ? client.read() : -1;
|
||||
}
|
||||
|
||||
int
|
||||
EthernetClientStream::peek()
|
||||
{
|
||||
return maintain() ? client.peek() : -1;
|
||||
}
|
||||
|
||||
void EthernetClientStream::flush()
|
||||
{
|
||||
if (maintain())
|
||||
client.flush();
|
||||
}
|
||||
|
||||
size_t
|
||||
EthernetClientStream::write(uint8_t c)
|
||||
{
|
||||
return maintain() ? client.write(c) : 0;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetClientStream::maintain(IPAddress localip)
|
||||
{
|
||||
// ensure the local IP is updated in the case that it is changed by the DHCP server
|
||||
if (this->localip != localip) {
|
||||
this->localip = localip;
|
||||
if (connected)
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EthernetClientStream::stop()
|
||||
{
|
||||
client.stop();
|
||||
connected = false;
|
||||
time_connect = millis();
|
||||
}
|
||||
|
||||
bool
|
||||
EthernetClientStream::maintain()
|
||||
{
|
||||
if (client && client.connected())
|
||||
return true;
|
||||
|
||||
if (connected) {
|
||||
stop();
|
||||
}
|
||||
// if the client is disconnected, attempt to reconnect every 5 seconds
|
||||
else if (millis() - time_connect >= MILLIS_RECONNECT) {
|
||||
connected = host ? client.connect(host, port) : client.connect(ip, port);
|
||||
if (!connected) {
|
||||
time_connect = millis();
|
||||
DEBUG_PRINTLN("Connection failed. Attempting to reconnect...");
|
||||
} else {
|
||||
DEBUG_PRINTLN("Connected");
|
||||
}
|
||||
}
|
||||
return connected;
|
||||
}
|
||||
|
||||
#endif /* ETHERNETCLIENTSTREAM_H */
|
||||
@@ -0,0 +1,3 @@
|
||||
/*
|
||||
* Implementation is in EthernetServerStream.h to avoid linker issues.
|
||||
*/
|
||||
147
arduino/libraries/Firmata/utility/EthernetServerStream.h
Normal file
147
arduino/libraries/Firmata/utility/EthernetServerStream.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
EthernetServerStream.h
|
||||
|
||||
Copyright (C) 2017 Marc Josef Pees. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
|
||||
Last updated July 10th, 2017
|
||||
*/
|
||||
|
||||
#ifndef ETHERNETSERVERSTREAM_H
|
||||
#define ETHERNETSERVERSTREAM_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <Stream.h>
|
||||
#include <Ethernet.h>
|
||||
|
||||
//#define SERIAL_DEBUG
|
||||
#include "firmataDebug.h"
|
||||
|
||||
class EthernetServerStream : public Stream
|
||||
{
|
||||
public:
|
||||
EthernetServerStream(IPAddress localip, uint16_t port);
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
size_t write(uint8_t);
|
||||
void maintain(IPAddress localip);
|
||||
|
||||
private:
|
||||
EthernetClient client;
|
||||
IPAddress localip;
|
||||
uint16_t port;
|
||||
bool connected;
|
||||
bool maintain();
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
EthernetServer server = EthernetServer(3030);
|
||||
bool listening = false;
|
||||
bool connect_client();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* EthernetServerStream.cpp
|
||||
* Copied here as a hack to linker issues with 3rd party board packages that don't properly
|
||||
* implement the Arduino network APIs.
|
||||
*/
|
||||
EthernetServerStream::EthernetServerStream(IPAddress localip, uint16_t port)
|
||||
: localip(localip),
|
||||
port(port),
|
||||
connected(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool EthernetServerStream::connect_client()
|
||||
{
|
||||
if ( connected )
|
||||
{
|
||||
if ( client && client.connected() ) return true;
|
||||
stop();
|
||||
}
|
||||
|
||||
EthernetClient newClient = server.available();
|
||||
if ( !newClient ) return false;
|
||||
client = newClient;
|
||||
connected = true;
|
||||
DEBUG_PRINTLN("Connected");
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
EthernetServerStream::available()
|
||||
{
|
||||
return maintain() ? client.available() : 0;
|
||||
}
|
||||
|
||||
int
|
||||
EthernetServerStream::read()
|
||||
{
|
||||
return maintain() ? client.read() : -1;
|
||||
}
|
||||
|
||||
int
|
||||
EthernetServerStream::peek()
|
||||
{
|
||||
return maintain() ? client.peek() : -1;
|
||||
}
|
||||
|
||||
void EthernetServerStream::flush()
|
||||
{
|
||||
if (maintain())
|
||||
client.flush();
|
||||
}
|
||||
|
||||
size_t
|
||||
EthernetServerStream::write(uint8_t c)
|
||||
{
|
||||
return maintain() ? client.write(c) : 0;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetServerStream::maintain(IPAddress localip)
|
||||
{
|
||||
// ensure the local IP is updated in the case that it is changed by the DHCP server
|
||||
if (this->localip != localip) {
|
||||
this->localip = localip;
|
||||
if (connected)
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EthernetServerStream::stop()
|
||||
{
|
||||
if(client)
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
connected = false;
|
||||
}
|
||||
|
||||
bool
|
||||
EthernetServerStream::maintain()
|
||||
{
|
||||
if (connect_client()) return true;
|
||||
|
||||
stop();
|
||||
|
||||
if(!listening)
|
||||
{
|
||||
server = EthernetServer(port);
|
||||
server.begin();
|
||||
listening = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* ETHERNETSERVERSTREAM_H */
|
||||
38
arduino/libraries/Firmata/utility/FirmataFeature.h
Normal file
38
arduino/libraries/Firmata/utility/FirmataFeature.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
FirmataFeature.h
|
||||
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
|
||||
Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
|
||||
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
|
||||
Copyright (C) 2013 Norbert Truchsess. All rights reserved.
|
||||
Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
Interface for Firmata feature classes.
|
||||
|
||||
This version of FirmataFeature.h differs from the ConfigurableFirmata
|
||||
version in the following ways:
|
||||
|
||||
- Imports Firmata.h rather than ConfigurableFirmata.h
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
*/
|
||||
|
||||
#ifndef FirmataFeature_h
|
||||
#define FirmataFeature_h
|
||||
|
||||
#include <Firmata.h>
|
||||
|
||||
class FirmataFeature
|
||||
{
|
||||
public:
|
||||
virtual void handleCapability(byte pin) = 0;
|
||||
virtual boolean handlePinMode(byte pin, int mode) = 0;
|
||||
virtual boolean handleSysex(byte command, byte argc, byte* argv) = 0;
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
342
arduino/libraries/Firmata/utility/SerialFirmata.cpp
Normal file
342
arduino/libraries/Firmata/utility/SerialFirmata.cpp
Normal file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
SerialFirmata.cpp
|
||||
Copyright (C) 2016 Jeff Hoefs. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
|
||||
This version of SerialFirmata.cpp differs from the ConfigurableFirmata
|
||||
version in the following ways:
|
||||
|
||||
- handlePinMode calls Firmata::setPinMode
|
||||
|
||||
Last updated October 16th, 2016
|
||||
*/
|
||||
|
||||
#include "SerialFirmata.h"
|
||||
|
||||
SerialFirmata::SerialFirmata()
|
||||
{
|
||||
#if defined(SoftwareSerial_h)
|
||||
swSerial0 = NULL;
|
||||
swSerial1 = NULL;
|
||||
swSerial2 = NULL;
|
||||
swSerial3 = NULL;
|
||||
#endif
|
||||
|
||||
serialIndex = -1;
|
||||
}
|
||||
|
||||
boolean SerialFirmata::handlePinMode(byte pin, int mode)
|
||||
{
|
||||
// used for both HW and SW serial
|
||||
if (mode == PIN_MODE_SERIAL) {
|
||||
Firmata.setPinMode(pin, PIN_MODE_SERIAL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SerialFirmata::handleCapability(byte pin)
|
||||
{
|
||||
if (IS_PIN_SERIAL(pin)) {
|
||||
Firmata.write(PIN_MODE_SERIAL);
|
||||
Firmata.write(getSerialPinType(pin));
|
||||
}
|
||||
}
|
||||
|
||||
boolean SerialFirmata::handleSysex(byte command, byte argc, byte *argv)
|
||||
{
|
||||
if (command == SERIAL_MESSAGE) {
|
||||
|
||||
Stream *serialPort;
|
||||
byte mode = argv[0] & SERIAL_MODE_MASK;
|
||||
byte portId = argv[0] & SERIAL_PORT_ID_MASK;
|
||||
|
||||
switch (mode) {
|
||||
case SERIAL_CONFIG:
|
||||
{
|
||||
long baud = (long)argv[1] | ((long)argv[2] << 7) | ((long)argv[3] << 14);
|
||||
serial_pins pins;
|
||||
|
||||
if (portId < 8) {
|
||||
serialPort = getPortFromId(portId);
|
||||
if (serialPort != NULL) {
|
||||
pins = getSerialPinNumbers(portId);
|
||||
if (pins.rx != 0 && pins.tx != 0) {
|
||||
Firmata.setPinMode(pins.rx, PIN_MODE_SERIAL);
|
||||
Firmata.setPinMode(pins.tx, PIN_MODE_SERIAL);
|
||||
// Fixes an issue where some serial devices would not work properly with Arduino Due
|
||||
// because all Arduino pins are set to OUTPUT by default in StandardFirmata.
|
||||
pinMode(pins.rx, INPUT);
|
||||
}
|
||||
((HardwareSerial*)serialPort)->begin(baud);
|
||||
}
|
||||
} else {
|
||||
#if defined(SoftwareSerial_h)
|
||||
byte swTxPin, swRxPin;
|
||||
if (argc > 4) {
|
||||
swRxPin = argv[4];
|
||||
swTxPin = argv[5];
|
||||
} else {
|
||||
// RX and TX pins must be specified when using SW serial
|
||||
Firmata.sendString("Specify serial RX and TX pins");
|
||||
return false;
|
||||
}
|
||||
switch (portId) {
|
||||
case SW_SERIAL0:
|
||||
if (swSerial0 == NULL) {
|
||||
swSerial0 = new SoftwareSerial(swRxPin, swTxPin);
|
||||
}
|
||||
break;
|
||||
case SW_SERIAL1:
|
||||
if (swSerial1 == NULL) {
|
||||
swSerial1 = new SoftwareSerial(swRxPin, swTxPin);
|
||||
}
|
||||
break;
|
||||
case SW_SERIAL2:
|
||||
if (swSerial2 == NULL) {
|
||||
swSerial2 = new SoftwareSerial(swRxPin, swTxPin);
|
||||
}
|
||||
break;
|
||||
case SW_SERIAL3:
|
||||
if (swSerial3 == NULL) {
|
||||
swSerial3 = new SoftwareSerial(swRxPin, swTxPin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
serialPort = getPortFromId(portId);
|
||||
if (serialPort != NULL) {
|
||||
Firmata.setPinMode(swRxPin, PIN_MODE_SERIAL);
|
||||
Firmata.setPinMode(swTxPin, PIN_MODE_SERIAL);
|
||||
((SoftwareSerial*)serialPort)->begin(baud);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break; // SERIAL_CONFIG
|
||||
}
|
||||
case SERIAL_WRITE:
|
||||
{
|
||||
byte data;
|
||||
serialPort = getPortFromId(portId);
|
||||
if (serialPort == NULL) {
|
||||
break;
|
||||
}
|
||||
for (byte i = 1; i < argc; i += 2) {
|
||||
data = argv[i] + (argv[i + 1] << 7);
|
||||
serialPort->write(data);
|
||||
}
|
||||
break; // SERIAL_WRITE
|
||||
}
|
||||
case SERIAL_READ:
|
||||
if (argv[1] == SERIAL_READ_CONTINUOUSLY) {
|
||||
if (serialIndex + 1 >= MAX_SERIAL_PORTS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
// maximum number of bytes to read from buffer per iteration of loop()
|
||||
serialBytesToRead[portId] = (int)argv[2] | ((int)argv[3] << 7);
|
||||
} else {
|
||||
// read all available bytes per iteration of loop()
|
||||
serialBytesToRead[portId] = 0;
|
||||
}
|
||||
serialIndex++;
|
||||
reportSerial[serialIndex] = portId;
|
||||
} else if (argv[1] == SERIAL_STOP_READING) {
|
||||
byte serialIndexToSkip = 0;
|
||||
if (serialIndex <= 0) {
|
||||
serialIndex = -1;
|
||||
} else {
|
||||
for (byte i = 0; i < serialIndex + 1; i++) {
|
||||
if (reportSerial[i] == portId) {
|
||||
serialIndexToSkip = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// shift elements over to fill space left by removed element
|
||||
for (byte i = serialIndexToSkip; i < serialIndex + 1; i++) {
|
||||
if (i < MAX_SERIAL_PORTS) {
|
||||
reportSerial[i] = reportSerial[i + 1];
|
||||
}
|
||||
}
|
||||
serialIndex--;
|
||||
}
|
||||
}
|
||||
break; // SERIAL_READ
|
||||
case SERIAL_CLOSE:
|
||||
serialPort = getPortFromId(portId);
|
||||
if (serialPort != NULL) {
|
||||
if (portId < 8) {
|
||||
((HardwareSerial*)serialPort)->end();
|
||||
} else {
|
||||
#if defined(SoftwareSerial_h)
|
||||
((SoftwareSerial*)serialPort)->end();
|
||||
if (serialPort != NULL) {
|
||||
free(serialPort);
|
||||
serialPort = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break; // SERIAL_CLOSE
|
||||
case SERIAL_FLUSH:
|
||||
serialPort = getPortFromId(portId);
|
||||
if (serialPort != NULL) {
|
||||
getPortFromId(portId)->flush();
|
||||
}
|
||||
break; // SERIAL_FLUSH
|
||||
#if defined(SoftwareSerial_h)
|
||||
case SERIAL_LISTEN:
|
||||
// can only call listen() on software serial ports
|
||||
if (portId > 7) {
|
||||
serialPort = getPortFromId(portId);
|
||||
if (serialPort != NULL) {
|
||||
((SoftwareSerial*)serialPort)->listen();
|
||||
}
|
||||
}
|
||||
break; // SERIAL_LISTEN
|
||||
#endif
|
||||
} // end switch
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SerialFirmata::update()
|
||||
{
|
||||
checkSerial();
|
||||
}
|
||||
|
||||
void SerialFirmata::reset()
|
||||
{
|
||||
#if defined(SoftwareSerial_h)
|
||||
Stream *serialPort;
|
||||
// free memory allocated for SoftwareSerial ports
|
||||
for (byte i = SW_SERIAL0; i < SW_SERIAL3 + 1; i++) {
|
||||
serialPort = getPortFromId(i);
|
||||
if (serialPort != NULL) {
|
||||
free(serialPort);
|
||||
serialPort = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
serialIndex = -1;
|
||||
for (byte i = 0; i < SERIAL_READ_ARR_LEN; i++) {
|
||||
serialBytesToRead[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// get a pointer to the serial port associated with the specified port id
|
||||
Stream* SerialFirmata::getPortFromId(byte portId)
|
||||
{
|
||||
switch (portId) {
|
||||
case HW_SERIAL0:
|
||||
// block use of Serial (typically pins 0 and 1) until ability to reclaim Serial is implemented
|
||||
//return &Serial;
|
||||
return NULL;
|
||||
#if defined(PIN_SERIAL1_RX)
|
||||
case HW_SERIAL1:
|
||||
return &Serial1;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL2_RX)
|
||||
case HW_SERIAL2:
|
||||
return &Serial2;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL3_RX)
|
||||
case HW_SERIAL3:
|
||||
return &Serial3;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL4_RX)
|
||||
case HW_SERIAL4:
|
||||
return &Serial4;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL5_RX)
|
||||
case HW_SERIAL5:
|
||||
return &Serial5;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL6_RX)
|
||||
case HW_SERIAL6:
|
||||
return &Serial6;
|
||||
#endif
|
||||
#if defined(SoftwareSerial_h)
|
||||
case SW_SERIAL0:
|
||||
if (swSerial0 != NULL) {
|
||||
// instances of SoftwareSerial are already pointers so simply return the instance
|
||||
return swSerial0;
|
||||
}
|
||||
break;
|
||||
case SW_SERIAL1:
|
||||
if (swSerial1 != NULL) {
|
||||
return swSerial1;
|
||||
}
|
||||
break;
|
||||
case SW_SERIAL2:
|
||||
if (swSerial2 != NULL) {
|
||||
return swSerial2;
|
||||
}
|
||||
break;
|
||||
case SW_SERIAL3:
|
||||
if (swSerial3 != NULL) {
|
||||
return swSerial3;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check serial ports that have READ_CONTINUOUS mode set and relay any data
|
||||
// for each port to the device attached to that port.
|
||||
void SerialFirmata::checkSerial()
|
||||
{
|
||||
byte portId, serialData;
|
||||
int bytesToRead = 0;
|
||||
int numBytesToRead = 0;
|
||||
Stream* serialPort;
|
||||
|
||||
if (serialIndex > -1) {
|
||||
|
||||
// loop through all reporting (READ_CONTINUOUS) serial ports
|
||||
for (byte i = 0; i < serialIndex + 1; i++) {
|
||||
portId = reportSerial[i];
|
||||
bytesToRead = serialBytesToRead[portId];
|
||||
serialPort = getPortFromId(portId);
|
||||
if (serialPort == NULL) {
|
||||
continue;
|
||||
}
|
||||
#if defined(SoftwareSerial_h)
|
||||
// only the SoftwareSerial port that is "listening" can read data
|
||||
if (portId > 7 && !((SoftwareSerial*)serialPort)->isListening()) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (serialPort->available() > 0) {
|
||||
Firmata.write(START_SYSEX);
|
||||
Firmata.write(SERIAL_MESSAGE);
|
||||
Firmata.write(SERIAL_REPLY | portId);
|
||||
|
||||
if (bytesToRead == 0 || (serialPort->available() <= bytesToRead)) {
|
||||
numBytesToRead = serialPort->available();
|
||||
} else {
|
||||
numBytesToRead = bytesToRead;
|
||||
}
|
||||
|
||||
// relay serial data to the serial device
|
||||
while (numBytesToRead > 0) {
|
||||
serialData = serialPort->read();
|
||||
Firmata.write(serialData & 0x7F);
|
||||
Firmata.write((serialData >> 7) & 0x7F);
|
||||
numBytesToRead--;
|
||||
}
|
||||
Firmata.write(END_SYSEX);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
208
arduino/libraries/Firmata/utility/SerialFirmata.h
Normal file
208
arduino/libraries/Firmata/utility/SerialFirmata.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
SerialFirmata.h
|
||||
Copyright (C) 2016 Jeff Hoefs. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
|
||||
This version of SerialFirmata.h differs from the ConfigurableFirmata
|
||||
version in the following ways:
|
||||
|
||||
- Defines FIRMATA_SERIAL_FEATURE (could add to Configurable version as well)
|
||||
- Imports Firmata.h rather than ConfigurableFirmata.h
|
||||
|
||||
Last updated October 16th, 2016
|
||||
*/
|
||||
|
||||
#ifndef SerialFirmata_h
|
||||
#define SerialFirmata_h
|
||||
|
||||
#include <Firmata.h>
|
||||
#include "FirmataFeature.h"
|
||||
// SoftwareSerial is currently only supported for AVR-based boards and the Arduino 101.
|
||||
// Limited to Arduino 1.6.6 or higher because Arduino builder cannot find SoftwareSerial
|
||||
// prior to this release.
|
||||
#if (ARDUINO > 10605) && (defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ARC32))
|
||||
#include <SoftwareSerial.h>
|
||||
#endif
|
||||
|
||||
#define FIRMATA_SERIAL_FEATURE
|
||||
|
||||
// Serial port Ids
|
||||
#define HW_SERIAL0 0x00
|
||||
#define HW_SERIAL1 0x01
|
||||
#define HW_SERIAL2 0x02
|
||||
#define HW_SERIAL3 0x03
|
||||
#define HW_SERIAL4 0x04
|
||||
#define HW_SERIAL5 0x05
|
||||
#define HW_SERIAL6 0x06
|
||||
// extensible up to 0x07
|
||||
|
||||
#define SW_SERIAL0 0x08
|
||||
#define SW_SERIAL1 0x09
|
||||
#define SW_SERIAL2 0x0A
|
||||
#define SW_SERIAL3 0x0B
|
||||
// extensible up to 0x0F
|
||||
|
||||
#define SERIAL_PORT_ID_MASK 0x0F
|
||||
#define MAX_SERIAL_PORTS 8
|
||||
#define SERIAL_READ_ARR_LEN 12
|
||||
|
||||
// map configuration query response resolution value to serial pin type
|
||||
#define RES_RX1 0x02
|
||||
#define RES_TX1 0x03
|
||||
#define RES_RX2 0x04
|
||||
#define RES_TX2 0x05
|
||||
#define RES_RX3 0x06
|
||||
#define RES_TX3 0x07
|
||||
#define RES_RX4 0x08
|
||||
#define RES_TX4 0x09
|
||||
#define RES_RX5 0x0a
|
||||
#define RES_TX5 0x0b
|
||||
#define RES_RX6 0x0c
|
||||
#define RES_TX6 0x0d
|
||||
|
||||
// Serial command bytes
|
||||
#define SERIAL_CONFIG 0x10
|
||||
#define SERIAL_WRITE 0x20
|
||||
#define SERIAL_READ 0x30
|
||||
#define SERIAL_REPLY 0x40
|
||||
#define SERIAL_CLOSE 0x50
|
||||
#define SERIAL_FLUSH 0x60
|
||||
#define SERIAL_LISTEN 0x70
|
||||
|
||||
// Serial read modes
|
||||
#define SERIAL_READ_CONTINUOUSLY 0x00
|
||||
#define SERIAL_STOP_READING 0x01
|
||||
#define SERIAL_MODE_MASK 0xF0
|
||||
|
||||
namespace {
|
||||
|
||||
struct serial_pins {
|
||||
uint8_t rx;
|
||||
uint8_t tx;
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the serial serial pin type (RX1, TX1, RX2, TX2, etc) for the specified pin.
|
||||
*/
|
||||
inline uint8_t getSerialPinType(uint8_t pin) {
|
||||
#if defined(PIN_SERIAL_RX)
|
||||
// TODO when use of HW_SERIAL0 is enabled
|
||||
#endif
|
||||
#if defined(PIN_SERIAL1_RX)
|
||||
if (pin == PIN_SERIAL1_RX) return RES_RX1;
|
||||
if (pin == PIN_SERIAL1_TX) return RES_TX1;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL2_RX)
|
||||
if (pin == PIN_SERIAL2_RX) return RES_RX2;
|
||||
if (pin == PIN_SERIAL2_TX) return RES_TX2;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL3_RX)
|
||||
if (pin == PIN_SERIAL3_RX) return RES_RX3;
|
||||
if (pin == PIN_SERIAL3_TX) return RES_TX3;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL4_RX)
|
||||
if (pin == PIN_SERIAL4_RX) return RES_RX4;
|
||||
if (pin == PIN_SERIAL4_TX) return RES_TX4;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL5_RX)
|
||||
if (pin == PIN_SERIAL5_RX) return RES_RX5;
|
||||
if (pin == PIN_SERIAL5_TX) return RES_TX5;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL6_RX)
|
||||
if (pin == PIN_SERIAL6_RX) return RES_RX6;
|
||||
if (pin == PIN_SERIAL6_TX) return RES_TX6;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the RX and TX pins numbers for the specified HW serial port.
|
||||
*/
|
||||
inline serial_pins getSerialPinNumbers(uint8_t portId) {
|
||||
serial_pins pins;
|
||||
switch (portId) {
|
||||
#if defined(PIN_SERIAL_RX)
|
||||
// case HW_SERIAL0:
|
||||
// // TODO when use of HW_SERIAL0 is enabled
|
||||
// break;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL1_RX)
|
||||
case HW_SERIAL1:
|
||||
pins.rx = PIN_SERIAL1_RX;
|
||||
pins.tx = PIN_SERIAL1_TX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL2_RX)
|
||||
case HW_SERIAL2:
|
||||
pins.rx = PIN_SERIAL2_RX;
|
||||
pins.tx = PIN_SERIAL2_TX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL3_RX)
|
||||
case HW_SERIAL3:
|
||||
pins.rx = PIN_SERIAL3_RX;
|
||||
pins.tx = PIN_SERIAL3_TX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL4_RX)
|
||||
case HW_SERIAL4:
|
||||
pins.rx = PIN_SERIAL4_RX;
|
||||
pins.tx = PIN_SERIAL4_TX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL5_RX)
|
||||
case HW_SERIAL5:
|
||||
pins.rx = PIN_SERIAL5_RX;
|
||||
pins.tx = PIN_SERIAL5_TX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PIN_SERIAL6_RX)
|
||||
case HW_SERIAL6:
|
||||
pins.rx = PIN_SERIAL6_RX;
|
||||
pins.tx = PIN_SERIAL6_TX;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
pins.rx = 0;
|
||||
pins.tx = 0;
|
||||
}
|
||||
return pins;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
|
||||
class SerialFirmata: public FirmataFeature
|
||||
{
|
||||
public:
|
||||
SerialFirmata();
|
||||
boolean handlePinMode(byte pin, int mode);
|
||||
void handleCapability(byte pin);
|
||||
boolean handleSysex(byte command, byte argc, byte* argv);
|
||||
void update();
|
||||
void reset();
|
||||
void checkSerial();
|
||||
|
||||
private:
|
||||
byte reportSerial[MAX_SERIAL_PORTS];
|
||||
int serialBytesToRead[SERIAL_READ_ARR_LEN];
|
||||
signed char serialIndex;
|
||||
|
||||
#if defined(SoftwareSerial_h)
|
||||
Stream *swSerial0;
|
||||
Stream *swSerial1;
|
||||
Stream *swSerial2;
|
||||
Stream *swSerial3;
|
||||
#endif
|
||||
|
||||
Stream* getPortFromId(byte portId);
|
||||
|
||||
};
|
||||
|
||||
#endif /* SerialFirmata_h */
|
||||
105
arduino/libraries/Firmata/utility/WiFiClientStream.h
Normal file
105
arduino/libraries/Firmata/utility/WiFiClientStream.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
WiFiClientStream.h
|
||||
|
||||
An Arduino Stream that wraps an instance of a WiFiClient. For use
|
||||
with legacy Arduino WiFi shield and other boards and shields that
|
||||
are compatible with the Arduino WiFi library.
|
||||
|
||||
Copyright (C) 2016 Jens B. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
|
||||
Parts of this class are based on
|
||||
|
||||
- EthernetClientStream - Copyright (C) 2013 Norbert Truchsess. All rights reserved.
|
||||
|
||||
published under the same license.
|
||||
|
||||
Last updated April 23rd, 2016
|
||||
*/
|
||||
|
||||
#ifndef WIFI_CLIENT_STREAM_H
|
||||
#define WIFI_CLIENT_STREAM_H
|
||||
|
||||
#include "WiFiStream.h"
|
||||
|
||||
#define MILLIS_RECONNECT 5000
|
||||
|
||||
class WiFiClientStream : public WiFiStream
|
||||
{
|
||||
protected:
|
||||
uint32_t _time_connect = 0;
|
||||
|
||||
/**
|
||||
* check if TCP client is connected
|
||||
* @return true if connected
|
||||
*/
|
||||
virtual inline bool connect_client()
|
||||
{
|
||||
if ( _connected )
|
||||
{
|
||||
if ( _client && _client.connected() ) return true;
|
||||
stop();
|
||||
}
|
||||
|
||||
// active TCP connect
|
||||
if ( WiFi.status() == WL_CONNECTED )
|
||||
{
|
||||
// if the client is disconnected, try to reconnect every 5 seconds
|
||||
if ( millis() - _time_connect >= MILLIS_RECONNECT )
|
||||
{
|
||||
_connected = _client.connect( _remote_ip, _port );
|
||||
if ( !_connected )
|
||||
{
|
||||
_time_connect = millis();
|
||||
}
|
||||
else if ( _currentHostConnectionCallback )
|
||||
{
|
||||
(*_currentHostConnectionCallback)(HOST_CONNECTION_CONNECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _connected;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* create a WiFi stream with a TCP client
|
||||
*/
|
||||
WiFiClientStream(IPAddress server_ip, uint16_t server_port) : WiFiStream(server_ip, server_port) {}
|
||||
|
||||
/**
|
||||
* maintain WiFi and TCP connection
|
||||
* @return true if WiFi and TCP connection are established
|
||||
*/
|
||||
virtual inline bool maintain()
|
||||
{
|
||||
return connect_client();
|
||||
}
|
||||
|
||||
/**
|
||||
* stop client connection
|
||||
*/
|
||||
virtual inline void stop()
|
||||
{
|
||||
if ( _client)
|
||||
{
|
||||
_client.stop();
|
||||
if ( _currentHostConnectionCallback )
|
||||
{
|
||||
(*_currentHostConnectionCallback)(HOST_CONNECTION_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
_connected = false;
|
||||
_time_connect = millis();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //WIFI_CLIENT_STREAM_H
|
||||
107
arduino/libraries/Firmata/utility/WiFiServerStream.h
Normal file
107
arduino/libraries/Firmata/utility/WiFiServerStream.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
WiFiServerStream.h
|
||||
|
||||
An Arduino Stream extension for a WiFiClient or WiFiServer to be used
|
||||
with legacy Arduino WiFi shield and other boards and shields that
|
||||
are compatible with the Arduino WiFi library.
|
||||
|
||||
Copyright (C) 2016 Jens B. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
|
||||
Parts of this class are based on
|
||||
|
||||
- WiFiStream - Copyright (C) 2015-2016 Jesse Frush. All rights reserved.
|
||||
|
||||
published under the same license.
|
||||
|
||||
Last updated April 23rd, 2016
|
||||
*/
|
||||
|
||||
#ifndef WIFI_SERVER_STREAM_H
|
||||
#define WIFI_SERVER_STREAM_H
|
||||
|
||||
#include "WiFiStream.h"
|
||||
|
||||
class WiFiServerStream : public WiFiStream
|
||||
{
|
||||
protected:
|
||||
WiFiServer _server = WiFiServer(3030);
|
||||
bool _listening = false;
|
||||
|
||||
/**
|
||||
* check if TCP client is connected
|
||||
* @return true if connected
|
||||
*/
|
||||
virtual inline bool connect_client()
|
||||
{
|
||||
if ( _connected )
|
||||
{
|
||||
if ( _client && _client.connected() ) return true;
|
||||
stop();
|
||||
}
|
||||
|
||||
// passive TCP connect (accept)
|
||||
WiFiClient newClient = _server.available();
|
||||
if ( !newClient ) return false;
|
||||
_client = newClient;
|
||||
_connected = true;
|
||||
if ( _currentHostConnectionCallback )
|
||||
{
|
||||
(*_currentHostConnectionCallback)(HOST_CONNECTION_CONNECTED);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* create a WiFi stream with a TCP server
|
||||
*/
|
||||
WiFiServerStream(uint16_t server_port) : WiFiStream(server_port) {}
|
||||
|
||||
/**
|
||||
* maintain WiFi and TCP connection
|
||||
* @return true if WiFi and TCP connection are established
|
||||
*/
|
||||
virtual inline bool maintain()
|
||||
{
|
||||
if ( connect_client() ) return true;
|
||||
|
||||
stop();
|
||||
|
||||
if ( !_listening && WiFi.status() == WL_CONNECTED )
|
||||
{
|
||||
// start TCP server after first WiFi connect
|
||||
_server = WiFiServer(_port);
|
||||
_server.begin();
|
||||
_listening = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* stop client connection
|
||||
*/
|
||||
virtual inline void stop()
|
||||
{
|
||||
if ( _client)
|
||||
{
|
||||
_client.stop();
|
||||
if ( _currentHostConnectionCallback )
|
||||
{
|
||||
(*_currentHostConnectionCallback)(HOST_CONNECTION_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
_connected = false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //WIFI_SERVER_STREAM_H
|
||||
4
arduino/libraries/Firmata/utility/WiFiStream.cpp
Normal file
4
arduino/libraries/Firmata/utility/WiFiStream.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
* Implementation is in WiFiStream.h to avoid linker issues. Legacy WiFi and modern WiFi101 both define WiFiClass which
|
||||
* will cause linker errors whenever Firmata.h is included.
|
||||
*/
|
||||
226
arduino/libraries/Firmata/utility/WiFiStream.h
Normal file
226
arduino/libraries/Firmata/utility/WiFiStream.h
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
WiFiStream.h
|
||||
|
||||
An Arduino Stream extension for a WiFiClient or WiFiServer to be used
|
||||
with legacy Arduino WiFi shield and other boards and shields that
|
||||
are compatible with the Arduino WiFi library.
|
||||
|
||||
Copyright (C) 2015-2016 Jesse Frush. All rights reserved.
|
||||
Copyright (C) 2016 Jens B. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
|
||||
Last updated April 23rd, 2016
|
||||
*/
|
||||
|
||||
#ifndef WIFI_STREAM_H
|
||||
#define WIFI_STREAM_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <Stream.h>
|
||||
|
||||
#define HOST_CONNECTION_DISCONNECTED 0
|
||||
#define HOST_CONNECTION_CONNECTED 1
|
||||
|
||||
extern "C" {
|
||||
// callback function types
|
||||
typedef void (*hostConnectionCallbackFunction)(byte);
|
||||
}
|
||||
|
||||
class WiFiStream : public Stream
|
||||
{
|
||||
protected:
|
||||
WiFiClient _client;
|
||||
bool _connected = false;
|
||||
hostConnectionCallbackFunction _currentHostConnectionCallback;
|
||||
|
||||
//configuration members
|
||||
IPAddress _local_ip; // DHCP
|
||||
IPAddress _subnet;
|
||||
IPAddress _gateway;
|
||||
IPAddress _remote_ip;
|
||||
uint16_t _port;
|
||||
uint8_t _key_idx; //WEP
|
||||
const char *_key = nullptr; //WEP
|
||||
const char *_passphrase = nullptr; //WPA
|
||||
char *_ssid = nullptr;
|
||||
|
||||
/**
|
||||
* check if TCP client is connected
|
||||
* @return true if connected
|
||||
*/
|
||||
virtual bool connect_client() = 0;
|
||||
|
||||
public:
|
||||
/** constructor for TCP server */
|
||||
WiFiStream(uint16_t server_port) : _port(server_port) {}
|
||||
|
||||
/** constructor for TCP client */
|
||||
WiFiStream(IPAddress server_ip, uint16_t server_port) : _remote_ip(server_ip), _port(server_port) {}
|
||||
|
||||
inline void attach( hostConnectionCallbackFunction newFunction ) { _currentHostConnectionCallback = newFunction; }
|
||||
|
||||
/******************************************************************************
|
||||
* network configuration
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ESP8266
|
||||
/**
|
||||
* configure a static local IP address without defining the local network
|
||||
* DHCP will be used as long as local IP address is not defined
|
||||
*/
|
||||
inline void config(IPAddress local_ip)
|
||||
{
|
||||
_local_ip = local_ip;
|
||||
WiFi.config( local_ip );
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* configure a static local IP address
|
||||
* DHCP will be used as long as local IP address is not defined
|
||||
*/
|
||||
inline void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
_local_ip = local_ip;
|
||||
_subnet = subnet;
|
||||
_gateway = gateway;
|
||||
#ifndef ESP8266
|
||||
WiFi.config( local_ip, IPAddress(0, 0, 0, 0), gateway, subnet );
|
||||
#else
|
||||
WiFi.config( local_ip, gateway, subnet );
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @return local IP address
|
||||
*/
|
||||
inline IPAddress getLocalIP()
|
||||
{
|
||||
return WiFi.localIP();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* network functions
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* maintain WiFi and TCP connection
|
||||
* @return true if WiFi and TCP connection are established
|
||||
*/
|
||||
virtual bool maintain() = 0;
|
||||
|
||||
#ifdef ESP8266
|
||||
/**
|
||||
* get status of TCP connection
|
||||
* @return status of TCP connection
|
||||
* CLOSED = 0 (typical)
|
||||
* LISTEN = 1 (not used)
|
||||
* SYN_SENT = 2
|
||||
* SYN_RCVD = 3
|
||||
* ESTABLISHED = 4 (typical)
|
||||
* FIN_WAIT_1 = 5
|
||||
* FIN_WAIT_2 = 6
|
||||
* CLOSE_WAIT = 7
|
||||
* CLOSING = 8
|
||||
* LAST_ACK = 9
|
||||
* TIME_WAIT = 10
|
||||
*/
|
||||
inline uint8_t status()
|
||||
{
|
||||
return _client.status();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* close TCP client connection
|
||||
*/
|
||||
virtual void stop() = 0;
|
||||
|
||||
/******************************************************************************
|
||||
* WiFi configuration
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* initialize WiFi without security (open) and initiate client connection
|
||||
* if WiFi connection is already established
|
||||
* @return WL_CONNECTED if WiFi connection is established
|
||||
*/
|
||||
inline int begin(char *ssid)
|
||||
{
|
||||
_ssid = ssid;
|
||||
|
||||
WiFi.begin(ssid);
|
||||
int result = WiFi.status();
|
||||
return WiFi.status();
|
||||
}
|
||||
|
||||
#ifndef ESP8266
|
||||
/**
|
||||
* initialize WiFi with WEP security and initiate client connection
|
||||
* if WiFi connection is already established
|
||||
* @return WL_CONNECTED if WiFi connection is established
|
||||
*/
|
||||
inline int begin(char *ssid, uint8_t key_idx, const char *key)
|
||||
{
|
||||
_ssid = ssid;
|
||||
_key_idx = key_idx;
|
||||
_key = key;
|
||||
|
||||
WiFi.begin( ssid, key_idx, key );
|
||||
return WiFi.status();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* initialize WiFi with WPA-PSK security and initiate client connection
|
||||
* if WiFi connection is already established
|
||||
* @return WL_CONNECTED if WiFi connection is established
|
||||
*/
|
||||
inline int begin(char *ssid, const char *passphrase)
|
||||
{
|
||||
_ssid = ssid;
|
||||
_passphrase = passphrase;
|
||||
|
||||
WiFi.begin(ssid, passphrase);
|
||||
return WiFi.status();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* stream functions
|
||||
******************************************************************************/
|
||||
|
||||
inline int available()
|
||||
{
|
||||
return connect_client() ? _client.available() : 0;
|
||||
}
|
||||
|
||||
inline void flush()
|
||||
{
|
||||
if( _client ) _client.flush();
|
||||
}
|
||||
|
||||
inline int peek()
|
||||
{
|
||||
return connect_client() ? _client.peek(): 0;
|
||||
}
|
||||
|
||||
inline int read()
|
||||
{
|
||||
return connect_client() ? _client.read() : -1;
|
||||
}
|
||||
|
||||
inline size_t write(uint8_t byte)
|
||||
{
|
||||
return connect_client() ? _client.write( byte ) : 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //WIFI_STREAM_H
|
||||
14
arduino/libraries/Firmata/utility/firmataDebug.h
Normal file
14
arduino/libraries/Firmata/utility/firmataDebug.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef FIRMATA_DEBUG_H
|
||||
#define FIRMATA_DEBUG_H
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
#define DEBUG_BEGIN(baud) Serial.begin(baud); while(!Serial) {;}
|
||||
#define DEBUG_PRINTLN(x) Serial.println (x); Serial.flush()
|
||||
#define DEBUG_PRINT(x) Serial.print (x)
|
||||
#else
|
||||
#define DEBUG_BEGIN(baud)
|
||||
#define DEBUG_PRINTLN(x)
|
||||
#define DEBUG_PRINT(x)
|
||||
#endif
|
||||
|
||||
#endif /* FIRMATA_DEBUG_H */
|
||||
Reference in New Issue
Block a user