From 5ffd9741dc89abeb77ec3960e8c54355dda67580 Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Mon, 29 Sep 2025 08:58:12 +0200 Subject: [PATCH 01/50] DRAFT respberry pi support --- ArduinoCore-API/api/Stream.h | 1 + ArduinoCore-Linux/cores/arduino/Arduino.cpp | 34 +-- ArduinoCore-Linux/cores/arduino/Hardware.h | 22 +- .../cores/arduino/HardwareGPIO_RPI.cpp | 210 ++++++++++++++++++ .../cores/arduino/HardwareGPIO_RPI.h | 34 +++ .../cores/arduino/HardwareI2C_RPI.cpp | 102 +++++++++ .../cores/arduino/HardwareI2C_RPI.h | 54 +++++ .../cores/arduino/HardwareSPI_RPI.cpp | 89 ++++++++ .../cores/arduino/HardwareSPI_RPI.h | 43 ++++ .../cores/arduino/HardwareSetup.h | 8 +- Readme.md | 8 + _config.yml | 1 - .../jupyter/01-Setup.ipynb | 0 .../jupyter/02-BasicCommands.ipynb | 0 .../jupyter/03-Network.ipynb | 0 .../jupyter/04-Pins.ipynb | 0 .../jupyter/05-Serial.ipynb | 0 17 files changed, 575 insertions(+), 31 deletions(-) create mode 100644 ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp create mode 100644 ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h create mode 100644 ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp create mode 100644 ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h create mode 100644 ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp create mode 100644 ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h delete mode 100644 _config.yml rename 01-Setup.ipynb => examples/jupyter/01-Setup.ipynb (100%) rename 02-BasicCommands.ipynb => examples/jupyter/02-BasicCommands.ipynb (100%) rename 03-Network.ipynb => examples/jupyter/03-Network.ipynb (100%) rename 04-Pins.ipynb => examples/jupyter/04-Pins.ipynb (100%) rename 05-Serial.ipynb => examples/jupyter/05-Serial.ipynb (100%) diff --git a/ArduinoCore-API/api/Stream.h b/ArduinoCore-API/api/Stream.h index 10dcb4b..f75c8a8 100644 --- a/ArduinoCore-API/api/Stream.h +++ b/ArduinoCore-API/api/Stream.h @@ -62,6 +62,7 @@ class Stream : public Print virtual int peek() = 0; Stream() {_timeout=1000;} + ~Stream() {} // parsing methods diff --git a/ArduinoCore-Linux/cores/arduino/Arduino.cpp b/ArduinoCore-Linux/cores/arduino/Arduino.cpp index 729457f..6deeb54 100644 --- a/ArduinoCore-Linux/cores/arduino/Arduino.cpp +++ b/ArduinoCore-Linux/cores/arduino/Arduino.cpp @@ -10,16 +10,16 @@ #include "PluggableUSB.h" #include "RemoteSerial.h" #include "Hardware.h" -#if defined(PROVIDE_HARDWARE_SETUP_SKIP) -// Not available for Windows / MSVC -#else -#include "HardwareSetup.h" +#if !defined(PROVIDE_HARDWARE_SETUP_SKIP) +# include "HardwareSetup.h" #endif -#if defined(PROVIDE_HARDWARE_WIFI_SKIP) -// Not available for Windows / MSVC -#else -#include "WiFi.h" -#include "WiFiClient.h" +#if !defined(PROVIDE_HARDWARE_WIFI_SKIP) +# include "WiFi.h" +# include "WiFiClient.h" +#endif +#if defined(RPI) +# include "HardwareGPIO_RPI.h" +# include "HardwareI2C_RPI.h" #endif #include "PluggableUSB.h" #include "deprecated-avr-comp/avr/dtostrf.h" @@ -32,14 +32,20 @@ namespace arduino { ArduinoLogger Logger; // Support for logging StdioDevice Serial; // output to screen HardwareImpl Hardware; // implementation for gpio, spi, i2c -#if defined(PROVIDE_HARDWARE_WIFI_SKIP) -#else + +#if !defined(PROVIDE_HARDWARE_WIFI_SKIP) WifiMock WiFi; // So that we can use the WiFi #endif -#if defined(PROVIDE_HARDWARE_SETUP_SKIP) -#else -HardwareSetupImpl HardwareSetup; // setup for implementation + +#if !defined(PROVIDE_HARDWARE_SETUP_SKIP) +#ifdef RPI +static HardwareGPIO_RPI RPI_GPIO; +static HardwareI2C_RPI RPI_I2c; +#endif +HardwareSetupRemoteClass HardwareSetup; // setup for implementation #endif + + #if PROVIDE_SERIALLIB SerialImpl Serial1("/dev/ttyACM0"); // output to serial port #endif diff --git a/ArduinoCore-Linux/cores/arduino/Hardware.h b/ArduinoCore-Linux/cores/arduino/Hardware.h index e6317c6..125493d 100644 --- a/ArduinoCore-Linux/cores/arduino/Hardware.h +++ b/ArduinoCore-Linux/cores/arduino/Hardware.h @@ -6,22 +6,20 @@ namespace arduino { class HardwareI2CEx; class HardwareSPI; class HardwareGPIO; -//class I2SClass; - +// class I2SClass; + /** - * Class which is used to represent the actual implementation which is used to drive the - * specific interface + * Class which is used to represent the actual implementation which is used to + * drive the specific interface **/ struct HardwareImpl { - public: - HardwareGPIO *gpio; - HardwareI2CEx *i2c; - HardwareSPI *spi; - //I2SClass *i2s; + public: + HardwareImpl() {} + HardwareGPIO* gpio = nullptr; + HardwareI2CEx* i2c = nullptr; + HardwareSPI* spi = nullptr; }; extern HardwareImpl Hardware; - - -} +} // namespace arduino diff --git a/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp b/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp new file mode 100644 index 0000000..1fdea14 --- /dev/null +++ b/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp @@ -0,0 +1,210 @@ + +#ifdef RPI + +#include +#include +#include "HardwareGPIO_RPI.h" +#include "Hardware.h" +#include "ArduinoLogger.h" + +namespace arduino { + +// Helper: map pin number to gpiod_line* +static std::map gpio_lines; +static gpiod_chip* gpio_chip = nullptr; + +HardwareGPIO_RPI::HardwareGPIO_RPI() { + Hardware.gpio = this; + gpio_chip = gpiod_chip_open_by_name("gpiochip0"); + if (!gpio_chip) { + Logger.error("HardwareGPIO_RPI", "Failed to open gpiochip0"); + } +} + +HardwareGPIO_RPI::~HardwareGPIO_RPI() { + Hardware.gpio = nullptr; + for (auto& kv : gpio_lines) { + gpiod_line_release(kv.second); + } + gpio_lines.clear(); + if (gpio_chip) { + gpiod_chip_close(gpio_chip); + gpio_chip = nullptr; + } +} + +void HardwareGPIO_RPI::pinMode(pin_size_t pinNumber, PinMode pinMode) { + if (!gpio_chip) return; + gpiod_line* line = gpio_lines[pinNumber]; + if (!line) { + line = gpiod_chip_get_line(gpio_chip, pinNumber); + if (!line) { + Logger.error("HardwareGPIO_RPI", "Failed to get line"); + return; + } + gpio_lines[pinNumber] = line; + } + int ret = 0; + if (pinMode == OUTPUT) { + ret = gpiod_line_request_output(line, "arduino-emulator", 0); + } else { + ret = gpiod_line_request_input(line, "arduino-emulator"); + } + if (ret < 0) { + Logger.error("HardwareGPIO_RPI", "Failed to set pin mode"); + } +} + +void HardwareGPIO_RPI::digitalWrite(pin_size_t pinNumber, PinStatus status) { + auto it = gpio_lines.find(pinNumber); + if (it == gpio_lines.end() || !it->second) { + pinMode(pinNumber, OUTPUT); + } + gpiod_line* line = gpio_lines[pinNumber]; + if (line) { + int value = (status == HIGH) ? 1 : 0; + if (gpiod_line_set_value(line, value) < 0) { + Logger.error("HardwareGPIO_RPI", "Failed to write value"); + } + } +} + +PinStatus HardwareGPIO_RPI::digitalRead(pin_size_t pinNumber) { + auto it = gpio_lines.find(pinNumber); + if (it == gpio_lines.end() || !it->second) { + pinMode(pinNumber, INPUT); + } + gpiod_line* line = gpio_lines[pinNumber]; + if (line) { + int value = gpiod_line_get_value(line); + if (value < 0) { + Logger.error("HardwareGPIO_RPI", "Failed to read value"); + return LOW; + } + return value ? HIGH : LOW; + } + return LOW; +} + +int HardwareGPIO_RPI::analogRead(pin_size_t pinNumber) { + Logger.error("HardwareGPIO_RPI", + "analogRead not supported on Raspberry Pi GPIO"); + return 0; +} + +void HardwareGPIO_RPI::analogReference(uint8_t mode) { + m_analogReference = mode; +} + +void HardwareGPIO_RPI::analogWrite(pin_size_t pinNumber, int value) { + // Supported hardware PWM pins on Raspberry Pi: 12, 13, 18, 19 + // Use sysfs interface: /sys/class/pwm/pwmchip0 + bool supported = false; + for (int i = 0; i < 4; ++i) { + if (pinNumber == pwm_pins[i]) { + supported = true; + break; + } + } + if (!supported) { + Logger.error("HardwareGPIO_RPI", + "analogWrite: pin does not support hardware PWM"); + return; + } + + // Map pin to PWM channel (chip0: pwm0 for GPIO18, pwm1 for GPIO19, etc.) + int pwm_channel = -1; + if (pinNumber == 18) + pwm_channel = 0; + else if (pinNumber == 19) + pwm_channel = 1; + else if (pinNumber == 12) + pwm_channel = 0; // On some models + else if (pinNumber == 13) + pwm_channel = 1; // On some models + + if (pwm_channel < 0) { + Logger.error("HardwareGPIO_RPI", + "analogWrite: could not map pin to PWM channel"); + return; + } + + // Export PWM channel if not already exported + char export_path[64]; + snprintf(export_path, sizeof(export_path), "/sys/class/pwm/pwmchip0/export"); + FILE* fexp = fopen(export_path, "w"); + if (fexp) { + fprintf(fexp, "%d", pwm_channel); + fclose(fexp); + } + // Set period and duty cycle + char period_path[64], duty_path[64], enable_path[64]; + snprintf(period_path, sizeof(period_path), + "/sys/class/pwm/pwmchip0/pwm%d/period", pwm_channel); + snprintf(duty_path, sizeof(duty_path), + "/sys/class/pwm/pwmchip0/pwm%d/duty_cycle", pwm_channel); + snprintf(enable_path, sizeof(enable_path), + "/sys/class/pwm/pwmchip0/pwm%d/enable", pwm_channel); + + // Set period to 20000 ns (50 kHz) + FILE* fperiod = fopen(period_path, "w"); + if (fperiod) { + fprintf(fperiod, "%d", 20000); + fclose(fperiod); + } + // Duty cycle: value in range 0-255 + int duty = (value < 0) ? 0 : (value > 255) ? 255 : value; + int duty_ns = (duty * 20000) / 255; + FILE* fduty = fopen(duty_path, "w"); + if (fduty) { + fprintf(fduty, "%d", duty_ns); + fclose(fduty); + } + // Enable PWM + FILE* fenable = fopen(enable_path, "w"); + if (fenable) { + fprintf(fenable, "%d", 1); + fclose(fenable); + } +} + +void HardwareGPIO_RPI::tone(uint8_t _pin, unsigned int frequency, + unsigned long duration) { + Logger.error("HardwareGPIO_RPI", "tone not supported on Raspberry Pi GPIO"); +} + +void HardwareGPIO_RPI::noTone(uint8_t _pin) { + Logger.error("HardwareGPIO_RPI", "noTone not supported on Raspberry Pi GPIO"); +} + +unsigned long HardwareGPIO_RPI::pulseIn(uint8_t pin, uint8_t state, + unsigned long timeout) { + Logger.error("HardwareGPIO_RPI", "pulseIn not implemented"); + return 0; +} + +unsigned long HardwareGPIO_RPI::pulseInLong(uint8_t pin, uint8_t state, + unsigned long timeout) { + Logger.error("HardwareGPIO_RPI", "pulseInLong not implemented"); + return 0; +} + +void HardwareGPIO_RPI::analogWriteFrequency(uint8_t pin, uint32_t freq) { + bool supported = false; + for (int i = 0; i < 4; ++i) { + if (pin == pwm_pins[i]) { + supported = true; + break; + } + } + if (!supported) { + Logger.error("HardwareGPIO_RPI", + "analogWriteFrequency: pin does not support hardware PWM"); + return; + } + gpio_frequencies[pin] = freq; +} + +} // namespace arduino + +#endif \ No newline at end of file diff --git a/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h b/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h new file mode 100644 index 0000000..642e8ec --- /dev/null +++ b/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h @@ -0,0 +1,34 @@ +#pragma once +#ifdef RPI +#include "HardwareGPIO.h" + +namespace arduino { + +class HardwareGPIO_RPI : public HardwareGPIO { + public: + HardwareGPIO_RPI(); + ~HardwareGPIO_RPI(); + void pinMode(pin_size_t pinNumber, PinMode pinMode) override; + void digitalWrite(pin_size_t pinNumber, PinStatus status) override; + PinStatus digitalRead(pin_size_t pinNumber) override; + int analogRead(pin_size_t pinNumber) override; + void analogReference(uint8_t mode) override; + void analogWrite(pin_size_t pinNumber, int value) override; + void tone(uint8_t _pin, unsigned int frequency, + unsigned long duration = 0) override; + void noTone(uint8_t _pin) override; + unsigned long pulseIn(uint8_t pin, uint8_t state, + unsigned long timeout = 1000000L) override; + unsigned long pulseInLong(uint8_t pin, uint8_t state, + unsigned long timeout = 1000000L) override; + void analogWriteFrequency(uint8_t pin, uint32_t freq); + + private: + int m_analogReference = 0; // Default to AR_DEFAULT + std::map gpio_frequencies; + static const int pwm_pins[] = {12, 13, 18, 19}; +}; + +} // namespace arduino + +#endif \ No newline at end of file diff --git a/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp b/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp new file mode 100644 index 0000000..e9da3a1 --- /dev/null +++ b/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp @@ -0,0 +1,102 @@ +#ifdef RPI + +#include "HardwareI2C_RPI.h" +#include +#include +#include +#include +#include +#include + +namespace arduino { + + +void HardwareI2C_RPI::begin(uint8_t address) { + begin(); + current_address = address; + if (ioctl(i2c_fd, I2C_SLAVE, address) < 0) { + Logger.error("HardwareI2C_RPI: Failed to set I2C address"); + } +} + +void HardwareI2C_RPI::end() { + if (i2c_fd >= 0) { + close(i2c_fd); + i2c_fd = -1; + } +} + +void HardwareI2C_RPI::setClock(uint32_t freq) { + i2c_clock = freq; + // Changing I2C clock at runtime is not supported via /dev/i2c-1 + // Usually set via device tree overlays or raspi-config +} + +void HardwareI2C_RPI::beginTransmission(uint8_t address) { + current_address = address; + if (ioctl(i2c_fd, I2C_SLAVE, address) < 0) { + perror("HardwareI2C_RPI: Failed to set I2C address"); + } +} + +size_t HardwareI2C_RPI::write(uint8_t data) { + i2c_tx_buffer.push_back(data); + return 1; +} + +size_t HardwareI2C_RPI::write(const uint8_t* data, size_t len) { + i2c_tx_buffer.insert(i2c_tx_buffer.end(), data, data + len); + return len; +} + +int HardwareI2C_RPI::available() { return i2c_rx_buffer.size() - i2c_rx_pos; } + +int HardwareI2C_RPI::peek() { + if (i2c_rx_pos < i2c_rx_buffer.size()) { + return i2c_rx_buffer[i2c_rx_pos]; + } + return -1; +} + +int HardwareI2C_RPI::read() { + if (i2c_rx_pos < i2c_rx_buffer.size()) { + return i2c_rx_buffer[i2c_rx_pos++]; + } + return -1; +} + +uint8_t HardwareI2C_RPI::endTransmission(bool stopBit) { + if (i2c_fd < 0 || i2c_tx_buffer.empty()) return 4; // error + ssize_t w = ::write(i2c_fd, i2c_tx_buffer.data(), i2c_tx_buffer.size()); + i2c_tx_buffer.clear(); + return (w < 0) ? 4 : 0; +} + +size_t HardwareI2C_RPI::requestFrom(uint8_t address, size_t len, bool stopBit) { + beginTransmission(address); + i2c_rx_buffer.resize(len); + ssize_t r = ::read(i2c_fd, i2c_rx_buffer.data(), len); + i2c_rx_pos = 0; + if (r < 0) { + perror("HardwareI2C_RPI: Failed to read"); + i2c_rx_buffer.clear(); + return 0; + } + i2c_rx_buffer.resize(r); + return (size_t)r; +} + +size_t HardwareI2C_RPI::requestFrom(uint8_t address, size_t len) { + return requestFrom(address, len, true); +} + +void HardwareI2C_RPI::onReceive(void (*cb)(int)) { + Logger.error("HardwareI2C_RPI", "onReceive not implemented on Linux I2C"); +} + +void HardwareI2C_RPI::onRequest(void (*cb)(void)) { + Logger.error("HardwareI2C_RPI", "onRequest not implemented on Linux I2C"); +} + +} // namespace arduino +#endif diff --git a/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h b/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h new file mode 100644 index 0000000..eef3546 --- /dev/null +++ b/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h @@ -0,0 +1,54 @@ +#pragma once +#ifdef RPI + +#include +#include "Hardware.h" +#include "HardwareI2C.h" +#include "ArduinoLogger.h" + +namespace arduino { + +class HardwareI2C_RPI : public HardwareI2C { + public: + HardwareI2C_RPI(const char* device = "/dev/i2c-1") : i2c_device(device) { + Hardware.i2c = this; + i2c_fd = open(device, O_RDWR); + if (i2c_fd < 0) { + Logger.error("HardwareI2C_RPI: Failed to open /dev/i2c-1"); + } + } + ~HardwareI2C_RPI() override { + Hardware.i2c = nullptr; + end(); + } + void begin() override; + void begin(uint8_t address) override; + void end() override; + void setClock(uint32_t freq) override; + void beginTransmission(uint8_t address) override; + uint8_t endTransmission(bool stopBit) override; + uint8_t endTransmission(void) override; + size_t requestFrom(uint8_t address, size_t len, bool stopBit) override; + size_t requestFrom(uint8_t address, size_t len) override; + void onReceive(void (*)(int)) override; + void onRequest(void (*)(void)) override; + size_t write(uint8_t) override; + size_t write(const uint8_t*, size_t) override; + int available() override; + int read() override; + int peek() override; + void flush() override; + + private: + int i2c_fd = -1; + uint8_t current_address = 0; + uint32_t i2c_clock = 100000; // default 100kHz + std::vector i2c_rx_buffer; + std::vector i2c_tx_buffer; + int i2c_rx_pos = 0; + const char* i2c_device; +}; + +} // namespace arduino + +#endif diff --git a/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp b/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp new file mode 100644 index 0000000..b3f164c --- /dev/null +++ b/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp @@ -0,0 +1,89 @@ +#ifdef RPI + +#include "HardwareSPI_RPI.h" + +#include +#include +#include +#include + +#include +#include + +namespace arduino { + +HardwareSPI_RPI::HardwareSPI_RPI(const char* device) { + spi_fd = open(device, O_RDWR); + if (spi_fd < 0) { + perror("HardwareSPI_RPI: Failed to open SPI device"); + } + ioctl(spi_fd, SPI_IOC_WR_MODE, &spi_mode); + ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits); + ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed); +} +HardwareSPI_RPI::~HardwareSPI_RPI() { + if (spi_fd >= 0) close(spi_fd); +} +void HardwareSPI_RPI::end() { + if (spi_fd >= 0) close(spi_fd); + spi_fd = -1; +} +uint8_t HardwareSPI_RPI::transfer(uint8_t data) { + uint8_t rx = 0; + struct spi_ioc_transfer tr = {}; + tr.tx_buf = (unsigned long)&data; + tr.rx_buf = (unsigned long)℞ + tr.len = 1; + tr.speed_hz = spi_speed; + tr.bits_per_word = spi_bits; + tr.delay_usecs = 0; + ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); + return rx; +} +uint16_t HardwareSPI_RPI::transfer16(uint16_t data) { + uint16_t rx = 0; + struct spi_ioc_transfer tr = {}; + tr.tx_buf = (unsigned long)&data; + tr.rx_buf = (unsigned long)℞ + tr.len = 2; + tr.speed_hz = spi_speed; + tr.bits_per_word = spi_bits; + tr.delay_usecs = 0; + ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); + return rx; +} +void HardwareSPI_RPI::transfer(void* buf, size_t count) { + struct spi_ioc_transfer tr = {}; + tr.tx_buf = (unsigned long)buf; + tr.rx_buf = (unsigned long)buf; + tr.len = count; + tr.speed_hz = spi_speed; + tr.bits_per_word = spi_bits; + tr.delay_usecs = 0; + ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); +} +void HardwareSPI_RPI::usingInterrupt(int interruptNumber) { + Logger.error("HardwareSPI_RPI: usingInterrupt not implemented\n"); +} +void HardwareSPI_RPI::notUsingInterrupt(int interruptNumber) { + Logger.error("HardwareSPI_RPI: notUsingInterrupt not implemented\n"); +} +void HardwareSPI_RPI::beginTransaction(SPISettings settings) { + spi_mode = settings.getDataMode(); + spi_speed = settings.getClockFreq(); + spi_bits = settings.getBitOrder(); + ioctl(spi_fd, SPI_IOC_WR_MODE, &spi_mode); + ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits); + ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed); +} +void HardwareSPI_RPI::endTransaction(void) {} +void HardwareSPI_RPI::attachInterrupt() { + Logger.error("HardwareSPI_RPI: attachInterrupt not implemented\n"); +} +void HardwareSPI_RPI::detachInterrupt() { + Logger.error("HardwareSPI_RPI: detachInterrupt not implemented\n"); +} + +} // namespace arduino + +#endif // RPI diff --git a/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h b/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h new file mode 100644 index 0000000..f0d504a --- /dev/null +++ b/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h @@ -0,0 +1,43 @@ +#pragma once +#ifdef RPI +#include + +#include "Common.h" +#include "HardwareSPI.h" +#include "Stream.h" + +namespace arduino { + +class HardwareSPI_RPI : public HardwareSPI { + public: + HardwareSPI_RPI(); + ~HardwareSPI_RPI() override; + + uint8_t transfer(uint8_t data) override; + uint16_t transfer16(uint16_t data) override; + void transfer(void* buf, size_t count) override; + + // Transaction Functions + void usingInterrupt(int interruptNumber) override; + void notUsingInterrupt(int interruptNumber) override; + void beginTransaction(SPISettings settings) override; + void endTransaction(void) override; + + // SPI Configuration methods + void attachInterrupt() override; + void detachInterrupt() override; + + void begin() override; + void end() override; + + protected: + int spi_fd = -1; + const char* DEFAULT_SPI_DEVICE = "/dev/spidev0.0"; + uint32_t spi_speed = 500000; // Default to 500kHz + uint8_t spi_mode = 0; // Default to SPI mode 0 + uint8_t spi_bits = 8; // Default to 8 bits per word +}; + +} // namespace arduino + +#endif // RPI diff --git a/ArduinoCore-Linux/cores/arduino/HardwareSetup.h b/ArduinoCore-Linux/cores/arduino/HardwareSetup.h index d3f5512..a7047e3 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareSetup.h +++ b/ArduinoCore-Linux/cores/arduino/HardwareSetup.h @@ -16,16 +16,16 @@ namespace arduino { * Class which is used to configure the actual Hardware APIs */ -class HardwareSetupImpl { +class HardwareSetupRemoteClass { public: // as a default we use udp - HardwareSetupImpl(int port=7000){ + HardwareSetupRemoteClass(int port=7000){ this->port = port; default_stream = new WiFiUDPStream(); default_stream->begin(port); } - ~HardwareSetupImpl(){ + ~HardwareSetupRemoteClass(){ cleanup(); } @@ -103,7 +103,7 @@ class HardwareSetupImpl { }; -extern HardwareSetupImpl HardwareSetup; +extern HardwareSetupRemoteClass HardwareSetup; } diff --git a/Readme.md b/Readme.md index a4dabe0..52ff1f3 100644 --- a/Readme.md +++ b/Readme.md @@ -5,6 +5,14 @@ If you have an Arduino Sketch that you want to run e.g in Linux or OS/X you can include this library with cmake. Here is an [example cmake file](https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-desktop/generator/CMakeLists.txt) for a [Arduino Audio Sketch](https://github.com/pschatzmann/arduino-audio-tools/tree/main/examples/examples-desktop/generator)). +## GPIO/SPI/I2C + +We provide some alternative implementations: + +- Dummy Implementatin which does nothing +- Transmit updates to a Microcontroller using UDP +- Rasperry PI + ## Jupyter diff --git a/_config.yml b/_config.yml deleted file mode 100644 index c741881..0000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-slate \ No newline at end of file diff --git a/01-Setup.ipynb b/examples/jupyter/01-Setup.ipynb similarity index 100% rename from 01-Setup.ipynb rename to examples/jupyter/01-Setup.ipynb diff --git a/02-BasicCommands.ipynb b/examples/jupyter/02-BasicCommands.ipynb similarity index 100% rename from 02-BasicCommands.ipynb rename to examples/jupyter/02-BasicCommands.ipynb diff --git a/03-Network.ipynb b/examples/jupyter/03-Network.ipynb similarity index 100% rename from 03-Network.ipynb rename to examples/jupyter/03-Network.ipynb diff --git a/04-Pins.ipynb b/examples/jupyter/04-Pins.ipynb similarity index 100% rename from 04-Pins.ipynb rename to examples/jupyter/04-Pins.ipynb diff --git a/05-Serial.ipynb b/examples/jupyter/05-Serial.ipynb similarity index 100% rename from 05-Serial.ipynb rename to examples/jupyter/05-Serial.ipynb From 53cbf74e5c6bad8710181d2597c157fbd7f67e96 Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Mon, 29 Sep 2025 09:01:21 +0200 Subject: [PATCH 02/50] readme --- Readme.md => README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename Readme.md => README.md (75%) diff --git a/Readme.md b/README.md similarity index 75% rename from Readme.md rename to README.md index 52ff1f3..4040e8c 100644 --- a/Readme.md +++ b/README.md @@ -2,7 +2,7 @@ ## Using this Project as a library -If you have an Arduino Sketch that you want to run e.g in Linux or OS/X you can include this library with cmake. +If you have an Arduino Sketch that you want to run e.g in Linux, OS/X or Windows you can include this library with cmake. Here is an [example cmake file](https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-desktop/generator/CMakeLists.txt) for a [Arduino Audio Sketch](https://github.com/pschatzmann/arduino-audio-tools/tree/main/examples/examples-desktop/generator)). ## GPIO/SPI/I2C @@ -10,7 +10,7 @@ Here is an [example cmake file](https://github.com/pschatzmann/arduino-audio-too We provide some alternative implementations: - Dummy Implementatin which does nothing -- Transmit updates to a Microcontroller using UDP +- Communicates changes to/from a Microcontroller using UDP - Rasperry PI @@ -18,7 +18,7 @@ We provide some alternative implementations: I really wanted to have an interactive [Jupyter](https://jupyter.org/) environemnt in which I could play around with [Arduino](https://www.arduino.cc/) commands and when I discovered that Arduino provides a good starting point with their [ArduinoCore-API](https://github.com/arduino/ArduinoCore-API/tree/105276f8d81413391b14a3dc6c80180ee9e33d56) I decided to start this project. -I am using [xeus-cling](https://github.com/jupyter-xeus/xeus-cling) as a runtime environment to simulate an Arduino Development board and I have added the missing implementation using C or the C++ std library. +You can also use [xeus-cling](https://github.com/jupyter-xeus/xeus-cling) as a runtime environment to simulate an Arduino Development board and I have added the missing implementation using C or the C++ std library. Here is a quick demo: From 18f94d99b1cb1eec1946e247021f2e32ea6c0eac Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Mon, 29 Sep 2025 09:15:49 +0200 Subject: [PATCH 03/50] standardize defines --- ArduinoCore-Linux/cores/arduino/Arduino.cpp | 12 ++++++------ ArduinoCore-Linux/cores/arduino/Arduino.h | 4 ++-- ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp | 2 +- ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h | 2 +- ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp | 2 +- ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h | 2 +- ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp | 4 ++-- ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h | 4 ++-- README.md | 8 ++++++++ 9 files changed, 24 insertions(+), 16 deletions(-) diff --git a/ArduinoCore-Linux/cores/arduino/Arduino.cpp b/ArduinoCore-Linux/cores/arduino/Arduino.cpp index 6deeb54..591a5df 100644 --- a/ArduinoCore-Linux/cores/arduino/Arduino.cpp +++ b/ArduinoCore-Linux/cores/arduino/Arduino.cpp @@ -10,14 +10,14 @@ #include "PluggableUSB.h" #include "RemoteSerial.h" #include "Hardware.h" -#if !defined(PROVIDE_HARDWARE_SETUP_SKIP) +#if !defined(SKIP_HARDWARE_SETUP) # include "HardwareSetup.h" #endif -#if !defined(PROVIDE_HARDWARE_WIFI_SKIP) +#if !defined(SKIP_HARDWARE_WIFI) # include "WiFi.h" # include "WiFiClient.h" #endif -#if defined(RPI) +#if defined(USE_RPI) # include "HardwareGPIO_RPI.h" # include "HardwareI2C_RPI.h" #endif @@ -33,12 +33,12 @@ ArduinoLogger Logger; // Support for logging StdioDevice Serial; // output to screen HardwareImpl Hardware; // implementation for gpio, spi, i2c -#if !defined(PROVIDE_HARDWARE_WIFI_SKIP) +#if !defined(SKIP_HARDWARE_WIFI) WifiMock WiFi; // So that we can use the WiFi #endif -#if !defined(PROVIDE_HARDWARE_SETUP_SKIP) -#ifdef RPI +#if !defined(SKIP_HARDWARE_SETUP) +#ifdef USE_RPI static HardwareGPIO_RPI RPI_GPIO; static HardwareI2C_RPI RPI_I2c; #endif diff --git a/ArduinoCore-Linux/cores/arduino/Arduino.h b/ArduinoCore-Linux/cores/arduino/Arduino.h index c887ef0..5ccf947 100644 --- a/ArduinoCore-Linux/cores/arduino/Arduino.h +++ b/ArduinoCore-Linux/cores/arduino/Arduino.h @@ -32,8 +32,8 @@ #if defined(_MSC_VER) // Temporary unsupported under Win/MSVC -#define PROVIDE_HARDWARE_SETUP_SKIP -#define PROVIDE_HARDWARE_WIFI_SKIP +#define SKIP_HARDWARE_SETUP +#define SKIP_HARDWARE_WIFI #endif #include "ArduinoAPI.h" diff --git a/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp b/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp index 1fdea14..d42d2f3 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp +++ b/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.cpp @@ -1,5 +1,5 @@ -#ifdef RPI +#ifdef USE_RPI #include #include diff --git a/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h b/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h index 642e8ec..df76f05 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h +++ b/ArduinoCore-Linux/cores/arduino/HardwareGPIO_RPI.h @@ -1,5 +1,5 @@ #pragma once -#ifdef RPI +#ifdef USE_RPI #include "HardwareGPIO.h" namespace arduino { diff --git a/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp b/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp index e9da3a1..781a95c 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp +++ b/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.cpp @@ -1,4 +1,4 @@ -#ifdef RPI +#ifdef USE_RPI #include "HardwareI2C_RPI.h" #include diff --git a/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h b/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h index eef3546..50cddbb 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h +++ b/ArduinoCore-Linux/cores/arduino/HardwareI2C_RPI.h @@ -1,5 +1,5 @@ #pragma once -#ifdef RPI +#ifdef USE_RPI #include #include "Hardware.h" diff --git a/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp b/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp index b3f164c..a6725bb 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp +++ b/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.cpp @@ -1,4 +1,4 @@ -#ifdef RPI +#ifdef USE_RPI #include "HardwareSPI_RPI.h" @@ -86,4 +86,4 @@ void HardwareSPI_RPI::detachInterrupt() { } // namespace arduino -#endif // RPI +#endif // USE_RPI diff --git a/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h b/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h index f0d504a..e048b70 100644 --- a/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h +++ b/ArduinoCore-Linux/cores/arduino/HardwareSPI_RPI.h @@ -1,5 +1,5 @@ #pragma once -#ifdef RPI +#ifdef USE_RPI #include #include "Common.h" @@ -40,4 +40,4 @@ class HardwareSPI_RPI : public HardwareSPI { } // namespace arduino -#endif // RPI +#endif // USE_RPI diff --git a/README.md b/README.md index 4040e8c..c7b28b2 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,14 @@ Here is a quick demo: - [Using Pins](04-Pins.ipynb) - [Using Serial](05-Serial.ipynb) +## Supported Defines + +You can activate/deactivate some functionality with the helpo f the following defines: + +- USE_RPI: activates support for Rasperry PI +- USE_HTTPS: provide https support +- SKIP_HARDWARE_SETUP: deactivate GPIO/SPI/I2C implementations +- SKIP_HARDWARE_WIFI: deactivate WiFi ## Documentation From ad72a13fe831a8d47ca993905a4a4b2c6fcdce16 Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Mon, 29 Sep 2025 09:18:14 +0200 Subject: [PATCH 04/50] doxygen --- Doxyfile | 2 +- docs/html/_arduino_8h_source.html | 4 +- docs/html/_common_8h_source.html | 210 ++--- docs/html/_hardware_8h_source.html | 20 +- .../_hardware_g_p_i_o___r_p_i_8h_source.html | 130 +++ .../_hardware_i2_c___r_p_i_8h_source.html | 150 ++++ .../_hardware_s_p_i___r_p_i_8h_source.html | 140 +++ docs/html/_hardware_setup_8h_source.html | 10 +- docs/html/_stream_8h_source.html | 139 +-- docs/html/annotated.html | 71 +- docs/html/class_stream_mock-members.html | 29 +- .../html/classarduino_1_1_client-members.html | 1 + ...ssarduino_1_1_ethernet_client-members.html | 29 +- ...assarduino_1_1_ethernet_u_d_p-members.html | 3 +- .../classarduino_1_1_file_stream-members.html | 1 + .../classarduino_1_1_hardware_g_p_i_o.html | 3 +- .../classarduino_1_1_hardware_g_p_i_o.png | Bin 655 -> 1009 bytes ..._1_1_hardware_g_p_i_o___r_p_i-members.html | 103 +++ ...sarduino_1_1_hardware_g_p_i_o___r_p_i.html | 487 ++++++++++ ...ssarduino_1_1_hardware_g_p_i_o___r_p_i.png | Bin 0 -> 693 bytes ...lassarduino_1_1_hardware_i2_c-members.html | 1 + docs/html/classarduino_1_1_hardware_i2_c.html | 9 +- docs/html/classarduino_1_1_hardware_i2_c.png | Bin 1452 -> 2014 bytes ...ino_1_1_hardware_i2_c___r_p_i-members.html | 170 ++++ ...lassarduino_1_1_hardware_i2_c___r_p_i.html | 842 ++++++++++++++++++ ...classarduino_1_1_hardware_i2_c___r_p_i.png | Bin 0 -> 1175 bytes .../html/classarduino_1_1_hardware_s_p_i.html | 3 +- docs/html/classarduino_1_1_hardware_s_p_i.png | Bin 619 -> 978 bytes ...no_1_1_hardware_s_p_i___r_p_i-members.html | 107 +++ ...assarduino_1_1_hardware_s_p_i___r_p_i.html | 461 ++++++++++ ...lassarduino_1_1_hardware_s_p_i___r_p_i.png | Bin 0 -> 668 bytes ...ssarduino_1_1_hardware_serial-members.html | 1 + ...1_hardware_setup_remote_class-members.html | 97 ++ ...duino_1_1_hardware_setup_remote_class.html | 131 +++ ...rduino_1_1_remote_serial_impl-members.html | 1 + .../classarduino_1_1_serial_impl-members.html | 1 + ...classarduino_1_1_stdio_device-members.html | 1 + .../html/classarduino_1_1_stream-members.html | 1 + docs/html/classarduino_1_1_u_d_p-members.html | 3 +- ...duino_1_1_wi_fi_client_secure-members.html | 1 + ...rduino_1_1_wi_fi_u_d_p_stream-members.html | 5 +- docs/html/classes.html | 2 +- .../dir_2ba506666022b9e33e4ecc950aca3a7c.html | 6 + docs/html/files.html | 63 +- docs/html/hierarchy.html | 9 +- docs/html/index.html | 56 +- docs/html/namespacearduino.html | 26 +- docs/html/namespaces.html | 71 +- docs/html/search/all_1.js | 38 +- docs/html/search/all_10.js | 130 +-- docs/html/search/all_11.js | 121 ++- docs/html/search/all_12.js | 33 +- docs/html/search/all_13.js | 7 +- docs/html/search/all_14.js | 14 +- docs/html/search/all_15.js | 14 +- docs/html/search/all_16.js | 2 +- docs/html/search/all_17.js | 4 + docs/html/search/all_3.js | 49 +- docs/html/search/all_4.js | 4 +- docs/html/search/all_5.js | 35 +- docs/html/search/all_7.js | 3 +- docs/html/search/all_8.js | 23 +- docs/html/search/all_9.js | 73 +- docs/html/search/all_a.js | 12 +- docs/html/search/all_b.js | 37 +- docs/html/search/all_c.js | 28 +- docs/html/search/all_d.js | 9 +- docs/html/search/all_e.js | 22 +- docs/html/search/all_f.js | 55 +- docs/html/search/classes_8.js | 21 +- docs/html/search/pages_0.js | 4 +- docs/html/search/pages_1.js | 4 + docs/html/search/pages_2.js | 4 + docs/html/search/pages_3.js | 4 + docs/html/search/searchdata.js | 4 +- ...ructarduino_1_1_hardware_impl-members.html | 5 +- .../html/structarduino_1_1_hardware_impl.html | 6 +- 77 files changed, 3647 insertions(+), 718 deletions(-) create mode 100644 docs/html/_hardware_g_p_i_o___r_p_i_8h_source.html create mode 100644 docs/html/_hardware_i2_c___r_p_i_8h_source.html create mode 100644 docs/html/_hardware_s_p_i___r_p_i_8h_source.html create mode 100644 docs/html/classarduino_1_1_hardware_g_p_i_o___r_p_i-members.html create mode 100644 docs/html/classarduino_1_1_hardware_g_p_i_o___r_p_i.html create mode 100644 docs/html/classarduino_1_1_hardware_g_p_i_o___r_p_i.png create mode 100644 docs/html/classarduino_1_1_hardware_i2_c___r_p_i-members.html create mode 100644 docs/html/classarduino_1_1_hardware_i2_c___r_p_i.html create mode 100644 docs/html/classarduino_1_1_hardware_i2_c___r_p_i.png create mode 100644 docs/html/classarduino_1_1_hardware_s_p_i___r_p_i-members.html create mode 100644 docs/html/classarduino_1_1_hardware_s_p_i___r_p_i.html create mode 100644 docs/html/classarduino_1_1_hardware_s_p_i___r_p_i.png create mode 100644 docs/html/classarduino_1_1_hardware_setup_remote_class-members.html create mode 100644 docs/html/classarduino_1_1_hardware_setup_remote_class.html create mode 100644 docs/html/search/all_17.js create mode 100644 docs/html/search/pages_1.js create mode 100644 docs/html/search/pages_2.js create mode 100644 docs/html/search/pages_3.js diff --git a/Doxyfile b/Doxyfile index d236f97..6d78dd0 100644 --- a/Doxyfile +++ b/Doxyfile @@ -2217,7 +2217,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = USE_RPI USE_HTTPS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/docs/html/_arduino_8h_source.html b/docs/html/_arduino_8h_source.html index 44ab59f..6934cde 100644 --- a/docs/html/_arduino_8h_source.html +++ b/docs/html/_arduino_8h_source.html @@ -115,8 +115,8 @@
32
33#if defined(_MSC_VER)
34// Temporary unsupported under Win/MSVC
-
35#define PROVIDE_HARDWARE_SETUP_SKIP
-
36#define PROVIDE_HARDWARE_WIFI_SKIP
+
35#define SKIP_HARDWARE_SETUP
+
36#define SKIP_HARDWARE_WIFI
37#endif
38
39#include "ArduinoAPI.h"
diff --git a/docs/html/_common_8h_source.html b/docs/html/_common_8h_source.html index 7b008a9..22643ae 100644 --- a/docs/html/_common_8h_source.html +++ b/docs/html/_common_8h_source.html @@ -155,117 +155,121 @@
72#define bit(b) (1UL << (b))
73#endif
74
-
75/* TODO: request for removal */
-
76// typedef bool boolean;
-
77// typedef uint8_t byte;
-
78// typedef uint16_t word;
-
79
-
80void init(void);
-
81void initVariant(void);
-
82
-
83#ifndef HOST
-
84int atexit(void (*func)()) __attribute__((weak));
-
85#endif
-
86int main() __attribute__((weak));
-
87
-
88#ifdef EXTENDED_PIN_MODE
-
89// Platforms who wnat to declare more than 256 pins need to define EXTENDED_PIN_MODE globally
-
90typedef uint32_t pin_size_t;
-
91#else
-
92typedef uint8_t pin_size_t;
-
93#endif
-
94
-
95void pinMode(pin_size_t pinNumber, PinMode pinMode);
-
96void digitalWrite(pin_size_t pinNumber, PinStatus status);
-
97PinStatus digitalRead(pin_size_t pinNumber);
-
98int analogRead(pin_size_t pinNumber);
-
99void analogReference(uint8_t mode);
-
100void analogWrite(pin_size_t pinNumber, int value);
-
101
-
102unsigned long millis(void);
-
103unsigned long micros(void);
-
104void delay(unsigned long);
-
105void delayMicroseconds(unsigned int us);
-
106unsigned long pulseIn(pin_size_t pin, uint8_t state, unsigned long timeout);
-
107unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout);
-
108
-
109void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val);
-
110uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder);
-
111
-
112void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode);
-
113void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void* param);
-
114void detachInterrupt(pin_size_t interruptNumber);
+
75#ifdef SKIP_LEGACY_TYPES
+
76/* TODO: request for removal */
+
77#else
+
78// Keep these legacy types as they expected to be defined by Arduino.h and may be used by user code
+
79typedef bool boolean;
+
80typedef uint8_t byte;
+
81typedef uint16_t word;
+
82#endif
+
83
+
84void init(void);
+
85void initVariant(void);
+
86
+
87#ifndef HOST
+
88int atexit(void (*func)()) __attribute__((weak));
+
89#endif
+
90int main() __attribute__((weak));
+
91
+
92#ifdef EXTENDED_PIN_MODE
+
93// Platforms who wnat to declare more than 256 pins need to define EXTENDED_PIN_MODE globally
+
94typedef uint32_t pin_size_t;
+
95#else
+
96typedef uint8_t pin_size_t;
+
97#endif
+
98
+
99void pinMode(pin_size_t pinNumber, PinMode pinMode);
+
100void digitalWrite(pin_size_t pinNumber, PinStatus status);
+
101PinStatus digitalRead(pin_size_t pinNumber);
+
102int analogRead(pin_size_t pinNumber);
+
103void analogReference(uint8_t mode);
+
104void analogWrite(pin_size_t pinNumber, int value);
+
105
+
106unsigned long millis(void);
+
107unsigned long micros(void);
+
108void delay(unsigned long);
+
109void delayMicroseconds(unsigned int us);
+
110unsigned long pulseIn(pin_size_t pin, uint8_t state, unsigned long timeout);
+
111unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout);
+
112
+
113void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val);
+
114uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder);
115
-
116void setup(void)__attribute__((weak));
-
117void loop(void)__attribute__((weak));
-
118
-
119long map(long, long, long, long, long);
-
120
-
121#ifdef __cplusplus
-
122} // extern "C"
-
123#endif
+
116void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode);
+
117void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void* param);
+
118void detachInterrupt(pin_size_t interruptNumber);
+
119
+
120void setup(void)__attribute__((weak));
+
121void loop(void)__attribute__((weak));
+
122
+
123long map(long, long, long, long, long);
124
125#ifdef __cplusplus
-
126 template<class T, class L>
-
127 auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
-
128 {
-
129 return (b < a) ? b : a;
-
130 }
-
131
-
132 template<class T, class L>
-
133 auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
-
134 {
-
135 return (a < b) ? b : a;
-
136 }
-
137#else
-
138#ifndef min
-
139#define min(a,b) \
-
140 ({ __typeof__ (a) _a = (a); \
-
141 __typeof__ (b) _b = (b); \
-
142 _a < _b ? _a : _b; })
-
143#endif
-
144#ifndef max
-
145#define max(a,b) \
-
146 ({ __typeof__ (a) _a = (a); \
-
147 __typeof__ (b) _b = (b); \
-
148 _a > _b ? _a : _b; })
-
149#endif
-
150#endif
-
151
-
152#ifdef __cplusplus
-
153
-
154// // WMath prototypes
-
155// long random(long);
-
156// long random(long, long);
-
157// void randomSeed(unsigned long);
-
158
-
159static long random(long max){
-
160 return rand() % max;
-
161}
+
126} // extern "C"
+
127#endif
+
128
+
129#ifdef __cplusplus
+
130 template<class T, class L>
+
131 auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
+
132 {
+
133 return (b < a) ? b : a;
+
134 }
+
135
+
136 template<class T, class L>
+
137 auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
+
138 {
+
139 return (a < b) ? b : a;
+
140 }
+
141#else
+
142#ifndef min
+
143#define min(a,b) \
+
144 ({ __typeof__ (a) _a = (a); \
+
145 __typeof__ (b) _b = (b); \
+
146 _a < _b ? _a : _b; })
+
147#endif
+
148#ifndef max
+
149#define max(a,b) \
+
150 ({ __typeof__ (a) _a = (a); \
+
151 __typeof__ (b) _b = (b); \
+
152 _a > _b ? _a : _b; })
+
153#endif
+
154#endif
+
155
+
156#ifdef __cplusplus
+
157
+
158// // WMath prototypes
+
159// long random(long);
+
160// long random(long, long);
+
161// void randomSeed(unsigned long);
162
-
163static long random(long min, long max){
-
164 long tmp = rand() % (max- min);
-
165 return tmp + min;
-
166}
-
167
-
168static void randomSeed(unsigned seed){
-
169 srand(seed);
+
163static long random(long max){
+
164 return rand() % max;
+
165}
+
166
+
167static long random(long min, long max){
+
168 long tmp = rand() % (max- min);
+
169 return tmp + min;
170}
171
-
172/* C++ prototypes */
-
173uint16_t makeWord(uint16_t w);
-
174uint16_t makeWord(uint8_t h, uint8_t l);
+
172static void randomSeed(unsigned seed){
+
173 srand(seed);
+
174}
175
-
176#define word(...) makeWord(__VA_ARGS__)
-
177
-
178unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
-
179unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
-
180
-
181void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
-
182void noTone(uint8_t _pin);
-
183
+
176/* C++ prototypes */
+
177uint16_t makeWord(uint16_t w);
+
178uint16_t makeWord(uint8_t h, uint8_t l);
+
179
+
180#define word(...) makeWord(__VA_ARGS__)
+
181
+
182unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
+
183unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
184
-
185#endif // __cplusplus
+
185void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
+
186void noTone(uint8_t _pin);
+
187
+
188
+
189#endif // __cplusplus