arduino_ci 0.3.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +125 -69
- data/REFERENCE.md +711 -0
- data/cpp/arduino/Arduino.h +1 -7
- data/cpp/arduino/ArduinoDefines.h +3 -0
- data/cpp/arduino/AvrMath.h +117 -17
- data/cpp/arduino/Client.h +27 -0
- data/cpp/arduino/EEPROM.h +64 -0
- data/cpp/arduino/Godmode.cpp +7 -0
- data/cpp/arduino/Godmode.h +121 -15
- data/cpp/arduino/HardwareSerial.h +4 -4
- data/cpp/arduino/IPAddress.h +59 -0
- data/cpp/arduino/Print.h +9 -12
- data/cpp/arduino/Printable.h +8 -0
- data/cpp/arduino/SPI.h +11 -3
- data/cpp/arduino/Server.h +5 -0
- data/cpp/arduino/Udp.h +27 -0
- data/cpp/arduino/Wire.h +197 -77
- data/cpp/arduino/avr/io.h +10 -1
- data/cpp/arduino/avr/pgmspace.h +76 -46
- data/cpp/unittest/ArduinoUnitTests.h +32 -0
- data/cpp/unittest/Assertion.h +54 -26
- data/cpp/unittest/Compare.h +58 -51
- data/cpp/unittest/OstreamHelpers.h +4 -0
- data/exe/arduino_ci.rb +538 -0
- data/exe/arduino_ci_remote.rb +2 -393
- data/exe/arduino_library_location.rb +2 -2
- data/exe/ensure_arduino_installation.rb +7 -1
- data/lib/arduino_ci.rb +1 -0
- data/lib/arduino_ci/arduino_backend.rb +238 -0
- data/lib/arduino_ci/arduino_downloader.rb +43 -73
- data/lib/arduino_ci/arduino_downloader_linux.rb +17 -55
- data/lib/arduino_ci/arduino_downloader_osx.rb +21 -33
- data/lib/arduino_ci/arduino_downloader_windows.rb +11 -53
- data/lib/arduino_ci/arduino_installation.rb +18 -80
- data/lib/arduino_ci/ci_config.rb +8 -11
- data/lib/arduino_ci/cpp_library.rb +250 -59
- data/lib/arduino_ci/host.rb +59 -4
- data/lib/arduino_ci/library_properties.rb +101 -0
- data/lib/arduino_ci/version.rb +1 -1
- data/misc/default.yml +57 -6
- metadata +19 -87
- data/cpp/arduino/Arduino.h.orig +0 -143
- data/exe/libasan.rb +0 -29
- data/lib/arduino_ci/arduino_cmd.rb +0 -332
- data/lib/arduino_ci/arduino_cmd_linux.rb +0 -17
- data/lib/arduino_ci/arduino_cmd_linux_builder.rb +0 -19
- data/lib/arduino_ci/arduino_cmd_osx.rb +0 -17
- data/lib/arduino_ci/arduino_cmd_windows.rb +0 -17
data/cpp/arduino/Arduino.h
CHANGED
@@ -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;
|
@@ -37,9 +36,6 @@ typedef uint8_t byte;
|
|
37
36
|
#define highByte(w) ((uint8_t) ((w) >> 8))
|
38
37
|
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
39
38
|
|
40
|
-
// Arduino defines this
|
41
|
-
#define _NOP() do { 0; } while (0)
|
42
|
-
|
43
39
|
// might as well use that NO-op macro for these, while unit testing
|
44
40
|
// you need interrupts? interrupt yourself
|
45
41
|
#define yield() _NOP()
|
@@ -71,5 +67,3 @@ inline unsigned int makeWord(unsigned int w) { return w; }
|
|
71
67
|
inline unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }
|
72
68
|
|
73
69
|
#define word(...) makeWord(__VA_ARGS__)
|
74
|
-
|
75
|
-
|
@@ -92,3 +92,6 @@
|
|
92
92
|
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
93
93
|
#define LED_BUILTIN 13
|
94
94
|
#endif
|
95
|
+
|
96
|
+
// Arduino defines this
|
97
|
+
#define _NOP() do { 0; } while (0)
|
data/cpp/arduino/AvrMath.h
CHANGED
@@ -1,26 +1,126 @@
|
|
1
1
|
#pragma once
|
2
|
+
#include "ArduinoDefines.h"
|
2
3
|
#include <math.h>
|
3
4
|
|
4
|
-
#
|
5
|
-
#define map(x,inMin,inMax,outMin,outMax) (((x)-(inMin))*((outMax)-(outMin))/((inMax)-(inMin))+outMin)
|
5
|
+
#ifdef __cplusplus
|
6
6
|
|
7
|
-
|
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
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
#define abs(x) ((x)>0?(x):-(x))
|
20
|
+
template <class T> auto radians(const T °) -> decltype(deg * DEG_TO_RAD) {
|
21
|
+
return deg * DEG_TO_RAD;
|
22
|
+
}
|
16
23
|
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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,27 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <Stream.h>
|
4
|
+
#include <IPAddress.h>
|
5
|
+
|
6
|
+
class Client : public Stream {
|
7
|
+
public:
|
8
|
+
Client() {
|
9
|
+
// The Stream mock defines a String buffer but never puts anyting in it!
|
10
|
+
if (!mGodmodeDataIn) {
|
11
|
+
mGodmodeDataIn = new String;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
~Client() {
|
15
|
+
if (mGodmodeDataIn) {
|
16
|
+
delete mGodmodeDataIn;
|
17
|
+
mGodmodeDataIn = nullptr;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
virtual size_t write(uint8_t value) {
|
21
|
+
mGodmodeDataIn->concat(value);
|
22
|
+
return 1;
|
23
|
+
}
|
24
|
+
|
25
|
+
protected:
|
26
|
+
uint8_t *rawIPAddress(IPAddress &addr) { return addr.raw_address(); }
|
27
|
+
};
|
@@ -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;
|
data/cpp/arduino/Godmode.cpp
CHANGED
@@ -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];
|
data/cpp/arduino/Godmode.h
CHANGED
@@ -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
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
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
|
-
|
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;
|
@@ -123,21 +160,90 @@ class GodmodeState {
|
|
123
160
|
};
|
124
161
|
|
125
162
|
// io pins
|
126
|
-
|
127
|
-
|
163
|
+
inline void pinMode(uint8_t pin, uint8_t mode) { _NOP(); }
|
164
|
+
inline void analogReference(uint8_t mode) { _NOP(); }
|
128
165
|
|
129
166
|
void digitalWrite(uint8_t, uint8_t);
|
130
167
|
int digitalRead(uint8_t);
|
131
168
|
int analogRead(uint8_t);
|
132
169
|
void analogWrite(uint8_t, int);
|
133
|
-
|
134
|
-
|
170
|
+
inline void analogReadResolution(uint8_t bits) { _NOP(); }
|
171
|
+
inline void analogWriteResolution(uint8_t bits) { _NOP(); }
|
135
172
|
void attachInterrupt(uint8_t interrupt, void ISR(void), uint8_t mode);
|
136
173
|
void detachInterrupt(uint8_t interrupt);
|
137
174
|
|
138
175
|
// TODO: issue #26 to track the commanded state here
|
139
|
-
inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) {}
|
140
|
-
inline void noTone(uint8_t _pin) {}
|
176
|
+
inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) { throw "Not Yet Implemented"; }
|
177
|
+
inline void noTone(uint8_t _pin) { throw "Not Yet Implemented"; }
|
178
|
+
inline uint8_t pulseIn(uint8_t _pin, uint8_t _value, uint32_t _timeout) { throw "Not Yet Implemented"; }
|
179
|
+
inline uint8_t pulseIn(uint8_t pin, uint8_t value) { return pulseIn(pin, value, (uint32_t) 1000000); }
|
180
|
+
inline uint32_t pulseInLong(uint8_t _pin, uint8_t _value, uint32_t _timeout) { throw "Not Yet Implemented"; }
|
181
|
+
inline uint32_t pulseInLong(uint8_t pin, uint8_t value) { return pulseInLong(pin, value, (uint32_t) 1000000); }
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Shifts in a byte of data one bit at a time.
|
185
|
+
*
|
186
|
+
* Starts from either the most (i.e. the leftmost) or least (rightmost)
|
187
|
+
* significant bit. For each bit, the clock pin is pulled high, the next bit is
|
188
|
+
* read from the data line, and then the clock pin is taken low.
|
189
|
+
*
|
190
|
+
* @param dataPin the pin on which to input each bit
|
191
|
+
* @param clockPin the pin to toggle to signal a read from dataPin
|
192
|
+
* @param bitOrder which order to shift in the bits; either MSBFIRST or LSBFIRST. B=Bit, not byte
|
193
|
+
*
|
194
|
+
* @return The value read
|
195
|
+
*/
|
196
|
+
inline uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, bool bitOrder) {
|
197
|
+
bool mFirst = bitOrder == MSBFIRST;
|
198
|
+
uint8_t ret = 0x00;
|
199
|
+
for (uint8_t i = 0, mask = (bitOrder == MSBFIRST ? 0x80 : 0x01); i < 8; ++i) {
|
200
|
+
digitalWrite(clockPin, HIGH);
|
201
|
+
uint8_t setBit = mFirst ? 0x80 : 0x01;
|
202
|
+
uint8_t val = (mFirst ? (setBit >> i) : (setBit << i));
|
203
|
+
ret = ret | (digitalRead(dataPin) ? val : 0x00);
|
204
|
+
digitalWrite(clockPin, LOW);
|
205
|
+
}
|
206
|
+
return ret;
|
207
|
+
}
|
208
|
+
|
209
|
+
/**
|
210
|
+
* Shifts out a byte of data one bit at a time.
|
211
|
+
*
|
212
|
+
* Starts from either the most (i.e. the leftmost) or least (rightmost)
|
213
|
+
* significant bit. Each bit is written in turn to a data pin, after which a
|
214
|
+
* clock pin is pulsed (taken high, then low) to indicate that the bit is
|
215
|
+
* available.
|
216
|
+
*
|
217
|
+
* @param dataPin the pin on which to input each bit
|
218
|
+
* @param clockPin the pin to toggle to signal a write from dataPin
|
219
|
+
* @param bitOrder which order to shift in the bits; either MSBFIRST or LSBFIRST. B=Bit, not byte
|
220
|
+
* @param value the data to shift out
|
221
|
+
*
|
222
|
+
* @return The value read
|
223
|
+
*/
|
224
|
+
inline void shiftOut(uint8_t dataPin, uint8_t clockPin, bool bitOrder, uint8_t value) {
|
225
|
+
bool mFirst = bitOrder == MSBFIRST;
|
226
|
+
uint8_t ret = 0x00;
|
227
|
+
for (uint8_t i = 0, mask = (bitOrder == MSBFIRST ? 0x80 : 0x01); i < 8; ++i) {
|
228
|
+
uint8_t setBit = mFirst ? 0x80 : 0x01;
|
229
|
+
uint8_t val = (mFirst ? (setBit >> i) : (setBit << i));
|
230
|
+
digitalWrite(dataPin, (value & val) ? HIGH : LOW);
|
231
|
+
digitalWrite(clockPin, HIGH);
|
232
|
+
digitalWrite(clockPin, LOW);
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
// These definitions allow the following to compile (see issue #193):
|
237
|
+
// https://github.com/arduino-libraries/Ethernet/blob/master/src/utility/w5100.h:341
|
238
|
+
// we allow one byte per port which "wastes" 224 bytes, but makes the code easier
|
239
|
+
#if defined(__AVR__)
|
240
|
+
#define digitalPinToBitMask(pin) (1)
|
241
|
+
#define digitalPinToPort(pin) (pin)
|
242
|
+
#define portInputRegister(port) (GODMODE()->pMmapPort(port))
|
243
|
+
#define portOutputRegister(port) (GODMODE()->pMmapPort(port))
|
244
|
+
#else
|
245
|
+
// we don't (yet) support other boards
|
246
|
+
#endif
|
141
247
|
|
142
248
|
|
143
249
|
GodmodeState* GODMODE();
|