99
1010 See file LICENSE.txt for further informations on licensing terms.
1111
12- Last updated January 7th , 2017
12+ Last updated January 8th , 2017
1313*/
1414
1515#include " SPIFirmata.h"
1616
1717SPIFirmata::SPIFirmata ()
18+ {
19+ init ();
20+ }
21+
22+ void SPIFirmata::init ()
1823{
1924 mDeviceId = 0 ;
2025 mCsPin = -1 ;
26+ mCsActiveState = SPI_CS_ACTIVE_LOW; // default
2127}
2228
23- boolean SPIFirmata::handlePinMode (byte pin, int mode)
29+ bool SPIFirmata::handlePinMode (uint8_t pin, int mode)
2430{
25- // ignore SS pin for now
26- if (mode == PIN_MODE_SPI && pin != SS) {
27- Firmata.setPinMode (pin, PIN_MODE_SPI);
28- return true ;
29- }
31+ // There is no reason for a user to manually set the SPI pin modes
3032 return false ;
3133}
3234
33- void SPIFirmata::handleCapability (byte pin)
35+ void SPIFirmata::handleCapability (uint8_t pin)
3436{
3537 // ignore SS pin for now
3638 if (IS_PIN_SPI (pin) && pin != SS) {
@@ -41,30 +43,43 @@ void SPIFirmata::handleCapability(byte pin)
4143 }
4244}
4345
44- boolean SPIFirmata::handleSysex (byte command, byte argc, byte *argv)
46+ bool SPIFirmata::handleSysex (uint8_t command, uint8_t argc, uint8_t *argv)
4547{
4648 if (command == SPI_DATA) {
47- byte mode = argv[0 ];
49+ uint8_t mode = argv[0 ];
4850 // not using channel yet
49- byte channel = argv[1 ] & SPI_CHANNEL_MASK;
51+ uint8_t channel = argv[1 ] & SPI_CHANNEL_MASK;
5052
5153 switch (mode) {
5254 case SPI_CONFIG:
5355 SPI.begin ();
56+ // SPI pin states are configured by SPI.begin, but we still register them with Firmata.
57+ Firmata.setPinMode (MOSI, PIN_MODE_SPI);
58+ Firmata.setPinMode (MISO, PIN_MODE_SPI);
59+ Firmata.setPinMode (SCK, PIN_MODE_SPI);
60+ // ignore SS for now
61+ // Firmata.setPinMode(SS, PIN_MODE_SPI);
5462 break ;
5563 case SPI_BEGIN_TRANSACTION:
5664 {
5765 mDeviceId = argv[1 ] >> 2 ;
5866 uint8_t bitOrder = argv[2 ] & SPI_BIT_ORDER_MASK;
5967 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 );
68+ uint32_t clockSpeed = (uint32_t )argv[3 ] | ((uint32_t )argv[4 ] << 7 ) |
69+ (( uint32_t )argv[ 5 ] << 14 ) | ((uint32_t )argv[6 ] << 21 ) | ((uint32_t )argv[7 ] << 28 );
6270
6371 if (argc > 8 ) {
6472 mCsPin = argv[8 ];
6573 pinMode (mCsPin , OUTPUT);
66- // TODO - need to know if the device is active LOW or active HIGH at this time.
67- digitalWrite (mCsPin , HIGH);
74+
75+ if (argv[9 ] != END_SYSEX) {
76+ mCsActiveState = argv[9 ];
77+ } else {
78+ // set default
79+ mCsActiveState = SPI_CS_ACTIVE_LOW;
80+ }
81+ // set CS pin to opposite of active state
82+ digitalWrite (mCsPin , !mCsActiveState );
6883
6984 // protect the CS pin
7085 // TODO - decide if this is the best approach. If PIN_MODE_SPI is set, the user cannot
@@ -81,34 +96,28 @@ boolean SPIFirmata::handleSysex(byte command, byte argc, byte *argv)
8196 break ;
8297 case SPI_TRANSFER:
8398 {
84- byte transferOptions = argv[2 ] & SPI_TRANSFER_OPTS_MASK ;
85- byte numBytes = argv[3 ];
99+ uint8_t transferOptions = argv[2 ] & SPI_TRANSFER_MODES_MASK ;
100+ uint8_t numBytes = argv[3 ];
86101
87- boolean csIsActive = true ;
88- byte csStartVal = LOW;
89- byte csEndVal = HIGH;
90- boolean csStartOnly = false ;
91- boolean csEndOnly = false ;
102+ bool csIsActive = true ;
103+ bool csStartOnly = false ;
104+ bool csEndOnly = false ;
92105
93- // boolean csToggle = false;
106+ // bool csToggle = false;
94107
95108 if (mCsPin >= 0 ) {
96109 if (argv[2 ] & SPI_CS_DISABLE_MASK) {
97110 csIsActive = false ;
98111 } else {
99112 if (argv[2 ] & SPI_CS_START_ONLY_MASK) csStartOnly = true ;
100113 if (argv[2 ] & SPI_CS_END_ONLY_MASK) csEndOnly = true ;
101- if (argv[2 ] & SPI_CS_ACTIVE_EDGE_MASK) {
102- csStartVal = HIGH;
103- csStartVal = LOW;
104- }
105114 // TODO - handle csToggle
106115 // if (argv[2] & SPI_CS_TOGGLE_MASK) csToggle = true;
107116 }
108117 }
109118
110- if ((csIsActive || csStartOnly) && !csEndOnly) {
111- digitalWrite (mCsPin , csStartVal );
119+ if (mCsPin >= 0 && csIsActive && !csEndOnly) {
120+ digitalWrite (mCsPin , mCsActiveState );
112121 }
113122
114123 if (transferOptions == SPI_READ_WRITE) {
@@ -122,8 +131,9 @@ boolean SPIFirmata::handleSysex(byte command, byte argc, byte *argv)
122131 Firmata.sendString (" No transferOptions set" );
123132 }
124133
125- if ((csIsActive || csEndOnly) && !csStartOnly) {
126- digitalWrite (mCsPin , csEndVal);
134+ // TODO - ideally this should be called before the SPI_REPLY message is sent.
135+ if (mCsPin >= 0 && csIsActive && !csStartOnly) {
136+ digitalWrite (mCsPin , !mCsActiveState );
127137 }
128138 break ; // SPI_TRANSFER
129139 }
@@ -138,20 +148,19 @@ boolean SPIFirmata::handleSysex(byte command, byte argc, byte *argv)
138148
139149void SPIFirmata::reset ()
140150{
141- mCsPin = -1 ;
142- mDeviceId = 0 ;
151+ init ();
143152}
144153
145- void SPIFirmata::readWrite (byte channel, byte numBytes, byte argc, byte *argv)
154+ void SPIFirmata::readWrite (uint8_t channel, uint8_t numBytes, uint8_t argc, uint8_t *argv)
146155{
147- byte offset = 4 ; // mode + channel + opts + numBytes
148- byte buffer[numBytes];
149- byte bufferIndex = 0 ;
156+ uint8_t offset = 4 ; // mode + channel + opts + numBytes
157+ uint8_t buffer[numBytes];
158+ uint8_t bufferIndex = 0 ;
150159 if (numBytes * 2 != argc - offset) {
151160 // TODO - handle error
152161 Firmata.sendString (" fails numBytes test" );
153162 }
154- for (byte i = 0 ; i < numBytes * 2 ; i += 2 ) {
163+ for (uint8_t i = 0 ; i < numBytes * 2 ; i += 2 ) {
155164 bufferIndex = (i + 1 ) / 2 ;
156165 buffer[bufferIndex] = argv[i + offset + 1 ] << 7 | argv[i + offset];
157166 }
@@ -160,38 +169,38 @@ void SPIFirmata::readWrite(byte channel, byte numBytes, byte argc, byte *argv)
160169 reply (channel, numBytes, buffer);
161170}
162171
163- void SPIFirmata::writeOnly (byte channel, byte numBytes, byte argc, byte *argv)
172+ void SPIFirmata::writeOnly (uint8_t channel, uint8_t numBytes, uint8_t argc, uint8_t *argv)
164173{
165- byte offset = 4 ;
166- byte txValue;
174+ uint8_t offset = 4 ;
175+ uint8_t txValue;
167176 if (numBytes * 2 != argc - offset) {
168177 // TODO - handle error
169178 Firmata.sendString (" fails numBytes test" );
170179 }
171- for (byte i = 0 ; i < numBytes * 2 ; i += 2 ) {
180+ for (uint8_t i = 0 ; i < numBytes * 2 ; i += 2 ) {
172181 txValue = argv[i + offset + 1 ] << 7 | argv[i + offset];
173182 SPI.transfer (txValue);
174183 }
175184}
176185
177- void SPIFirmata::readOnly (byte channel, byte numBytes)
186+ void SPIFirmata::readOnly (uint8_t channel, uint8_t numBytes)
178187{
179- byte replyData[numBytes];
180- for (byte i = 0 ; i < numBytes; i++) {
188+ uint8_t replyData[numBytes];
189+ for (uint8_t i = 0 ; i < numBytes; i++) {
181190 replyData[i] = SPI.transfer (0x00 );
182191 }
183192 reply (channel, numBytes, replyData);
184193}
185194
186- void SPIFirmata::reply (byte channel, byte numBytes, byte *buffer)
195+ void SPIFirmata::reply (uint8_t channel, uint8_t numBytes, uint8_t *buffer)
187196{
188197 Firmata.write (START_SYSEX);
189198 Firmata.write (SPI_DATA);
190199 Firmata.write (SPI_REPLY);
191200 Firmata.write (mDeviceId << 2 | channel);
192201 Firmata.write (numBytes);
193202
194- for (byte i = 0 ; i < numBytes; i++) {
203+ for (uint8_t i = 0 ; i < numBytes; i++) {
195204 Firmata.write (buffer[i] & 0x7F );
196205 Firmata.write (buffer[i] >> 7 & 0x7F );
197206 }
0 commit comments