arduino_ci 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,13 +9,12 @@ Where possible, variable names from the Arduino library are used to avoid confli
9
9
 
10
10
  #include "ArduinoDefines.h"
11
11
 
12
+ #include "IPAddress.h"
12
13
  #include "WCharacter.h"
13
14
  #include "WString.h"
14
15
  #include "Print.h"
15
16
  #include "Stream.h"
16
17
  #include "HardwareSerial.h"
17
- #include "SPI.h"
18
- #include "Wire.h"
19
18
 
20
19
  typedef bool boolean;
21
20
  typedef uint8_t byte;
@@ -1,26 +1,126 @@
1
1
  #pragma once
2
+ #include "ArduinoDefines.h"
2
3
  #include <math.h>
3
4
 
4
- #define constrain(x,l,h) ((x)<(l)?(l):((x)>(h)?(h):(x)))
5
- #define map(x,inMin,inMax,outMin,outMax) (((x)-(inMin))*((outMax)-(outMin))/((inMax)-(inMin))+outMin)
5
+ #ifdef __cplusplus
6
6
 
7
- #define sq(x) ((x)*(x))
7
+ template <class Amt, class Low, class High>
8
+ auto constrain(const Amt &amt, const Low &low, const High &high)
9
+ -> decltype(amt < low ? low : (amt > high ? high : amt)) {
10
+ return (amt < low ? low : (amt > high ? high : amt));
11
+ }
8
12
 
9
- #define radians(deg) ((deg)*DEG_TO_RAD)
10
- #define degrees(rad) ((rad)*RAD_TO_DEG)
13
+ template <class X, class InMin, class InMax, class OutMin, class OutMax>
14
+ auto map(const X &x, const InMin &inMin, const InMax &inMax,
15
+ const OutMin &outMin, const OutMax &outMax)
16
+ -> decltype((x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin) {
17
+ return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
18
+ }
11
19
 
12
- #ifdef abs
13
- #undef abs
14
- #endif
15
- #define abs(x) ((x)>0?(x):-(x))
20
+ template <class T> auto radians(const T &deg) -> decltype(deg * DEG_TO_RAD) {
21
+ return deg * DEG_TO_RAD;
22
+ }
16
23
 
17
- #ifdef max
18
- #undef max
19
- #endif
20
- #define max(a,b) ((a)>(b)?(a):(b))
24
+ template <class T> auto degrees(const T &rad) -> decltype(rad * RAD_TO_DEG) {
25
+ return rad * RAD_TO_DEG;
26
+ }
21
27
 
22
- #ifdef min
23
- #undef min
24
- #endif
25
- #define min(a,b) ((a)<(b)?(a):(b))
28
+ template <class T> auto sq(const T &x) -> decltype(x * x) { return x * x; }
29
+
30
+ template <class T> auto abs(const T &x) -> decltype(x > 0 ? x : -x) {
31
+ return x > 0 ? x : -x;
32
+ }
33
+
34
+ template <class T, class L>
35
+ auto min(const T &a, const L &b) -> decltype((b < a) ? b : a) {
36
+ return (b < a) ? b : a;
37
+ }
38
+
39
+ template <class T, class L>
40
+ auto max(const T &a, const L &b) -> decltype((b < a) ? b : a) {
41
+ return (a < b) ? b : a;
42
+ }
43
+
44
+ #else // __cplusplus
45
+
46
+ #ifdef constrain
47
+ #undef constrain
48
+ #endif
49
+ #define constrain(amt, low, high) \
50
+ ({ \
51
+ __typeof__(amt) _amt = (amt); \
52
+ __typeof__(low) _low = (low); \
53
+ __typeof__(high) _high = (high); \
54
+ (amt < low ? low : (amt > high ? high : amt)); \
55
+ })
26
56
 
57
+ #ifdef map
58
+ #undef map
59
+ #endif
60
+ #define map(x, inMin, inMax, outMin, outMax) \
61
+ ({ \
62
+ __typeof__(x) _x = (x); \
63
+ __typeof__(inMin) _inMin = (inMin); \
64
+ __typeof__(inMax) _inMax = (inMax); \
65
+ __typeof__(outMin) _outMin = (outMin); \
66
+ __typeof__(outMax) _outMax = (outMax); \
67
+ (_x - _inMin) * (_outMax - _outMin) / (_inMax - _inMin) + _outMin; \
68
+ })
69
+
70
+ #ifdef radians
71
+ #undef radians
72
+ #endif
73
+ #define radians(deg) \
74
+ ({ \
75
+ __typeof__(deg) _deg = (deg); \
76
+ _deg *DEG_TO_RAD; \
77
+ })
78
+
79
+ #ifdef degrees
80
+ #undef degrees
81
+ #endif
82
+ #define degrees(rad) \
83
+ ({ \
84
+ __typeof__(rad) _rad = (rad); \
85
+ _rad *RAD_TO_DEG; \
86
+ })
87
+
88
+ #ifdef sq
89
+ #undef sq
90
+ #endif
91
+ #define sq(x) \
92
+ ({ \
93
+ __typeof__(x) _x = (x); \
94
+ _x *_x; \
95
+ })
96
+
97
+ #ifdef abs
98
+ #undef abs
99
+ #endif
100
+ #define abs(x) \
101
+ ({ \
102
+ __typeof__(x) _x = (x); \
103
+ _x > 0 ? _x : -_x; \
104
+ })
105
+
106
+ #ifdef min
107
+ #undef min
108
+ #endif
109
+ #define min(a, b) \
110
+ ({ \
111
+ __typeof__(a) _a = (a); \
112
+ __typeof__(b) _b = (b); \
113
+ _a < _b ? _a : _b; \
114
+ })
115
+
116
+ #ifdef max
117
+ #undef max
118
+ #endif
119
+ #define max(a, b) \
120
+ ({ \
121
+ __typeof__(a) _a = (a); \
122
+ __typeof__(b) _b = (b); \
123
+ _a > _b ? _a : _b; \
124
+ })
125
+
126
+ #endif
@@ -0,0 +1,26 @@
1
+ #pragma once
2
+
3
+ #include <Stream.h>
4
+
5
+ class Client : public Stream {
6
+ public:
7
+ Client() {
8
+ // The Stream mock defines a String buffer but never puts anyting in it!
9
+ if (!mGodmodeDataIn) {
10
+ mGodmodeDataIn = new String;
11
+ }
12
+ }
13
+ ~Client() {
14
+ if (mGodmodeDataIn) {
15
+ delete mGodmodeDataIn;
16
+ mGodmodeDataIn = nullptr;
17
+ }
18
+ }
19
+ virtual size_t write(uint8_t value) {
20
+ mGodmodeDataIn->concat(value);
21
+ return 1;
22
+ }
23
+
24
+ protected:
25
+ uint8_t *rawIPAddress(IPAddress &addr) { return addr.raw_address(); }
26
+ };
@@ -0,0 +1,64 @@
1
+ #pragma once
2
+
3
+ #include <cassert>
4
+ #include <inttypes.h>
5
+ #include <Godmode.h>
6
+
7
+ // Does the current board have EEPROM?
8
+ #ifndef EEPROM_SIZE
9
+ // In lieu of an "EEPROM.h not found" error for unsupported boards
10
+ #error "EEPROM library not available for your board"
11
+ #endif
12
+
13
+ class EEPROMClass {
14
+ private:
15
+ GodmodeState* state;
16
+ public:
17
+ // constructor
18
+ EEPROMClass() {
19
+ state = GODMODE();
20
+ }
21
+ // array subscript operator
22
+ uint8_t &operator[](const int index) {
23
+ assert(index < EEPROM_SIZE);
24
+ return state->eeprom[index];
25
+ }
26
+
27
+ uint8_t read(const int index) {
28
+ assert(index < EEPROM_SIZE);
29
+ return state->eeprom[index];
30
+ }
31
+
32
+ void write(const int index, const uint8_t value) {
33
+ assert(index < EEPROM_SIZE);
34
+ state->eeprom[index] = value;
35
+ }
36
+
37
+ void update(const int index, const uint8_t value) {
38
+ assert(index < EEPROM_SIZE);
39
+ state->eeprom[index] = value;
40
+ }
41
+
42
+ uint16_t length() { return EEPROM_SIZE; }
43
+
44
+ // read any object
45
+ template <typename T> T &get(const int index, T &object) {
46
+ uint8_t *ptr = (uint8_t *)&object;
47
+ for (int i = 0; i < sizeof(T); ++i) {
48
+ *ptr++ = read(index + i);
49
+ }
50
+ return object;
51
+ }
52
+
53
+ // write any object
54
+ template <typename T> const T &put(const int index, T &object) {
55
+ const uint8_t *ptr = (const uint8_t *)&object;
56
+ for (int i = 0; i < sizeof(T); ++i) {
57
+ write(index + i, *ptr++);
58
+ }
59
+ return object;
60
+ }
61
+ };
62
+
63
+ // global available in Godmode.cpp
64
+ extern EEPROMClass EEPROM;
@@ -113,3 +113,10 @@ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut);
113
113
 
114
114
  // defined in Wire.h
115
115
  TwoWire Wire = TwoWire();
116
+
117
+ #if defined(EEPROM_SIZE)
118
+ #include <EEPROM.h>
119
+ EEPROMClass EEPROM;
120
+ #endif
121
+
122
+ volatile uint8_t __ARDUINO_CI_SFR_MOCK[1024];
@@ -1,6 +1,8 @@
1
1
  #pragma once
2
2
  #include "ArduinoDefines.h"
3
+ #if defined(__AVR__)
3
4
  #include <avr/io.h>
5
+ #endif
4
6
  #include "WString.h"
5
7
  #include "PinHistory.h"
6
8
 
@@ -18,16 +20,29 @@ unsigned long micros();
18
20
 
19
21
  #define MOCK_PINS_COUNT 256
20
22
 
21
- #if defined(UBRR3H)
22
- #define NUM_SERIAL_PORTS 4
23
- #elif defined(UBRR2H)
24
- #define NUM_SERIAL_PORTS 3
25
- #elif defined(UBRR1H)
26
- #define NUM_SERIAL_PORTS 2
27
- #elif defined(UBRRH) || defined(UBRR0H)
28
- #define NUM_SERIAL_PORTS 1
23
+ #if (!defined NUM_SERIAL_PORTS)
24
+ #if defined(UBRR3H)
25
+ #define NUM_SERIAL_PORTS 4
26
+ #elif defined(UBRR2H)
27
+ #define NUM_SERIAL_PORTS 3
28
+ #elif defined(UBRR1H)
29
+ #define NUM_SERIAL_PORTS 2
30
+ #elif defined(UBRRH) || defined(UBRR0H)
31
+ #define NUM_SERIAL_PORTS 1
32
+ #else
33
+ #define NUM_SERIAL_PORTS 0
34
+ #endif
35
+ #endif
36
+
37
+ // different EEPROM implementations have different macros that leak out
38
+ #if !defined(EEPROM_SIZE) && defined(E2END) && (E2END)
39
+ // public value indicates that feature is available
40
+ #define EEPROM_SIZE (E2END + 1)
41
+ // local array size
42
+ #define _EEPROM_SIZE EEPROM_SIZE
29
43
  #else
30
- #define NUM_SERIAL_PORTS 0
44
+ // feature is not available but we want to have the array so other code compiles
45
+ #define _EEPROM_SIZE (0)
31
46
  #endif
32
47
 
33
48
  class GodmodeState {
@@ -43,6 +58,8 @@ class GodmodeState {
43
58
  uint8_t mode;
44
59
  };
45
60
 
61
+ uint8_t mmapPorts[MOCK_PINS_COUNT];
62
+
46
63
  static GodmodeState* instance;
47
64
 
48
65
  public:
@@ -54,6 +71,7 @@ class GodmodeState {
54
71
  struct PortDef serialPort[NUM_SERIAL_PORTS];
55
72
  struct InterruptDef interrupt[MOCK_PINS_COUNT]; // not sure how to get actual number
56
73
  struct PortDef spi;
74
+ uint8_t eeprom[_EEPROM_SIZE];
57
75
 
58
76
  void resetPins() {
59
77
  for (int i = 0; i < MOCK_PINS_COUNT; ++i) {
@@ -87,12 +105,28 @@ class GodmodeState {
87
105
  spi.readDelayMicros = 0;
88
106
  }
89
107
 
108
+ void resetMmapPorts() {
109
+ for (int i = 0; i < MOCK_PINS_COUNT; ++i) {
110
+ mmapPorts[i] = 1;
111
+ }
112
+ }
113
+
114
+ void resetEEPROM() {
115
+ #if defined(EEPROM_SIZE)
116
+ for(int i = 0; i < EEPROM_SIZE; ++i) {
117
+ eeprom[i] = 255;
118
+ }
119
+ #endif
120
+ }
121
+
90
122
  void reset() {
91
123
  resetClock();
92
124
  resetPins();
93
125
  resetInterrupts();
94
126
  resetPorts();
95
127
  resetSPI();
128
+ resetMmapPorts();
129
+ resetEEPROM();
96
130
  seed = 1;
97
131
  }
98
132
 
@@ -112,6 +146,9 @@ class GodmodeState {
112
146
  return instance->micros;
113
147
  }
114
148
 
149
+ uint8_t* pMmapPort(uint8_t port) { return &mmapPorts[port]; }
150
+ uint8_t mmapPortValue(uint8_t port) { return mmapPorts[port]; }
151
+
115
152
  // C++ 11, declare as public for better compiler error messages
116
153
  GodmodeState(GodmodeState const&) = delete;
117
154
  void operator=(GodmodeState const&) = delete;
@@ -139,5 +176,17 @@ void detachInterrupt(uint8_t interrupt);
139
176
  inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) {}
140
177
  inline void noTone(uint8_t _pin) {}
141
178
 
179
+ // These definitions allow the following to compile (see issue #193):
180
+ // https://github.com/arduino-libraries/Ethernet/blob/master/src/utility/w5100.h:341
181
+ // we allow one byte per port which "wastes" 224 bytes, but makes the code easier
182
+ #if defined(__AVR__)
183
+ #define digitalPinToBitMask(pin) (1)
184
+ #define digitalPinToPort(pin) (pin)
185
+ #define portInputRegister(port) (GODMODE()->pMmapPort(port))
186
+ #define portOutputRegister(port) (GODMODE()->pMmapPort(port))
187
+ #else
188
+ // we don't (yet) support other boards
189
+ #endif
190
+
142
191
 
143
192
  GodmodeState* GODMODE();
@@ -44,19 +44,19 @@ class HardwareSerial : public StreamTape
44
44
  operator bool() { return true; }
45
45
  };
46
46
 
47
- #if defined(UBRRH) || defined(UBRR0H)
47
+ #if NUM_SERIAL_PORTS >= 1
48
48
  extern HardwareSerial Serial;
49
49
  #define HAVE_HWSERIAL0
50
50
  #endif
51
- #if defined(UBRR1H)
51
+ #if NUM_SERIAL_PORTS >= 2
52
52
  extern HardwareSerial Serial1;
53
53
  #define HAVE_HWSERIAL1
54
54
  #endif
55
- #if defined(UBRR2H)
55
+ #if NUM_SERIAL_PORTS >= 3
56
56
  extern HardwareSerial Serial2;
57
57
  #define HAVE_HWSERIAL2
58
58
  #endif
59
- #if defined(UBRR3H)
59
+ #if NUM_SERIAL_PORTS >= 4
60
60
  extern HardwareSerial Serial3;
61
61
  #define HAVE_HWSERIAL3
62
62
  #endif
@@ -0,0 +1,59 @@
1
+ #pragma once
2
+
3
+ #include <stdint.h>
4
+
5
+ class IPAddress {
6
+ private:
7
+ union {
8
+ uint8_t bytes[4];
9
+ uint32_t dword;
10
+ operator uint8_t *() const { return (uint8_t *)bytes; }
11
+ } _address;
12
+
13
+ public:
14
+ // Constructors
15
+ IPAddress() : IPAddress(0, 0, 0, 0) {}
16
+ IPAddress(uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4) {
17
+ _address.bytes[0] = octet1;
18
+ _address.bytes[1] = octet2;
19
+ _address.bytes[2] = octet3;
20
+ _address.bytes[3] = octet4;
21
+ }
22
+ IPAddress(uint32_t dword) { _address.dword = dword; }
23
+ IPAddress(const uint8_t bytes[]) {
24
+ _address.bytes[0] = bytes[0];
25
+ _address.bytes[1] = bytes[1];
26
+ _address.bytes[2] = bytes[2];
27
+ _address.bytes[3] = bytes[3];
28
+ }
29
+ IPAddress(unsigned long dword) { _address.dword = (uint32_t)dword; }
30
+
31
+ // Accessors
32
+ uint32_t asWord() const { return _address.dword; }
33
+ uint8_t *raw_address() { return _address.bytes; }
34
+
35
+ // Comparisons
36
+ bool operator==(const IPAddress &rhs) const {
37
+ return _address.dword == rhs.asWord();
38
+ }
39
+
40
+ bool operator!=(const IPAddress &rhs) const {
41
+ return _address.dword != rhs.asWord();
42
+ }
43
+
44
+ // Indexing
45
+ uint8_t operator[](int index) const { return _address.bytes[index]; }
46
+ uint8_t &operator[](int index) { return _address.bytes[index]; }
47
+
48
+ // Conversions
49
+ operator uint32_t() const { return _address.dword; };
50
+
51
+ friend class EthernetClass;
52
+ friend class UDP;
53
+ friend class Client;
54
+ friend class Server;
55
+ friend class DhcpClass;
56
+ friend class DNSClient;
57
+ };
58
+
59
+ const IPAddress INADDR_NONE(0, 0, 0, 0);