Skip to content

Fixes #144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
1 change: 1 addition & 0 deletions SampleProjects/TestSomething/test/godmode.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <ArduinoUnitTests.h>
#include <Arduino.h>
#include <SPI.h>
#include "fibonacciClock.h"

GodmodeState* state = GODMODE();
Expand Down
2 changes: 0 additions & 2 deletions cpp/arduino/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ Where possible, variable names from the Arduino library are used to avoid confli
#include "Print.h"
#include "Stream.h"
#include "HardwareSerial.h"
#include "SPI.h"
#include "Wire.h"

typedef bool boolean;
typedef uint8_t byte;
Expand Down
24 changes: 14 additions & 10 deletions cpp/arduino/Godmode.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once
#include "ArduinoDefines.h"
#if defined(__AVR__)
#include <avr/io.h>
#endif
#include "WString.h"
#include "PinHistory.h"

Expand All @@ -18,16 +20,18 @@ unsigned long micros();

#define MOCK_PINS_COUNT 256

#if defined(UBRR3H)
#define NUM_SERIAL_PORTS 4
#elif defined(UBRR2H)
#define NUM_SERIAL_PORTS 3
#elif defined(UBRR1H)
#define NUM_SERIAL_PORTS 2
#elif defined(UBRRH) || defined(UBRR0H)
#define NUM_SERIAL_PORTS 1
#else
#define NUM_SERIAL_PORTS 0
#if (!defined NUM_SERIAL_PORTS)
#if defined(UBRR3H)
#define NUM_SERIAL_PORTS 4
#elif defined(UBRR2H)
#define NUM_SERIAL_PORTS 3
#elif defined(UBRR1H)
#define NUM_SERIAL_PORTS 2
#elif defined(UBRRH) || defined(UBRR0H)
#define NUM_SERIAL_PORTS 1
#else
#define NUM_SERIAL_PORTS 0
#endif
#endif

class GodmodeState {
Expand Down
8 changes: 4 additions & 4 deletions cpp/arduino/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@ class HardwareSerial : public StreamTape
operator bool() { return true; }
};

#if defined(UBRRH) || defined(UBRR0H)
#if NUM_SERIAL_PORTS >= 1
extern HardwareSerial Serial;
#define HAVE_HWSERIAL0
#endif
#if defined(UBRR1H)
#if NUM_SERIAL_PORTS >= 2
extern HardwareSerial Serial1;
#define HAVE_HWSERIAL1
#endif
#if defined(UBRR2H)
#if NUM_SERIAL_PORTS >= 3
extern HardwareSerial Serial2;
#define HAVE_HWSERIAL2
#endif
#if defined(UBRR3H)
#if NUM_SERIAL_PORTS >= 4
extern HardwareSerial Serial3;
#define HAVE_HWSERIAL3
#endif
Expand Down
6 changes: 5 additions & 1 deletion cpp/arduino/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,14 @@ class SPIClass: public ObservableDataStream {
uint16_t transfer16(uint16_t data) {
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
in.val = data;
#if defined(SPCR) && defined(DORD)
if (!(SPCR & (1 << DORD))) {
out.msb = transfer(in.msb);
out.lsb = transfer(in.lsb);
} else {
}
else
#endif
{
out.lsb = transfer(in.lsb);
out.msb = transfer(in.msb);
}
Expand Down
122 changes: 76 additions & 46 deletions cpp/arduino/avr/pgmspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ out = externs.map {|l| l.split("(")[0].split(" ")[-1].gsub("*", "") }.uniq
out.each { |l| puts d(l) }
*/

#include <avr/io.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>

#define PROGMEM

Expand All @@ -27,20 +29,25 @@ out.each { |l| puts d(l) }
#define PGM_VOID_P const void *
#endif

// These are normally 32-bit, but here use (u)intptr_t to ensure a pointer can
// always be safely cast to these types.
typedef intptr_t int_farptr_t;
typedef uintptr_t uint_farptr_t;

// everything's a no-op
#define PSTR(s) ((const char *)(s))

#define pgm_read_byte_near(address_short) (* (const uint8_t *) (address_short) )
#define pgm_read_word_near(address_short) (* (const uint16_t *) (address_short) )
#define pgm_read_dword_near(address_short) (* (const uint32_t *) (address_short) )
#define pgm_read_float_near(address_short) (* (const float *) (address_short) )
#define pgm_read_ptr_near(address_short) (* (const void *) (address_short) )
#define pgm_read_ptr_near(address_short) (* (const void **) (address_short) )

#define pgm_read_byte_far(address_long) (* (const uint8_t *) (address_long) )
#define pgm_read_word_far(address_long) (* (const uint16_t *) (address_long) )
#define pgm_read_dword_far(address_long) (* (const uint32_t *) (address_long) )
#define pgm_read_float_far(address_long) (* (const float *) (address_long) )
#define pgm_read_ptr_far(address_long) (* (const void *) (address_long) )
#define pgm_read_ptr_far(address_long) (* (const void **) (address_long) )

#define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
#define pgm_read_word(address_short) pgm_read_word_near(address_short)
Expand All @@ -50,46 +57,69 @@ out.each { |l| puts d(l) }

#define pgm_get_far_address(var) ( (uint_farptr_t) (&(var)) )

#define memchr_P(...) ::memchr(__VA_ARGS__)
#define memcmp_P(...) ::memcmp(__VA_ARGS__)
#define memccpy_P(...) ::memccpy(__VA_ARGS__)
#define memcpy_P(...) ::memcpy(__VA_ARGS__)
#define memmem_P(...) ::memmem(__VA_ARGS__)
#define memrchr_P(...) ::memrchr(__VA_ARGS__)
#define strcat_P(...) ::strcat(__VA_ARGS__)
#define strchr_P(...) ::strchr(__VA_ARGS__)
#define strchrnul_P(...) ::strchrnul(__VA_ARGS__)
#define strcmp_P(...) ::strcmp(__VA_ARGS__)
#define strcpy_P(...) ::strcpy(__VA_ARGS__)
#define strcasecmp_P(...) ::strcasecmp(__VA_ARGS__)
#define strcasestr_P(...) ::strcasestr(__VA_ARGS__)
#define strcspn_P(...) ::strcspn(__VA_ARGS__)
#define strlcat_P(...) ::strlcat(__VA_ARGS__)
#define strlcpy_P(...) ::strlcpy(__VA_ARGS__)
#define strnlen_P(...) ::strnlen(__VA_ARGS__)
#define strncmp_P(...) ::strncmp(__VA_ARGS__)
#define strncasecmp_P(...) ::strncasecmp(__VA_ARGS__)
#define strncat_P(...) ::strncat(__VA_ARGS__)
#define strncpy_P(...) ::strncpy(__VA_ARGS__)
#define strpbrk_P(...) ::strpbrk(__VA_ARGS__)
#define strrchr_P(...) ::strrchr(__VA_ARGS__)
#define strsep_P(...) ::strsep(__VA_ARGS__)
#define strspn_P(...) ::strspn(__VA_ARGS__)
#define strstr_P(...) ::strstr(__VA_ARGS__)
#define strtok_P(...) ::strtok(__VA_ARGS__)
#define strtok_P(...) ::strtok(__VA_ARGS__)
#define strlen_P(...) ::strlen(__VA_ARGS__)
#define strnlen_P(...) ::strnlen(__VA_ARGS__)
#define memcpy_P(...) ::memcpy(__VA_ARGS__)
#define strcpy_P(...) ::strcpy(__VA_ARGS__)
#define strncpy_P(...) ::strncpy(__VA_ARGS__)
#define strcat_P(...) ::strcat(__VA_ARGS__)
#define strlcat_P(...) ::strlcat(__VA_ARGS__)
#define strncat_P(...) ::strncat(__VA_ARGS__)
#define strcmp_P(...) ::strcmp(__VA_ARGS__)
#define strncmp_P(...) ::strncmp(__VA_ARGS__)
#define strcasecmp_P(...) ::strcasecmp(__VA_ARGS__)
#define strncasecmp_P(...) ::strncasecmp(__VA_ARGS__)
#define strstr_P(...) ::strstr(__VA_ARGS__)
#define strlcpy_P(...) ::strlcpy(__VA_ARGS__)
#define memcmp_P(...) ::memcmp(__VA_ARGS__)
inline const void * memchr_P(const void *s, int val, size_t len) { return memchr(s, val, len); }
inline int memcmp_P(const void *s1, const void *s2, size_t len) { return memcmp(s1, s2, len); }
inline void *memcpy_P(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); }
inline char *strcat_P(char *dest, const char *src) { return strcat(dest, src); }
inline const char *strchr_P(const char *s, int val) { return strchr(s, val); }
inline int strcmp_P(const char *s1, const char *s2) { return strcmp(s1, s2); }
inline char *strcpy_P(char *dest, const char *src) { return strcpy(dest, src); }
inline size_t strcspn_P(const char *s, const char *reject) { return strcspn(s, reject); }
// strlcat and strlcpy are AVR-specific and not entirely trivial to reimplement using strncat it seems
//inline size_t strlcat_P(char *dst, const char *src, size_t siz) { return strlcat(dst, src, siz); }
//inline size_t strlcpy_P(char *dst, const char *src, size_t siz) { return strlcpy(dst, src, siz); }
//inline size_t strlcat_PF(char *dst, uint_farptr_t src, size_t n) { return strlcat(dst, (const char*)src, n); }
//inline size_t strlcpy_PF(char *dst, uint_farptr_t src, size_t siz) { return strlcpy(dst, (const char*)src, siz); }
inline int strncmp_P(const char *s1, const char *s2, size_t n) { return strncmp(s1, s2, n); }
inline char *strncat_P(char *dest, const char *src, size_t len) { return strncat(dest, src, len); }
inline char *strncpy_P(char *dest, const char *src, size_t n) { return strncpy(dest, src, n); }
inline char *strpbrk_P(const char *s, const char *accept) { return (char*)strpbrk(s, accept); }
inline const char *strrchr_P(const char *s, int val) { return strrchr(s, val); }
inline size_t strspn_P(const char *s, const char *accept) { return strspn(s, accept); }
inline char *strstr_P(const char *s1, const char *s2) { return (char*)strstr(s1, s2); }
inline char *strtok_P(char *s, const char * delim) { return strtok(s, delim); }
inline size_t strlen_PF(uint_farptr_t s) { return strlen((char*)s); }
inline void *memcpy_PF(void *dest, uint_farptr_t src, size_t n) { return memcpy(dest, (const char*)src, n); }
inline char *strcpy_PF(char *dst, uint_farptr_t src) { return strcpy(dst, (const char*)src); }
inline char *strncpy_PF(char *dst, uint_farptr_t src, size_t n) { return strncpy(dst, (const char*)src, n); }
inline char *strcat_PF(char *dst, uint_farptr_t src) { return strcat(dst, (const char*)src); }
inline char *strncat_PF(char *dst, uint_farptr_t src, size_t n) { return strncat(dst, (const char*)src, n); }
inline int strcmp_PF(const char *s1, uint_farptr_t s2) { return strcmp(s1, (const char*)s2); }
inline int strncmp_PF(const char *s1, uint_farptr_t s2, size_t n) { return strncmp(s1, (const char*)s2, n); }
inline char *strstr_PF(const char *s1, uint_farptr_t s2) { return (char*)strstr(s1, (const char*)s2); }
inline int memcmp_PF(const void *s1, uint_farptr_t s2, size_t len) { return memcmp(s1, (const char*)s2, len); }
inline size_t strlen_P(const char *src) { return strlen(src); }

// TODO: These functions cannot be found on the CYGWIN test build for
// some reason, so disable them for now. Most of these are less common
// and/or GNU-specific addons anyway
//inline void *memccpy_P(void *dest, const void *src, int val, size_t len) { return memccpy(dest, src, val, len); }
//inline void *memmem_P(const void *s1, size_t len1, const void *s2, size_t len2) { return memmem(s1, len1, s2, len2); }
//inline const void *memrchr_P(const void *src, int val, size_t len) { return memrchr(src, val, len); }
//inline const char *strchrnul_P(const char *s, int c) { return strchrnul(s, c); }
//inline int strcasecmp_P(const char *s1, const char *s2) { return strcasecmp(s1, s2); }
//inline char *strcasestr_P(const char *s1, const char *s2) { return (char*)strcasestr(s1, s2); }
//inline int strncasecmp_P(const char *s1, const char *s2, size_t n) { return strncasecmp(s1, s2, n); }
//inline char *strsep_P(char **sp, const char *delim) { return strsep(sp, delim); }
//inline char *strtok_r_P(char *string, const char *delim, char **last) { return strtok_r(string, delim, last); }
//inline int strcasecmp_PF(const char *s1, uint_farptr_t s2) { return strcasecmp(s1, (const char*)s2); }
//inline int strncasecmp_PF(const char *s1, uint_farptr_t s2, size_t n) { return strncasecmp(s1, (const char*)s2, n); }
//inline size_t strnlen_P(uint_farptr_t s, size_t len) { return strnlen((char*)s, len); }

// These are normally defined by stdio.h on AVR, but we cannot override that
// include file (at least not without no longer being able to include the
// original as well), so just define these here. It seems likely that any
// sketch that uses these progmem-stdio functions will also include pgmspace.h
inline int vfprintf_P(FILE *stream, const char *__fmt, va_list __ap) { return vfprintf(stream, __fmt, __ap); }
inline int printf_P(const char *__fmt, ...) { va_list args; va_start(args, __fmt); return vprintf(__fmt, args); va_end(args); }
inline int sprintf_P(char *s, const char *__fmt, ...) { va_list args; va_start(args, __fmt); return sprintf(s, __fmt, args); va_end(args); }
inline int snprintf_P(char *s, size_t __n, const char *__fmt, ...) { va_list args; va_start(args, __fmt); return vsnprintf(s, __n, __fmt, args); va_end(args); }
inline int vsprintf_P(char *s, const char *__fmt, va_list ap) { return vsprintf(s, __fmt, ap); }
inline int vsnprintf_P(char *s, size_t __n, const char *__fmt, va_list ap) { return vsnprintf(s, __n, __fmt, ap); }
inline int fprintf_P(FILE *stream, const char *__fmt, ...) { va_list args; va_start(args, __fmt); return vfprintf(stream, __fmt, args); va_end(args); }
inline int fputs_P(const char *str, FILE *__stream) { return fputs(str, __stream); }
inline int puts_P(const char *str) { return puts(str); }
inline int vfscanf_P(FILE *stream, const char *__fmt, va_list __ap) { return vfscanf(stream, __fmt, __ap); }
inline int fscanf_P(FILE *stream, const char *__fmt, ...) { va_list args; va_start(args, __fmt); return vfscanf(stream, __fmt, args); va_end(args); }
inline int scanf_P(const char *__fmt, ...) { va_list args; va_start(args, __fmt); return vscanf(__fmt, args); va_end(args); }
inline int sscanf_P(const char *buf, const char *__fmt, ...) { va_list args; va_start(args, __fmt); return vsscanf(buf, __fmt, args); va_end(args); }
2 changes: 1 addition & 1 deletion exe/arduino_ci_remote.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def perform_unit_tests(file_config)
config.allowable_unittest_files(cpp_library.test_files).each do |unittest_path|
unittest_name = unittest_path.basename.to_s
compilers.each do |gcc_binary|
attempt_multiline("Unit testing #{unittest_name} with #{gcc_binary}") do
attempt_multiline("Unit testing #{unittest_name} with #{gcc_binary} for #{p}") do
exe = cpp_library.build_for_test_with_configuration(
unittest_path,
config.aux_libraries_for_unittest,
Expand Down
52 changes: 49 additions & 3 deletions misc/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ platforms:
gcc:
features:
defines:
- __AVR__
- __AVR_ATmega328P__
- ARDUINO_ARCH_AVR
- ARDUINO_AVR_UNO
warnings:
flags:
due:
Expand All @@ -31,7 +34,10 @@ platforms:
gcc:
features:
defines:
- __AVR_ATmega328__
- __SAM3X8E__
- ARDUINO_ARCH_SAM
- ARDUINO_SAM_DUE
- NUM_SERIAL_PORTS=4
warnings:
flags:
zero:
Expand All @@ -40,8 +46,11 @@ platforms:
gcc:
features:
defines:
- __SAMD21G18A__
- ARDUINO_SAMD_ZERO
- __SAMD21G18A__
- ARDUINO_ARCH_SAMD
- ARDUINO_SAMD_ZERO
# This also has SerialUSB, which is not included here.
- NUM_SERIAL_PORTS=2
warnings:
flags:
esp32:
Expand All @@ -50,6 +59,10 @@ platforms:
gcc:
features:
defines:
- ESP32
- ARDUINO_ARCH_ESP32
- ARDUINO_FEATHER_ESP32
- NUM_SERIAL_PORTS=3
warnings:
flags:
esp8266:
Expand All @@ -58,6 +71,10 @@ platforms:
gcc:
features:
defines:
- ESP8266
- ARDUINO_ARCH_ESP8266
- ARDUINO_ESP8266_ESP12
- NUM_SERIAL_PORTS=2
warnings:
flags:
leonardo:
Expand All @@ -66,7 +83,10 @@ platforms:
gcc:
features:
defines:
- __AVR__
- __AVR_ATmega32U4__
- ARDUINO_ARCH_AVR
- ARDUINO_AVR_LEONARDO
warnings:
flags:
trinket:
Expand All @@ -75,6 +95,10 @@ platforms:
gcc:
features:
defines:
- __AVR__
- __AVR_ATtiny85__
- ARDUINO_ARCH_AVR
- ARDUINO_AVR_TRINKET5
warnings:
flags:
gemma:
Expand All @@ -83,6 +107,10 @@ platforms:
gcc:
features:
defines:
- __AVR__
- __AVR_ATtiny85__
- ARDUINO_ARCH_AVR
- ARDUINO_AVR_GEMMA
warnings:
flags:
m4:
Expand All @@ -91,6 +119,12 @@ platforms:
gcc:
features:
defines:
- __SAMD51__
- __SAMD51J19A__
- ARDUINO_ARCH_SAMD
- ARDUINO_METRO_M4
# Serial is actually USB virtual serial, not HardwareSerial
- NUM_SERIAL_PORTS=2
warnings:
flags:
mega2560:
Expand All @@ -99,7 +133,10 @@ platforms:
gcc:
features:
defines:
- __AVR__
- __AVR_ATmega2560__
- ARDUINO_ARCH_AVR
- ARDUINO_AVR_MEGA2560
warnings:
flags:
cplayClassic:
Expand All @@ -108,6 +145,10 @@ platforms:
gcc:
features:
defines:
- __AVR__
- __AVR_ATmega32U4__
- ARDUINO_ARCH_AVR
- ARDUINO_AVR_CIRCUITPLAY
warnings:
flags:
cplayExpress:
Expand All @@ -116,6 +157,11 @@ platforms:
gcc:
features:
defines:
- __SAMD21G18A__
- ARDUINO_ARCH_SAMD
- ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS
# Serial is actually an alias of SerialUSB, not a HardwareSerial
- NUM_SERIAL_PORTS=2
warnings:
flags:

Expand Down