diff --git a/ArduinoCore-Linux/cores/arduino/ArdStdio.h b/ArduinoCore-Linux/cores/arduino/ArdStdio.h index d47a3ea..4849e35 100644 --- a/ArduinoCore-Linux/cores/arduino/ArdStdio.h +++ b/ArduinoCore-Linux/cores/arduino/ArdStdio.h @@ -21,7 +21,9 @@ class StdioDevice : public Stream { ~StdioDevice(){ } - + + operator bool() const { return true; } // For classic while(!Serial) { ... } pattern for USB ready wait + virtual void begin(int speed){ // nothing to be done } @@ -36,13 +38,13 @@ class StdioDevice : public Stream { if (auto_flush) flush(); } - virtual void print(int str){ - std::cout << str; + virtual void print(int val, int radix = DEC){ + if (radix == DEC) { std::cout << val; } else { Stream::print(val, radix); } if (auto_flush) flush(); } - virtual void println(int str){ - std::cout << str << "\n"; + virtual void println(int val, int radix = DEC){ + if (radix == DEC) { std::cout << val << "\n"; } else { Stream::println(val, radix); } if (auto_flush) flush(); } diff --git a/ArduinoCore-Linux/cores/arduino/Arduino.cpp b/ArduinoCore-Linux/cores/arduino/Arduino.cpp index 2044225..323b9e1 100644 --- a/ArduinoCore-Linux/cores/arduino/Arduino.cpp +++ b/ArduinoCore-Linux/cores/arduino/Arduino.cpp @@ -10,9 +10,17 @@ #include "PluggableUSB.h" #include "RemoteSerial.h" #include "Hardware.h" +#if defined(PROVIDE_HARDWARE_SETUP_SKIP) +// Not available for Windows / MSVC +#else #include "HardwareSetup.h" +#endif +#if defined(PROVIDE_HARDWARE_WIFI_SKIP) +// Not available for Windows / MSVC +#else #include "WiFi.h" #include "WiFiClient.h" +#endif #include "PluggableUSB.h" #include "deprecated-avr-comp/avr/dtostrf.h" #include "ArduinoLogger.h" @@ -22,10 +30,16 @@ namespace arduino { ArduinoLogger Logger; // Support for logging -WifiMock WiFi; // So that we can use the WiFi StdioDevice Serial; // output to screen HardwareImpl Hardware; // implementation for gpio, spi, i2c +#if defined(PROVIDE_HARDWARE_WIFI_SKIP) +#else +WifiMock WiFi; // So that we can use the WiFi +#endif +#if defined(PROVIDE_HARDWARE_SETUP_SKIP) +#else HardwareSetupImpl HardwareSetup; // setup for implementation +#endif #if PROVIDE_SERIALLIB SerialImpl Serial1("/dev/ttyACM0"); // output to serial port #endif @@ -77,34 +91,63 @@ unsigned long micros(void){ } void pinMode(pin_size_t pinNumber, PinMode pinMode){ - Hardware.gpio->pinMode(pinNumber,pinMode); + if (Hardware.gpio != nullptr) { + Hardware.gpio->pinMode(pinNumber,pinMode); + } } void digitalWrite(pin_size_t pinNumber, PinStatus status) { - Hardware.gpio->digitalWrite(pinNumber,status); + if (Hardware.gpio != nullptr) { + Hardware.gpio->digitalWrite(pinNumber,status); + } } PinStatus digitalRead(pin_size_t pinNumber) { - return Hardware.gpio->digitalRead(pinNumber); + if (Hardware.gpio != nullptr) { + return Hardware.gpio->digitalRead(pinNumber); + } else { + return HIGH; //sumulate input pullup + } } int analogRead(pin_size_t pinNumber){ - return Hardware.gpio->analogRead(pinNumber); + if (Hardware.gpio != nullptr) { + return Hardware.gpio->analogRead(pinNumber); + } else { + return 0; + } + } void analogReference(uint8_t mode){ - Hardware.gpio->analogReference(mode); + if (Hardware.gpio != nullptr) { + Hardware.gpio->analogReference(mode); + } } void analogWrite(pin_size_t pinNumber, int value) { - Hardware.gpio->analogWrite(pinNumber,value); + if (Hardware.gpio != nullptr) { + Hardware.gpio->analogWrite(pinNumber,value); + } } void tone(uint8_t pinNumber, unsigned int frequency, unsigned long duration) { - Hardware.gpio->tone(pinNumber,frequency,duration); + if (Hardware.gpio != nullptr) { + Hardware.gpio->tone(pinNumber,frequency,duration); + } } void noTone(uint8_t pinNumber) { - Hardware.gpio->noTone(pinNumber); + if (Hardware.gpio != nullptr) { + Hardware.gpio->noTone(pinNumber); + } } unsigned long pulseIn(uint8_t pinNumber, uint8_t state, unsigned long timeout){ - return Hardware.gpio->pulseIn(pinNumber, state, timeout); + if (Hardware.gpio != nullptr) { + return Hardware.gpio->pulseIn(pinNumber, state, timeout); + } else { + return 0; + } } unsigned long pulseInLong(uint8_t pinNumber, uint8_t state, unsigned long timeout){ - return Hardware.gpio->pulseInLong(pinNumber, state, timeout); + if (Hardware.gpio != nullptr) { + return Hardware.gpio->pulseInLong(pinNumber, state, timeout); + } else { + return 0; + } } void yield(){ diff --git a/ArduinoCore-Linux/cores/arduino/Arduino.h b/ArduinoCore-Linux/cores/arduino/Arduino.h index 17b3942..c887ef0 100644 --- a/ArduinoCore-Linux/cores/arduino/Arduino.h +++ b/ArduinoCore-Linux/cores/arduino/Arduino.h @@ -20,6 +20,22 @@ # define HOST #endif +#if defined(_MSC_VER) && !defined(M_PI) && !defined(_USE_MATH_DEFINES) +#define _USE_MATH_DEFINES // to provide const like M_PI via +#endif + +#if defined(_MSC_VER) +// Not available under MSVC +#define __attribute__(x) // nothing +#define __builtin_constant_p(x) (0) // non-constant +#endif + +#if defined(_MSC_VER) +// Temporary unsupported under Win/MSVC +#define PROVIDE_HARDWARE_SETUP_SKIP +#define PROVIDE_HARDWARE_WIFI_SKIP +#endif + #include "ArduinoAPI.h" #include "ArdStdio.h" #include "ArduinoLogger.h" diff --git a/ArduinoCore-Linux/cores/arduino/HardwareGPIO.cpp b/ArduinoCore-Linux/cores/arduino/HardwareGPIO.cpp index 68e0e49..f8f24a8 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareGPIO.cpp +++ b/ArduinoCore-Linux/cores/arduino/HardwareGPIO.cpp @@ -11,50 +11,76 @@ namespace arduino { void pinMode(pin_size_t pinNumber, PinMode pinMode){ - Hardware.gpio->pinMode(pinNumber,pinMode); + if (Hardware.gpio != nullptr) { + Hardware.gpio->pinMode(pinNumber,pinMode); + } } void digitalWrite(pin_size_t pinNumber, PinStatus status){ - Hardware.gpio->digitalWrite(pinNumber, status); + if (Hardware.gpio != nullptr) { + Hardware.gpio->digitalWrite(pinNumber, status); + } } PinStatus digitalRead(pin_size_t pinNumber){ - return Hardware.gpio->digitalRead(pinNumber); + if (Hardware.gpio != nullptr) { + return Hardware.gpio->digitalRead(pinNumber); + } else { + return HIGH; // return high, simulate weak pullup + } } int analogRead(pin_size_t pinNumber){ - return Hardware.gpio->analogRead(pinNumber); + if (Hardware.gpio != nullptr) { + return Hardware.gpio->analogRead(pinNumber); + } else { + return 0; + } } void analogReference(uint8_t mode){ - Hardware.gpio->analogReference(mode); + if (Hardware.gpio != nullptr) { + Hardware.gpio->analogReference(mode); + } } void analogWrite(pin_size_t pinNumber, int value){ - Hardware.gpio->analogWrite(pinNumber, value); + if (Hardware.gpio != nullptr) { + Hardware.gpio->analogWrite(pinNumber, value); + } } // Generates a square wave of the specified frequency (and 50% duty cycle) on a pin void tone(uint8_t pinNumber, unsigned int frequency, unsigned long duration = 0){ - Hardware.gpio->tone(pinNumber, frequency, duration); - + if (Hardware.gpio != nullptr) { + Hardware.gpio->tone(pinNumber, frequency, duration); + } } // Stops the generation of a square wave triggered by tone() void noTone(uint8_t pinNumber){ - Hardware.gpio->noTone(pinNumber); + if (Hardware.gpio != nullptr) { + Hardware.gpio->noTone(pinNumber); + } } /// Reads a pulse (either HIGH or LOW) on a pin unsigned long pulseIn(uint8_t pinNumber, uint8_t state, unsigned long timeout = 1000000L){ - return Hardware.gpio->pulseIn(pinNumber, state, timeout); - + if (Hardware.gpio != nullptr) { + return Hardware.gpio->pulseIn(pinNumber, state, timeout); + } else { + return 0; + } } /// Reads a pulse (either HIGH or LOW) on a pin unsigned long pulseInLong(uint8_t pinNumber, uint8_t state, unsigned long timeout = 1000000L){ - return Hardware.gpio->pulseInLong(pinNumber, state, timeout); + if (Hardware.gpio != nullptr) { + return Hardware.gpio->pulseInLong(pinNumber, state, timeout); + } else { + return 0; + } } diff --git a/ArduinoCore-Linux/cores/arduino/HardwareI2CEx.cpp b/ArduinoCore-Linux/cores/arduino/HardwareI2CEx.cpp index 8393219..a1a393c 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareI2CEx.cpp +++ b/ArduinoCore-Linux/cores/arduino/HardwareI2CEx.cpp @@ -9,40 +9,65 @@ namespace arduino { void HardwareI2CEx::begin() { - Hardware.i2c->begin(); + if (Hardware.i2c != nullptr) { + Hardware.i2c->begin(); + } } void HardwareI2CEx::begin(uint8_t address) { - Hardware.i2c->begin(address); + if (Hardware.i2c != nullptr) { + Hardware.i2c->begin(address); + } } void HardwareI2CEx::end(){ - Hardware.i2c->end(); + if (Hardware.i2c != nullptr) { + Hardware.i2c->end(); + } } void HardwareI2CEx::setClock(uint32_t freq){ - Hardware.i2c->setClock(freq); + if (Hardware.i2c != nullptr) { + Hardware.i2c->setClock(freq); + } } void HardwareI2CEx::beginTransmission(uint8_t address){ - Hardware.i2c->beginTransmission(address); + if (Hardware.i2c != nullptr) { + Hardware.i2c->beginTransmission(address); + } } uint8_t HardwareI2CEx::endTransmission(bool stopBit){ - return Hardware.i2c->endTransmission(stopBit); + if (Hardware.i2c != nullptr) { + return Hardware.i2c->endTransmission(stopBit); + } else { + return 0; + } } uint8_t HardwareI2CEx::endTransmission(void){ - return Hardware.i2c->endTransmission(); + if (Hardware.i2c != nullptr) { + return Hardware.i2c->endTransmission(); + } else { + return 0; + } } size_t HardwareI2CEx::requestFrom(uint8_t address, size_t len, bool stopBit){ - return Hardware.i2c->requestFrom(address,len,stopBit); - + if (Hardware.i2c != nullptr) { + return Hardware.i2c->requestFrom(address,len,stopBit); + } else { + return 0; + } } size_t HardwareI2CEx::requestFrom(uint8_t address, size_t len){ - return Hardware.i2c->requestFrom(address,len); + if (Hardware.i2c != nullptr) { + return Hardware.i2c->requestFrom(address,len); + } else { + return 0; + } } diff --git a/ArduinoCore-Linux/cores/arduino/HardwareSPI.cpp b/ArduinoCore-Linux/cores/arduino/HardwareSPI.cpp index 1fb605a..34b9a5d 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareSPI.cpp +++ b/ArduinoCore-Linux/cores/arduino/HardwareSPI.cpp @@ -13,47 +13,73 @@ namespace arduino { //HardwareSPI::~HardwareSPI() {} uint8_t HardwareSPI::transfer(uint8_t data) { - return Hardware.spi->transfer(data); + if (Hardware.spi != nullptr) { + return Hardware.spi->transfer(data); + } else { + return 0; + } } uint16_t HardwareSPI::transfer16(uint16_t data) { - return Hardware.spi->transfer16(data); + if (Hardware.spi != nullptr) { + return Hardware.spi->transfer16(data); + } else { + return 0; + } } void HardwareSPI::transfer(void *data, size_t count) { - Hardware.spi->transfer(data, count); + if (Hardware.spi != nullptr) { + Hardware.spi->transfer(data, count); + } } void HardwareSPI::usingInterrupt(int interruptNumber) { - Hardware.spi->usingInterrupt(interruptNumber); + if (Hardware.spi != nullptr) { + Hardware.spi->usingInterrupt(interruptNumber); + } } void HardwareSPI::notUsingInterrupt(int interruptNumber){ - Hardware.spi->notUsingInterrupt(interruptNumber); + if (Hardware.spi != nullptr) { + Hardware.spi->notUsingInterrupt(interruptNumber); + } } void HardwareSPI::beginTransaction(SPISettings settings){ - Hardware.spi->beginTransaction(settings); + if (Hardware.spi != nullptr) { + Hardware.spi->beginTransaction(settings); + } } void HardwareSPI::endTransaction(void){ - Hardware.spi->endTransaction(); + if (Hardware.spi != nullptr) { + Hardware.spi->endTransaction(); + } } void HardwareSPI::attachInterrupt() { - Hardware.spi->attachInterrupt(); + if (Hardware.spi != nullptr) { + Hardware.spi->attachInterrupt(); + } } void HardwareSPI::detachInterrupt(){ - Hardware.spi->detachInterrupt(); + if (Hardware.spi != nullptr) { + Hardware.spi->detachInterrupt(); + } } void HardwareSPI::begin() { - Hardware.spi->begin(); + if (Hardware.spi != nullptr) { + Hardware.spi->begin(); + } } void HardwareSPI::end() { - Hardware.spi->end(); + if (Hardware.spi != nullptr) { + Hardware.spi->end(); + } } } \ No newline at end of file diff --git a/ArduinoCore-Linux/cores/arduino/RemoteSerial.h b/ArduinoCore-Linux/cores/arduino/RemoteSerial.h index 7d9ee00..c4eaafc 100644 --- a/ArduinoCore-Linux/cores/arduino/RemoteSerial.h +++ b/ArduinoCore-Linux/cores/arduino/RemoteSerial.h @@ -101,12 +101,21 @@ class RemoteSerialImpl : public Stream { } void flush() { + #if defined(_MSC_VER) + int available; + while((available = write_buffer.available()) > 0){ + uint8_t buffer[max_buffer_len]; + write_buffer.read(buffer, min(available, max_buffer_len)); + write(buffer, min(available, max_buffer_len)); + } + #else int available = write_buffer.available(); if (available>0){ uint8_t buffer[available]; write_buffer.read(buffer, available); write(buffer, available); } + #endif service->send(SerialFlush); service->send(no); service->flush(); @@ -116,7 +125,11 @@ class RemoteSerialImpl : public Stream { protected: HardwareService *service; uint8_t no; + #if defined(_MSC_VER) + static constexpr int max_buffer_len = 512; // MSVC does not support VLA + #else int max_buffer_len = 512; + #endif RingBufferExt write_buffer; RingBufferExt read_buffer;