1818*/
1919SPIClass SPI;
2020
21- SPIClass::SPIClass () : g_active_id (-1 )
21+ SPIClass::SPIClass () : _CSpin (-1 )
2222{
2323 _spi.pin_miso = digitalPinToPinName (MISO);
2424 _spi.pin_mosi = digitalPinToPinName (MOSI);
@@ -29,7 +29,7 @@ SPIClass::SPIClass() : g_active_id(-1)
2929/* By default hardware SS pin is not used. To use hardware SS pin you should set
3030ssel pin. Enable this pin disable software CS. See microcontroller documentation
3131for 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 )
3333{
3434 _spi.pin_miso = digitalPinToPinName (miso);
3535 _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
4545// begin using the default chip select
4646void SPIClass::begin ()
4747{
48- begin (BOARD_SPI_OWN_SS );
48+ begin (CS_PIN_CONTROLLED_BY_USER );
4949}
5050
5151// Begin with a chip select defined
5252void SPIClass::begin (uint8_t _pin)
5353{
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)
5561 return ;
5662
57- if ((_pin != BOARD_SPI_OWN_SS ) && (_spi.pin_ssel == NC)) {
63+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_spi.pin_ssel == NC)) {
5864 pinMode (_pin, OUTPUT);
5965 digitalWrite (_pin, HIGH);
6066 }
6167
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;
6472#if __has_include("WiFi.h")
6573 // Wait wifi shield initialization.
6674 // Should be better to do in SpiDrv::begin() of WiFi library but it seems
@@ -78,73 +86,98 @@ void SPIClass::usingInterrupt(uint8_t interruptNumber)
7886
7987void SPIClass::beginTransaction (uint8_t _pin, SPISettings settings)
8088{
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) {
8296 return ;
97+ }
8398
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;
89104 } else {
90- spiSettings[_pin ].msb = LSBFIRST;
105+ spiSettings[idx ].msb = LSBFIRST;
91106 }
92107
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+ }
96112
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;
100117}
101118
102- void SPIClass::end (uint8_t _pin)
119+ void SPIClass::endTransaction (uint8_t _pin)
103120{
104- UNUSED (_pin);
105- end ();
121+ if (_pin > NUM_DIGITAL_PINS)
122+ return ;
123+
124+ RemovePin (_pin);
125+ _CSpin = -1 ;
106126}
107127
108128void SPIClass::end ()
109129{
110130 spi_deinit (&_spi);
111- g_active_id = -1 ;
131+ RemoveAllPin ();
132+ _CSpin = -1 ;
112133}
113134
114135void SPIClass::setBitOrder (uint8_t _pin, BitOrder _bitOrder)
115136{
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) {
117142 return ;
143+ }
118144
119145 if (MSBFIRST == _bitOrder) {
120- spiSettings[_pin ].msb = MSBFIRST;
121- spiSettings[_pin ].bOrder = MSBFIRST;
146+ spiSettings[idx ].msb = MSBFIRST;
147+ spiSettings[idx ].bOrder = MSBFIRST;
122148 } else {
123- spiSettings[_pin ].msb = LSBFIRST;
124- spiSettings[_pin ].bOrder = LSBFIRST;
149+ spiSettings[idx ].msb = LSBFIRST;
150+ spiSettings[idx ].bOrder = LSBFIRST;
125151 }
126152
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 );
129156}
130157
131158void SPIClass::setDataMode (uint8_t _pin, uint8_t _mode)
132159{
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) {
134165 return ;
166+ }
135167
136168 if (SPI_MODE0 == _mode) {
137- spiSettings[_pin ].dMode = SPI_MODE_0;
169+ spiSettings[idx ].dMode = SPI_MODE_0;
138170 } else if (SPI_MODE1 == _mode) {
139- spiSettings[_pin ].dMode = SPI_MODE_1;
171+ spiSettings[idx ].dMode = SPI_MODE_1;
140172 } else if (SPI_MODE2 == _mode) {
141- spiSettings[_pin ].dMode = SPI_MODE_2;
173+ spiSettings[idx ].dMode = SPI_MODE_2;
142174 } else if (SPI_MODE3 == _mode) {
143- spiSettings[_pin ].dMode = SPI_MODE_3;
175+ spiSettings[idx ].dMode = SPI_MODE_3;
144176 }
145177
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 );
148181}
149182
150183/*
@@ -153,8 +186,13 @@ void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode)
153186 */
154187void SPIClass::setClockDivider (uint8_t _pin, uint8_t _divider)
155188{
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) {
157194 return ;
195+ }
158196
159197 /* Get clk freq of the SPI instance */
160198 uint32_t spiClkFreq = spi_getClkFreq (&_spi);
@@ -167,39 +205,49 @@ void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider)
167205 case (SPI_CLOCK_DIV32) :
168206 case (SPI_CLOCK_DIV64) :
169207 case (SPI_CLOCK_DIV128) :
170- spiSettings[_pin ].clk = spiClkFreq/_divider;
208+ spiSettings[idx ].clk = spiClkFreq/_divider;
171209 break ;
172210 default :
173- spiSettings[_pin ].clk = SPI_SPEED_CLOCK_DEFAULT;
211+ spiSettings[idx ].clk = SPI_SPEED_CLOCK_DEFAULT;
174212 break ;
175213 }
176214
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 );
179218}
180219
181220
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+ */
185227byte SPIClass::transfer (uint8_t _pin, uint8_t data, SPITransferMode _mode)
186228{
187229 uint8_t rx_buffer = 0 ;
188230
189- if (_pin > SPI_CHANNELS_NUM )
231+ if (_pin > NUM_DIGITAL_PINS )
190232 return rx_buffer;
191233
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;
195243 }
196244
197- if ((_pin != BOARD_SPI_OWN_SS ) && (_spi.pin_ssel == NC))
245+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_spi.pin_ssel == NC))
198246 digitalWrite (_pin, LOW);
199247
200- spi_transfer (&_spi, &data, &rx_buffer, sizeof (uint8_t ), 10000 );
248+ spi_transfer (&_spi, &data, &rx_buffer, sizeof (uint8_t ), SPI_TRANSFER_TIMEOUT );
201249
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))
203251 digitalWrite (_pin, HIGH);
204252
205253 return rx_buffer;
@@ -210,25 +258,31 @@ uint16_t SPIClass::transfer16(uint8_t _pin, uint16_t data, SPITransferMode _mode
210258 uint16_t rx_buffer = 0 ;
211259 uint16_t tmp;
212260
213- if (_pin > SPI_CHANNELS_NUM )
261+ if (_pin > NUM_DIGITAL_PINS )
214262 return rx_buffer;
215263
216264 if (spiSettings[_pin].msb ) {
217265 tmp = ((data & 0xff00 ) >> 8 ) | ((data & 0xff ) << 8 );
218266 data = tmp;
219267 }
220268
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;
224278 }
225279
226- if ((_pin != BOARD_SPI_OWN_SS ) && (_spi.pin_ssel == NC))
280+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_spi.pin_ssel == NC))
227281 digitalWrite (_pin, LOW);
228282
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 );
230284
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))
232286 digitalWrite (_pin, HIGH);
233287
234288 if (spiSettings[_pin].msb ) {
@@ -241,20 +295,26 @@ uint16_t SPIClass::transfer16(uint8_t _pin, uint16_t data, SPITransferMode _mode
241295
242296void SPIClass::transfer (uint8_t _pin, void *_buf, size_t _count, SPITransferMode _mode)
243297{
244- if ((_count == 0 ) || (_pin > SPI_CHANNELS_NUM ))
298+ if ((_count == 0 ) || (_buf == NULL ) || ( _pin > NUM_DIGITAL_PINS ))
245299 return ;
246300
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;
250310 }
251311
252- if ((_pin != BOARD_SPI_OWN_SS ) && (_spi.pin_ssel == NC))
312+ if ((_pin != CS_PIN_CONTROLLED_BY_USER ) && (_spi.pin_ssel == NC))
253313 digitalWrite (_pin, LOW);
254314
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 );
256316
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))
258318 digitalWrite (_pin, HIGH);
259319}
260320
0 commit comments