Skip to content

Commit 17cf555

Browse files
Ensure correct dataMode and bitOrder is set.
Also eliminate unnecessary buffers.
1 parent 90c0adb commit 17cf555

File tree

2 files changed

+39
-25
lines changed

2 files changed

+39
-25
lines changed

utility/SPIFirmata.cpp

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,18 @@ boolean SPIFirmata::handleSysex(byte command, byte argc, byte *argv)
5555
case SPI_BEGIN_TRANSACTION:
5656
{
5757
mDeviceId = argv[1] >> 2;
58-
byte bitOrder = argv[2] & SPI_BIT_ORDER_MASK;
59-
byte dataMode = argv[2] >> 1;
60-
long clockSpeed = (long)argv[3] | ((long)argv[4] << 7) | ((long)argv[5] << 14) |
61-
((long)argv[6] << 21) | ((long)argv[7] << 28);
58+
uint8_t bitOrder = argv[2] & SPI_BIT_ORDER_MASK;
59+
uint8_t dataMode = argv[2] >> 1;
60+
uint32_t clockSpeed = (uint32_t)argv[3] | ((uint32_t)argv[4] << 7) | ((uint32_t)argv[5] << 14) |
61+
((uint32_t)argv[6] << 21) | ((uint32_t)argv[7] << 28);
6262

6363
if (argc > 8) {
6464
mCsPin = argv[8];
6565
pinMode(mCsPin, OUTPUT);
6666
// protect the CS pin
6767
Firmata.setPinMode(mCsPin, PIN_MODE_SPI);
6868
}
69-
SPISettings settings(clockSpeed, bitOrder, dataMode);
69+
SPISettings settings(clockSpeed, getBitOrder(bitOrder), getDataMode(dataMode));
7070
SPI.beginTransaction(settings);
7171
break;
7272
}
@@ -137,14 +137,13 @@ void SPIFirmata::reset()
137137

138138
void SPIFirmata::readWrite(byte channel, byte numBytes, byte argc, byte *argv)
139139
{
140-
Firmata.sendString("readWrite");
141140
byte offset = 4; // mode + channel + opts + numBytes
141+
byte buffer[numBytes];
142+
byte bufferIndex = 0;
142143
if (numBytes * 2 != argc - offset) {
143144
// TODO - handle error
144145
Firmata.sendString("fails numBytes test");
145146
}
146-
byte buffer[numBytes];
147-
byte bufferIndex = 0;
148147
for (byte i = 0; i < numBytes * 2; i += 2) {
149148
bufferIndex = (i + 1) / 2;
150149
buffer[bufferIndex] = argv[i + offset + 1] << 7 | argv[i + offset];
@@ -154,38 +153,27 @@ void SPIFirmata::readWrite(byte channel, byte numBytes, byte argc, byte *argv)
154153
reply(channel, numBytes, buffer);
155154
}
156155

157-
// TODO - eliminate duplication between readWrite and writeOnly
158156
void SPIFirmata::writeOnly(byte channel, byte numBytes, byte argc, byte *argv)
159157
{
160-
Firmata.sendString("writeOnly");
161158
byte offset = 4;
159+
byte txValue;
162160
if (numBytes * 2 != argc - offset) {
163161
// TODO - handle error
164162
Firmata.sendString("fails numBytes test");
165163
}
166-
167-
byte buffer[numBytes];
168-
byte bufferIndex = 0;
169164
for (byte i = 0; i < numBytes * 2; i += 2) {
170-
bufferIndex = (i + 1) / 2;
171-
buffer[bufferIndex] = argv[i + offset + 1] << 7 | argv[i + offset];
165+
txValue = argv[i + offset + 1] << 7 | argv[i + offset];
166+
SPI.transfer(txValue);
172167
}
173-
SPI.transfer(buffer, numBytes);
174168
}
175169

176-
// TODO - combine readWrite and readOnly by sending zero for each byte read
177-
// in read-only mode.
178-
// That leaves us with read and writeOnly
179170
void SPIFirmata::readOnly(byte channel, byte numBytes)
180171
{
181-
Firmata.sendString("readOnly");
182-
byte buffer[numBytes];
172+
byte replyData[numBytes];
183173
for (byte i = 0; i < numBytes; i++) {
184-
buffer[i] = 0;
174+
replyData[i] = SPI.transfer(0x00);
185175
}
186-
SPI.transfer(buffer, numBytes);
187-
188-
reply(channel, numBytes, buffer);
176+
reply(channel, numBytes, replyData);
189177
}
190178

191179
void SPIFirmata::reply(byte channel, byte numBytes, byte *buffer)

utility/SPIFirmata.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,32 @@
5151
#define SPI_DEVICE_ID_MASK 0x7C
5252
#define SPI_BIT_ORDER_MASK 0x01
5353

54+
namespace {
55+
// TODO - check Teensy and other non SAM, SAMD or AVR variants
56+
#if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)
57+
inline BitOrder getBitOrder(uint8_t value) {
58+
if (value == 0) return LSBFIRST;
59+
return MSBFIRST; // default
60+
}
61+
#else
62+
inline uint8_t getBitOrder(uint8_t value) {
63+
if (value == 0) return LSBFIRST;
64+
return MSBFIRST; // default
65+
}
66+
#endif
67+
68+
inline uint8_t getDataMode(uint8_t value) {
69+
if (value == 1) {
70+
return SPI_MODE1;
71+
} else if (value == 2) {
72+
return SPI_MODE2;
73+
} else if (value == 3) {
74+
return SPI_MODE3;
75+
}
76+
return SPI_MODE0; // default
77+
}
78+
79+
}
5480

5581
class SPIFirmata: public FirmataFeature
5682
{

0 commit comments

Comments
 (0)