IoAbstraction
Loading...
Searching...
No Matches
MockIoAbstraction.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry).
3 * This product is licensed under an Apache license, see the LICENSE file in the top-level directory.
4 */
5
6#ifndef _MOCK_IO_ABSTRACTION_H_
7#define _MOCK_IO_ABSTRACTION_H_
8
15#include "IoAbstraction.h"
16
31
42private:
43 uint8_t pinModes[16];
44 uint16_t *readValues;
45 uint16_t *writeValues;
46 int runLoopCalls;
47 int numberOfCycles;
48
50 MockIoError error;
51
53 RawIntHandler intHandler;
55 uint8_t intPin;
57 uint8_t intMode;
58
59public:
60 MockedIoAbstraction(int numberOfCycles = 6) {
61 for(int i=0;i<16;i++) pinModes[i] = 0xff;
62 error = NO_ERROR;
63
64 this->numberOfCycles = numberOfCycles;
65 readValues = new uint16_t[numberOfCycles];
66 writeValues = new uint16_t[numberOfCycles];
67
68 resetIo();
69 }
70
71 virtual ~MockedIoAbstraction() {
72 delete readValues;
73 delete writeValues;
74 }
75
79 void resetIo() {
80 for(int i=0; i<numberOfCycles; i++) {
81 readValues[i] = 0;
82 writeValues[i] = 0;
83 }
84 runLoopCalls = 0;
85 }
86
87
88 void pinDirection(pinid_t pin, uint8_t mode) override {
89 checkPinInRange(pin);
90 pinModes[pin] = mode;
91 }
92
93 void writeValue(pinid_t pin, uint8_t value) override {
94 checkPinInRange(pin);
95
96 if(pinModes[pin] != OUTPUT) error = WRITE_NOT_OUTPUT;
97 bitWrite(writeValues[runLoopCalls], pin, value != 0);
98 }
99
100 uint8_t readValue(pinid_t pin) override {
101 checkPinInRange(pin);
102 if(pinModes[pin] != INPUT && pinModes[pin] != INPUT_PULLUP) error = READ_NOT_INPUT;
103 return bitRead(readValues[runLoopCalls], pin);
104 }
105
109 void attachInterrupt(pinid_t pin, RawIntHandler interruptHandler, uint8_t mode) override {
110 this->intHandler = interruptHandler;
111 this->intPin = pin;
112 this->intMode = mode;
113 }
114
115 bool runLoop() override {
116 // copy over the last written values (as they are generally additive) and bump counter.
117 uint16_t currentWritten = writeValues[runLoopCalls];
118
119 runLoopCalls++;
120 runLoopCalls = runLoopCalls % numberOfCycles; // dont exceed array
121
122 writeValues[runLoopCalls] = currentWritten;
123 return true;
124 }
125
126 void writePort(pinid_t pin, uint8_t portVal) override {
127
128 checkPinInRange(pin);
129
130 if(pin < 8) {
131 checkPinsAre(OUTPUT, 0, 7);
132 writeValues[runLoopCalls] = (writeValues[runLoopCalls] & 0xff00) | portVal;
133 }
134 else {
135 checkPinsAre(OUTPUT, 8, 15);
136 writeValues[runLoopCalls] = (writeValues[runLoopCalls] & 0x00ff) | (portVal << 8);
137 }
138 }
139
140 virtual uint8_t readPort(pinid_t pin) {
141 checkPinInRange(pin);
142
143 if(pin < 8) {
144 checkPinsAre(INPUT, 0, 7);
145 return readValues[runLoopCalls];
146 }
147 else {
148 checkPinsAre(INPUT, 8, 15);
149 return readValues[runLoopCalls] >> 8;
150 }
151 }
152
154 int getNumberOfRunLoops() {return runLoopCalls;}
155
157 uint16_t getWrittenValuesForRunLoop(int runLoop) { return writeValues[runLoop]; }
158
160 void setValueForReading(int runLoopNo, uint16_t val) {readValues[runLoopNo] = val;}
161
163 uint16_t getWrittenValue(int runLoopNo) {return writeValues[runLoopNo];}
164
166 MockIoError getErrorMode() {return error;}
167
169 void clearError() { error = NO_ERROR; }
170
172 RawIntHandler getInterruptFunction() {return intHandler;}
173
175 bool isIntRegisteredAs(uint8_t pin, uint8_t mode) {
176 return intPin == pin && intMode == mode && intHandler != NULL;
177 }
178private:
179 void checkPinInRange(int pin) {
180 if(pin > 15) error = PIN_TOO_HIGH;
181 }
182 void checkPinsAre(uint8_t mode, uint8_t start, uint8_t end) {
183 for(int i = start; i < end; ++i) {
184 if(mode == OUTPUT) {
185 if(pinModes[i] != OUTPUT) error = WRITE_NOT_OUTPUT;
186 }
187 else if(mode == INPUT) {
188 if(pinModes[i] != INPUT && pinModes[i] != INPUT_PULLUP) error = READ_NOT_INPUT;
189 }
190 }
191 }
192};
193
205private:
206 IoAbstractionRef delegate;
207 uint32_t writeVals;
208 int ports;
209public:
210 LoggingIoAbstraction(IoAbstractionRef delegate, int ports) {
211 this->delegate = delegate;
212 this->ports = ports;
213 writeVals = 0;
214 }
215
216 void pinDirection(pinid_t pin, uint8_t mode) override { delegate->pinDirection(pin, mode); }
217
218 void writeValue(pinid_t pin, uint8_t value) override {
219 bitWrite(writeVals, pin, value);
220 delegate->writeValue(pin, value);
221 }
222 uint8_t readValue(pinid_t pin) override { return delegate->readValue(pin); }
223
224 void attachInterrupt(pinid_t pin, RawIntHandler interruptHandler, uint8_t mode) override { delegate->attachInterrupt(pin, interruptHandler, mode); }
225
226 void writePort(pinid_t pin, uint8_t portVal) override {
227 if(pin < 8) {
228 writeVals &= 0xffffff00L;
229 writeVals |= (uint32_t)portVal;
230 }
231 else if(pin < 16) {
232 writeVals &= 0xffff00ffL;
233 writeVals |= ((uint32_t)portVal<<8);
234 }
235 else if(pin < 24) {
236 writeVals &= 0xff00ffffL;
237 writeVals |= ((uint32_t)portVal<<16);
238 }
239 else {
240 writeVals &= 0x00ffffffL;
241 writeVals |= ((uint32_t)portVal<<24);
242 }
243 delegate->writePort(pin, portVal);
244 }
245 uint8_t readPort(pinid_t pin) override { return delegate->readPort(pin);}
246
247 bool runLoop() override {
248 serlogF(SER_DEBUG, "Port write ");
249 uint32_t val = writeVals;
250 for(int i=0;i<ports;i++) {
251 printHexZeroPad(val);
252 val = val >> 8;
253 }
254 bool ret = delegate->runLoop();
255 serlogF(SER_DEBUG, "read ");
256 for(int i=0;i<ports;i++) {
257 printHexZeroPad(delegate->readPort(i * 8));
258 }
259 serlogF(SER_DEBUG, "EOL");
260 return ret;
261 }
262
263 void printHexZeroPad(uint8_t val) {
264 serlog3(SER_DEBUG, hexchar(val / 16), hexchar(val % 16), ' ');
265 }
266
267 char hexchar(uint8_t ch) {
268 return ch < 10 ? ch + '0' : (ch-10) + 'A';
269 }
270};
271
272#endif // _MOCK_IO_ABSTRACTION_H_
Using basic IoFacilities allows one to abstract away the use of IoExpanders, such that the switching ...
MockIoError
Definition MockIoAbstraction.h:21
@ READ_NOT_INPUT
Definition MockIoAbstraction.h:27
@ PIN_TOO_HIGH
Definition MockIoAbstraction.h:25
@ NO_ERROR
Definition MockIoAbstraction.h:23
@ WRITE_NOT_OUTPUT
Definition MockIoAbstraction.h:29
Definition BasicIoAbstraction.h:38
virtual void pinDirection(pinid_t pin, uint8_t mode)
virtual void writePort(pinid_t pin, uint8_t portVal)
virtual uint8_t readValue(pinid_t pin)
virtual void writeValue(pinid_t pin, uint8_t value)
virtual void attachInterrupt(pinid_t pin, RawIntHandler interruptHandler, uint8_t mode)
virtual bool runLoop()
Definition BasicIoAbstraction.h:147
virtual uint8_t readPort(pinid_t pin)
Definition MockIoAbstraction.h:204
uint8_t readPort(pinid_t pin) override
Definition MockIoAbstraction.h:245
void attachInterrupt(pinid_t pin, RawIntHandler interruptHandler, uint8_t mode) override
Definition MockIoAbstraction.h:224
void writeValue(pinid_t pin, uint8_t value) override
Definition MockIoAbstraction.h:218
bool runLoop() override
Definition MockIoAbstraction.h:247
void pinDirection(pinid_t pin, uint8_t mode) override
Definition MockIoAbstraction.h:216
uint8_t readValue(pinid_t pin) override
Definition MockIoAbstraction.h:222
void writePort(pinid_t pin, uint8_t portVal) override
Definition MockIoAbstraction.h:226
Definition MockIoAbstraction.h:41
void pinDirection(pinid_t pin, uint8_t mode) override
Definition MockIoAbstraction.h:88
MockIoError getErrorMode()
Definition MockIoAbstraction.h:166
void writeValue(pinid_t pin, uint8_t value) override
Definition MockIoAbstraction.h:93
virtual uint8_t readPort(pinid_t pin)
Definition MockIoAbstraction.h:140
void attachInterrupt(pinid_t pin, RawIntHandler interruptHandler, uint8_t mode) override
Definition MockIoAbstraction.h:109
bool isIntRegisteredAs(uint8_t pin, uint8_t mode)
Definition MockIoAbstraction.h:175
uint16_t getWrittenValue(int runLoopNo)
Definition MockIoAbstraction.h:163
uint8_t readValue(pinid_t pin) override
Definition MockIoAbstraction.h:100
RawIntHandler getInterruptFunction()
Definition MockIoAbstraction.h:172
bool runLoop() override
Definition MockIoAbstraction.h:115
uint16_t getWrittenValuesForRunLoop(int runLoop)
Definition MockIoAbstraction.h:157
void resetIo()
Definition MockIoAbstraction.h:79
void setValueForReading(int runLoopNo, uint16_t val)
Definition MockIoAbstraction.h:160
void clearError()
Definition MockIoAbstraction.h:169
void writePort(pinid_t pin, uint8_t portVal) override
Definition MockIoAbstraction.h:126
int getNumberOfRunLoops()
Definition MockIoAbstraction.h:154