18
18
*/
19
19
SPIClass SPI;
20
20
21
- SPIClass::SPIClass () : g_active_id (-1 )
21
+ SPIClass::SPIClass () : _CSpin (-1 )
22
22
{
23
23
_spi.pin_miso = digitalPinToPinName (MISO);
24
24
_spi.pin_mosi = digitalPinToPinName (MOSI);
@@ -29,7 +29,7 @@ SPIClass::SPIClass() : g_active_id(-1)
29
29
/* By default hardware SS pin is not used. To use hardware SS pin you should set
30
30
ssel pin. Enable this pin disable software CS. See microcontroller documentation
31
31
for the list of available SS pins. */
32
- SPIClass::SPIClass (uint8_t mosi, uint8_t miso, uint8_t sclk, uint8_t ssel) : g_active_id (-1 )
32
+ SPIClass::SPIClass (uint8_t mosi, uint8_t miso, uint8_t sclk, uint8_t ssel) : _CSpin (-1 )
33
33
{
34
34
_spi.pin_miso = digitalPinToPinName (miso);
35
35
_spi.pin_mosi = digitalPinToPinName (mosi);
@@ -45,22 +45,30 @@ SPIClass::SPIClass(uint8_t mosi, uint8_t miso, uint8_t sclk, uint8_t ssel) : g_a
45
45
// begin using the default chip select
46
46
void SPIClass::begin ()
47
47
{
48
- begin (BOARD_SPI_OWN_SS );
48
+ begin (CS_PIN_CONTROLLED_BY_USER );
49
49
}
50
50
51
51
// Begin with a chip select defined
52
52
void SPIClass::begin (uint8_t _pin)
53
53
{
54
- if (_pin > SPI_CHANNELS_NUM)
54
+ uint8_t idx;
55
+
56
+ if (_pin > NUM_DIGITAL_PINS)
57
+ return ;
58
+
59
+ idx = pinIdx (_pin, ADD_NEW_PIN);
60
+ if (idx == NB_SPI_SETTINGS)
55
61
return ;
56
62
57
- if ((_pin != BOARD_SPI_OWN_SS ) && (_spi.pin_ssel == NC)) {
63
+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_spi.pin_ssel == NC)) {
58
64
pinMode (_pin, OUTPUT);
59
65
digitalWrite (_pin, HIGH);
60
66
}
61
67
62
- spi_init (&_spi, spiSettings[_pin].clk , spiSettings[_pin].dMode , spiSettings[_pin].msb );
63
- g_active_id = _pin;
68
+ spi_init (&_spi, spiSettings[idx].clk ,
69
+ spiSettings[idx].dMode ,
70
+ spiSettings[idx].msb );
71
+ _CSpin = _pin;
64
72
#if __has_include("WiFi.h")
65
73
// Wait wifi shield initialization.
66
74
// Should be better to do in SpiDrv::begin() of WiFi library but it seems
@@ -78,73 +86,98 @@ void SPIClass::usingInterrupt(uint8_t interruptNumber)
78
86
79
87
void SPIClass::beginTransaction (uint8_t _pin, SPISettings settings)
80
88
{
81
- if (_pin > SPI_CHANNELS_NUM)
89
+ uint8_t idx;
90
+
91
+ if (_pin > NUM_DIGITAL_PINS)
92
+ return ;
93
+
94
+ idx = pinIdx (_pin, ADD_NEW_PIN);
95
+ if (idx == NB_SPI_SETTINGS) {
82
96
return ;
97
+ }
83
98
84
- spiSettings[_pin ].clk = settings.clk ;
85
- spiSettings[_pin ].dMode = settings.dMode ;
86
- spiSettings[_pin ].bOrder = settings.bOrder ;
87
- if (spiSettings[_pin ].bOrder == MSBFIRST) {
88
- spiSettings[_pin ].msb = MSBFIRST;
99
+ spiSettings[idx ].clk = settings.clk ;
100
+ spiSettings[idx ].dMode = settings.dMode ;
101
+ spiSettings[idx ].bOrder = settings.bOrder ;
102
+ if (spiSettings[idx ].bOrder == MSBFIRST) {
103
+ spiSettings[idx ].msb = MSBFIRST;
89
104
} else {
90
- spiSettings[_pin ].msb = LSBFIRST;
105
+ spiSettings[idx ].msb = LSBFIRST;
91
106
}
92
107
93
- spi_init (&_spi, spiSettings[_pin].clk , spiSettings[_pin].dMode , spiSettings[_pin].msb );
94
- g_active_id = _pin;
95
- }
108
+ if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_spi.pin_ssel == NC)) {
109
+ pinMode (_pin, OUTPUT);
110
+ digitalWrite (_pin, HIGH);
111
+ }
96
112
97
- void SPIClass::endTransaction (void )
98
- {
99
- g_active_id = -1 ;
113
+ spi_init (&_spi, spiSettings[idx].clk ,
114
+ spiSettings[idx].dMode ,
115
+ spiSettings[idx].msb );
116
+ _CSpin = _pin;
100
117
}
101
118
102
- void SPIClass::end (uint8_t _pin)
119
+ void SPIClass::endTransaction (uint8_t _pin)
103
120
{
104
- UNUSED (_pin);
105
- end ();
121
+ if (_pin > NUM_DIGITAL_PINS)
122
+ return ;
123
+
124
+ RemovePin (_pin);
125
+ _CSpin = -1 ;
106
126
}
107
127
108
128
void SPIClass::end ()
109
129
{
110
130
spi_deinit (&_spi);
111
- g_active_id = -1 ;
131
+ RemoveAllPin ();
132
+ _CSpin = -1 ;
112
133
}
113
134
114
135
void SPIClass::setBitOrder (uint8_t _pin, BitOrder _bitOrder)
115
136
{
116
- if (_pin > SPI_CHANNELS_NUM)
137
+ if (_pin > NUM_DIGITAL_PINS)
138
+ return ;
139
+
140
+ uint8_t idx = pinIdx (_pin, GET_IDX);
141
+ if (idx == NB_SPI_SETTINGS) {
117
142
return ;
143
+ }
118
144
119
145
if (MSBFIRST == _bitOrder) {
120
- spiSettings[_pin ].msb = MSBFIRST;
121
- spiSettings[_pin ].bOrder = MSBFIRST;
146
+ spiSettings[idx ].msb = MSBFIRST;
147
+ spiSettings[idx ].bOrder = MSBFIRST;
122
148
} else {
123
- spiSettings[_pin ].msb = LSBFIRST;
124
- spiSettings[_pin ].bOrder = LSBFIRST;
149
+ spiSettings[idx ].msb = LSBFIRST;
150
+ spiSettings[idx ].bOrder = LSBFIRST;
125
151
}
126
152
127
- spi_init (&_spi, spiSettings[_pin].clk , spiSettings[_pin].dMode , spiSettings[_pin].msb );
128
- g_active_id = _pin;
153
+ spi_init (&_spi, spiSettings[idx].clk ,
154
+ spiSettings[idx].dMode ,
155
+ spiSettings[idx].msb );
129
156
}
130
157
131
158
void SPIClass::setDataMode (uint8_t _pin, uint8_t _mode)
132
159
{
133
- if (_pin > SPI_CHANNELS_NUM)
160
+ if (_pin > NUM_DIGITAL_PINS)
161
+ return ;
162
+
163
+ uint8_t idx = pinIdx (_pin, GET_IDX);
164
+ if (idx == NB_SPI_SETTINGS) {
134
165
return ;
166
+ }
135
167
136
168
if (SPI_MODE0 == _mode) {
137
- spiSettings[_pin ].dMode = SPI_MODE_0;
169
+ spiSettings[idx ].dMode = SPI_MODE_0;
138
170
} else if (SPI_MODE1 == _mode) {
139
- spiSettings[_pin ].dMode = SPI_MODE_1;
171
+ spiSettings[idx ].dMode = SPI_MODE_1;
140
172
} else if (SPI_MODE2 == _mode) {
141
- spiSettings[_pin ].dMode = SPI_MODE_2;
173
+ spiSettings[idx ].dMode = SPI_MODE_2;
142
174
} else if (SPI_MODE3 == _mode) {
143
- spiSettings[_pin ].dMode = SPI_MODE_3;
175
+ spiSettings[idx ].dMode = SPI_MODE_3;
144
176
}
145
177
146
- spi_init (&_spi, spiSettings[_pin].clk , spiSettings[_pin].dMode , spiSettings[_pin].msb );
147
- g_active_id = _pin;
178
+ spi_init (&_spi, spiSettings[idx].clk ,
179
+ spiSettings[idx].dMode ,
180
+ spiSettings[idx].msb );
148
181
}
149
182
150
183
/*
@@ -153,8 +186,13 @@ void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode)
153
186
*/
154
187
void SPIClass::setClockDivider (uint8_t _pin, uint8_t _divider)
155
188
{
156
- if (_pin > SPI_CHANNELS_NUM)
189
+ if (_pin > NUM_DIGITAL_PINS)
190
+ return ;
191
+
192
+ uint8_t idx = pinIdx (_pin, GET_IDX);
193
+ if (idx == NB_SPI_SETTINGS) {
157
194
return ;
195
+ }
158
196
159
197
/* Get clk freq of the SPI instance */
160
198
uint32_t spiClkFreq = spi_getClkFreq (&_spi);
@@ -167,39 +205,49 @@ void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider)
167
205
case (SPI_CLOCK_DIV32) :
168
206
case (SPI_CLOCK_DIV64) :
169
207
case (SPI_CLOCK_DIV128) :
170
- spiSettings[_pin ].clk = spiClkFreq/_divider;
208
+ spiSettings[idx ].clk = spiClkFreq/_divider;
171
209
break ;
172
210
default :
173
- spiSettings[_pin ].clk = SPI_SPEED_CLOCK_DEFAULT;
211
+ spiSettings[idx ].clk = SPI_SPEED_CLOCK_DEFAULT;
174
212
break ;
175
213
}
176
214
177
- spi_init (&_spi, spiSettings[_pin].clk , spiSettings[_pin].dMode , spiSettings[_pin].msb );
178
- g_active_id = _pin;
215
+ spi_init (&_spi, spiSettings[idx].clk ,
216
+ spiSettings[idx].dMode ,
217
+ spiSettings[idx].msb );
179
218
}
180
219
181
220
182
- // Transfer a message on the selected SPI. The _pin is the CS of the SPI that
183
- // identifies the SPI instance.
184
- // If the _mode is set to SPI_CONTINUE, keep the spi instance alive.
221
+ /* Transfer a message on the selected SPI. The _pin is the CS.
222
+ * The transfer function can reconfigure the SPI instance if the CS pin is
223
+ * different from the previous one.
224
+ * If the _mode is set to SPI_CONTINUE, keep the spi instance alive. That means
225
+ * the CS pin is not reset. Be careful in case you use several CS pin.
226
+ */
185
227
byte SPIClass::transfer (uint8_t _pin, uint8_t data, SPITransferMode _mode)
186
228
{
187
229
uint8_t rx_buffer = 0 ;
188
230
189
- if (_pin > SPI_CHANNELS_NUM )
231
+ if (_pin > NUM_DIGITAL_PINS )
190
232
return rx_buffer;
191
233
192
- if (_pin != g_active_id) {
193
- spi_init (&_spi, spiSettings[_pin].clk , spiSettings[_pin].dMode , spiSettings[_pin].msb );
194
- g_active_id = _pin;
234
+ if (_pin != _CSpin) {
235
+ uint8_t idx = pinIdx (_pin, GET_IDX);
236
+ if (idx == NB_SPI_SETTINGS) {
237
+ return rx_buffer;
238
+ }
239
+ spi_init (&_spi, spiSettings[idx].clk ,
240
+ spiSettings[idx].dMode ,
241
+ spiSettings[idx].msb );
242
+ _CSpin = _pin;
195
243
}
196
244
197
- if ((_pin != BOARD_SPI_OWN_SS ) && (_spi.pin_ssel == NC))
245
+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_spi.pin_ssel == NC))
198
246
digitalWrite (_pin, LOW);
199
247
200
- spi_transfer (&_spi, &data, &rx_buffer, sizeof (uint8_t ), 10000 );
248
+ spi_transfer (&_spi, &data, &rx_buffer, sizeof (uint8_t ), SPI_TRANSFER_TIMEOUT );
201
249
202
- if ((_pin != BOARD_SPI_OWN_SS ) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC))
250
+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC))
203
251
digitalWrite (_pin, HIGH);
204
252
205
253
return rx_buffer;
@@ -210,25 +258,31 @@ uint16_t SPIClass::transfer16(uint8_t _pin, uint16_t data, SPITransferMode _mode
210
258
uint16_t rx_buffer = 0 ;
211
259
uint16_t tmp;
212
260
213
- if (_pin > SPI_CHANNELS_NUM )
261
+ if (_pin > NUM_DIGITAL_PINS )
214
262
return rx_buffer;
215
263
216
264
if (spiSettings[_pin].msb ) {
217
265
tmp = ((data & 0xff00 ) >> 8 ) | ((data & 0xff ) << 8 );
218
266
data = tmp;
219
267
}
220
268
221
- if (_pin != g_active_id) {
222
- spi_init (&_spi, spiSettings[_pin].clk , spiSettings[_pin].dMode , spiSettings[_pin].msb );
223
- g_active_id = _pin;
269
+ if (_pin != _CSpin) {
270
+ uint8_t idx = pinIdx (_pin, GET_IDX);
271
+ if (idx == NB_SPI_SETTINGS) {
272
+ return rx_buffer;
273
+ }
274
+ spi_init (&_spi, spiSettings[idx].clk ,
275
+ spiSettings[idx].dMode ,
276
+ spiSettings[idx].msb );
277
+ _CSpin = _pin;
224
278
}
225
279
226
- if ((_pin != BOARD_SPI_OWN_SS ) && (_spi.pin_ssel == NC))
280
+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_spi.pin_ssel == NC))
227
281
digitalWrite (_pin, LOW);
228
282
229
- spi_transfer (&_spi, (uint8_t *)&data, (uint8_t *)&rx_buffer, sizeof (uint16_t ), 10000000 );
283
+ spi_transfer (&_spi, (uint8_t *)&data, (uint8_t *)&rx_buffer, sizeof (uint16_t ), SPI_TRANSFER_TIMEOUT );
230
284
231
- if ((_pin != BOARD_SPI_OWN_SS ) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC))
285
+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC))
232
286
digitalWrite (_pin, HIGH);
233
287
234
288
if (spiSettings[_pin].msb ) {
@@ -241,20 +295,26 @@ uint16_t SPIClass::transfer16(uint8_t _pin, uint16_t data, SPITransferMode _mode
241
295
242
296
void SPIClass::transfer (uint8_t _pin, void *_buf, size_t _count, SPITransferMode _mode)
243
297
{
244
- if ((_count == 0 ) || (_pin > SPI_CHANNELS_NUM ))
298
+ if ((_count == 0 ) || (_buf == NULL ) || ( _pin > NUM_DIGITAL_PINS ))
245
299
return ;
246
300
247
- if (_pin != g_active_id) {
248
- spi_init (&_spi, spiSettings[_pin].clk , spiSettings[_pin].dMode , spiSettings[_pin].msb );
249
- g_active_id = _pin;
301
+ if (_pin != _CSpin) {
302
+ uint8_t idx = pinIdx (_pin, GET_IDX);
303
+ if (idx == NB_SPI_SETTINGS) {
304
+ return ;
305
+ }
306
+ spi_init (&_spi, spiSettings[idx].clk ,
307
+ spiSettings[idx].dMode ,
308
+ spiSettings[idx].msb );
309
+ _CSpin = _pin;
250
310
}
251
311
252
- if ((_pin != BOARD_SPI_OWN_SS ) && (_spi.pin_ssel == NC))
312
+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_spi.pin_ssel == NC))
253
313
digitalWrite (_pin, LOW);
254
314
255
- spi_transfer (&_spi, ((uint8_t *)_buf), ((uint8_t *)_buf), _count, 10000 );
315
+ spi_transfer (&_spi, ((uint8_t *)_buf), ((uint8_t *)_buf), _count, SPI_TRANSFER_TIMEOUT );
256
316
257
- if ((_pin != BOARD_SPI_OWN_SS ) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC))
317
+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC))
258
318
digitalWrite (_pin, HIGH);
259
319
}
260
320
0 commit comments