@@ -102,7 +102,7 @@ void ArduinoSPI::begin()
102
102
_cb_event_idx = _channel;
103
103
104
104
_spi_cfg.p_extend = &_spi_ext_cfg;
105
- _spi_cfg.p_callback = spi_callback ;
105
+ _spi_cfg.p_callback = nullptr ;
106
106
}
107
107
108
108
/* SPI configuration for SPI HAL driver. */
@@ -164,22 +164,8 @@ void ArduinoSPI::begin()
164
164
init_ok = false ;
165
165
}
166
166
}
167
- else
168
- {
169
- SpiMasterIrqReq_t irq_req
170
- {
171
- .ctrl = &_spi_ctrl,
172
- .cfg = &_spi_cfg,
173
- .hw_channel = (uint8_t )_channel,
174
- };
175
- init_ok &= IRQManager::getInstance ().addPeripheral (IRQ_SPI_MASTER, &irq_req);
176
167
177
- if (FSP_SUCCESS == _open (&_spi_ctrl, &_spi_cfg)) {
178
- init_ok &= true ;
179
- } else {
180
- init_ok = false ;
181
- }
182
- }
168
+ /* not using FSP for SPI anymore and no interrupts */
183
169
184
170
_is_initialized = init_ok;
185
171
}
@@ -196,24 +182,31 @@ void ArduinoSPI::end()
196
182
197
183
uint8_t ArduinoSPI::transfer (uint8_t data)
198
184
{
199
- uint8_t rxbuf;
200
- _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
201
- if (_is_sci) {
202
- _write_then_read (&_spi_sci_ctrl, &data, &rxbuf, 1 , SPI_BIT_WIDTH_8_BITS);
203
- } else {
204
- _write_then_read (&_spi_ctrl, &data, &rxbuf, 1 , SPI_BIT_WIDTH_8_BITS);
205
- }
185
+ uint8_t rxbuf;
186
+
187
+ if (_is_sci) {
188
+ _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
189
+
190
+ _write_then_read (&_spi_sci_ctrl, &data, &rxbuf, 1 , SPI_BIT_WIDTH_8_BITS);
191
+
192
+ for (auto const start = millis ();
193
+ (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis () - start < 1000 ); )
194
+ {
195
+ __NOP ();
196
+ }
197
+ if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
198
+ {
199
+ end ();
200
+ return 0 ;
201
+ }
202
+ }
203
+ else
204
+ {
205
+ _spi_ctrl.p_regs ->SPDR_BY = data;
206
+ while (0U == _spi_ctrl.p_regs ->SPSR_b .SPRF ) {}
207
+ rxbuf = _spi_ctrl.p_regs ->SPDR_BY ;
208
+ }
206
209
207
- for (auto const start = millis ();
208
- (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis () - start < 1000 ); )
209
- {
210
- __NOP ();
211
- }
212
- if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
213
- {
214
- end ();
215
- return 0 ;
216
- }
217
210
return rxbuf;
218
211
}
219
212
@@ -234,23 +227,78 @@ uint16_t ArduinoSPI::transfer16(uint16_t data)
234
227
235
228
void ArduinoSPI::transfer (void *buf, size_t count)
236
229
{
237
- _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
230
+ if (NULL == buf) {
231
+ return ;
232
+ }
238
233
239
- if (_is_sci) {
240
- _write_then_read (&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS);
241
- } else {
242
- _write_then_read (&_spi_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS);
243
- }
234
+ if (_is_sci) {
235
+ _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
244
236
245
- for (auto const start = millis ();
246
- (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis () - start < 1000 ); )
247
- {
248
- __NOP ();
249
- }
250
- if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
251
- {
252
- end ();
253
- }
237
+ _write_then_read (&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS);
238
+
239
+ for (auto const start = millis ();
240
+ (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis () - start < 1000 ); )
241
+ {
242
+ __NOP ();
243
+ }
244
+ if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
245
+ {
246
+ end ();
247
+ }
248
+ }
249
+ else {
250
+ uint32_t *buffer32 = (uint32_t *) buf;
251
+ size_t index_rx = 0 ;
252
+ size_t index_tx = 0 ;
253
+ size_t const n32 = count / 4U ;
254
+ uint8_t const bytes_remaining = (uint8_t ) (count & 3U );
255
+
256
+ if (n32 != 0U ) {
257
+ _spi_ctrl.p_regs ->SPCR_b .SPE = 0 ; /* disable SPI unit */
258
+ _spi_ctrl.p_regs ->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */
259
+ _spi_ctrl.p_regs ->SPCMD_b [0 ].SPB = 2 ; /* spi bit width = 32 */
260
+ _spi_ctrl.p_regs ->SPCR_b .SPE = 1 ; /* enable SPI unit */
261
+
262
+ while ((index_tx < 2U ) && (index_tx < n32)) {
263
+ if (_spi_ctrl.p_regs ->SPSR_b .SPTEF ) {
264
+ _spi_ctrl.p_regs ->SPDR = buffer32[index_tx];
265
+ index_tx++;
266
+ }
267
+ }
268
+
269
+ while (index_tx < n32) {
270
+ if (_spi_ctrl.p_regs ->SPSR_b .SPRF ) {
271
+ uint32_t tmp = _spi_ctrl.p_regs ->SPDR ;
272
+ _spi_ctrl.p_regs ->SPDR = buffer32[index_tx];
273
+ buffer32[index_rx] = tmp;
274
+ index_rx++;
275
+ index_tx++;
276
+ }
277
+ }
278
+
279
+ while (index_rx < n32) { /* collect the last word received */
280
+ if (_spi_ctrl.p_regs ->SPSR_b .SPRF ) {
281
+ uint32_t tmp = _spi_ctrl.p_regs ->SPDR ;
282
+ buffer32[index_rx] = tmp;
283
+ index_rx++;
284
+ }
285
+ }
286
+
287
+ _spi_ctrl.p_regs ->SPCR_b .SPE = 0 ; /* disable SPI unit */
288
+ _spi_ctrl.p_regs ->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */
289
+ _spi_ctrl.p_regs ->SPCMD_b [0 ].SPB = 7 ; /* spi bit width = 8 */
290
+ _spi_ctrl.p_regs ->SPCR_b .SPE = 1 ; /* enable SPI unit */
291
+ }
292
+
293
+ /* send the remaining bytes with 8-bit transfers */
294
+ uint8_t *buffer = (uint8_t *) &buffer32[index_rx];
295
+
296
+ for (uint8_t index = 0 ; index < bytes_remaining; index ++) {
297
+ _spi_ctrl.p_regs ->SPDR_BY = buffer[index ];
298
+ while (0U == _spi_ctrl.p_regs ->SPSR_b .SPRF ) {}
299
+ buffer[index ] = _spi_ctrl.p_regs ->SPDR_BY ;
300
+ }
301
+ }
254
302
}
255
303
256
304
void ArduinoSPI::beginTransaction (arduino::SPISettings settings)
@@ -366,29 +414,71 @@ void ArduinoSPI::configSpiSettings(arduino::SPISettings const & settings)
366
414
367
415
void ArduinoSPI::configSpi (arduino::SPISettings const & settings)
368
416
{
369
- auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig (settings);
417
+ /* * SPI base register access macro. */
418
+ #define SPI_REG (channel ) ((R_SPI0_Type *) ((uint32_t ) R_SPI0 + \
419
+ ((uint32_t ) R_SPI1 - (uint32_t ) R_SPI0) * (channel)))
370
420
371
- rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div ;
372
- R_SPI_CalculateBitrate (settings.getClockFreq (), &spck_div);
421
+ _spi_ctrl.p_cfg = &_spi_cfg;
422
+ _spi_ctrl.p_callback = _spi_cfg.p_callback ;
423
+ _spi_ctrl.p_context = _spi_cfg.p_context ;
424
+ _spi_ctrl.p_callback_memory = NULL ;
425
+ _spi_ctrl.p_regs = SPI_REG (_spi_ctrl.p_cfg ->channel );
373
426
374
- uint32_t spcmd0 = _spi_ctrl.p_regs ->SPCMD [0 ];
427
+ auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig (settings);
428
+ rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div ;
429
+ R_SPI_CalculateBitrate (settings.getClockFreq (), &spck_div);
375
430
376
- /* Configure CPHA setting. */
377
- spcmd0 |= (uint32_t ) clk_phase;
431
+ _spi_ctrl.p_regs ->SPCR = 0 ; /* disable SPI unit */
378
432
379
- /* Configure CPOL setting . */
380
- spcmd0 |= ( uint32_t ) clk_polarity << 1 ;
433
+ /* Power up the SPI module . */
434
+ R_BSP_MODULE_START (FSP_IP_SPI, _spi_cfg. channel ) ;
381
435
382
- /* Configure Bit Order (MSB,LSB) */
383
- spcmd0 |= (uint32_t ) bit_order << 12 ;
436
+ /* configure SSLn polarity setting. */
437
+ uint32_t sslp = 0 ;
438
+ sslp |= (uint32_t ) _spi_ext_cfg.ssl_polarity << _spi_ext_cfg.ssl_select ;
439
+ _spi_ctrl.p_regs ->SSLP = (uint8_t ) sslp;
384
440
385
- /* Configure the Bit Rate Division Setting */
386
- spcmd0 &= ~(((uint32_t ) 3 ) << 2 );
387
- spcmd0 |= (uint32_t ) spck_div.brdv << 2 ;
441
+ uint32_t sppcr = 0 ;
442
+ /* set MOSI idle value to low */
443
+ sppcr |= R_SPI0_SPPCR_MOIFE_Msk;
444
+ _spi_ctrl.p_regs ->SPPCR = (uint8_t ) sppcr;
388
445
389
- /* Update settings. */
390
- _spi_ctrl.p_regs ->SPCMD [0 ] = (uint16_t ) spcmd0;
391
- _spi_ctrl.p_regs ->SPBR = (uint8_t ) spck_div.spbr ;
446
+ /* configure bit rate */
447
+ _spi_ctrl.p_regs ->SPBR = (uint8_t ) spck_div.spbr ;
448
+
449
+ /* the SPBYT bit in SPDCR is documented only by "Technical Update" */
450
+ _spi_ctrl.p_regs ->SPDCR_b .SPBYT = 1 ; /* SPI byte access */
451
+
452
+ /* register undocumented for the RA4M1 but found to be working and necessary */
453
+ /* BYSW - Byte Swap Operating Mode Select - 1 = Byte Swap ON - essential for 32 bit transfers */
454
+ _spi_ctrl.p_regs ->SPDCR2_b .BYSW = 1 ;
455
+
456
+ _spi_ctrl.p_regs ->SPCKD = 0 ;
457
+
458
+ _spi_ctrl.p_regs ->SSLND = 0 ;
459
+
460
+ _spi_ctrl.p_regs ->SPND = 0 ;
461
+
462
+ _spi_ctrl.p_regs ->SPCR2 = R_SPI0_SPCR2_SCKASE_Msk;
463
+
464
+ /* SPMS = 0 -> SPI operation, TXMD = 0 -> full-duplex, SPxIE = 0 -> no interrupts */
465
+ if (SPI_MODE_MASTER == _spi_cfg.operating_mode ) {
466
+ _spi_ctrl.p_regs ->SPCR_b .MSTR = 1 ;
467
+ }
468
+
469
+ _spi_ctrl.p_regs ->SPCMD [0 ] = 0 ;
470
+ _spi_ctrl.p_regs ->SPCMD_b [0 ].CPHA = clk_phase;
471
+ _spi_ctrl.p_regs ->SPCMD_b [0 ].CPOL = clk_polarity;
472
+ _spi_ctrl.p_regs ->SPCMD_b [0 ].BRDV = spck_div.brdv ; /* set bit rate division */
473
+ _spi_ctrl.p_regs ->SPCMD_b [0 ].SPB = 7 ; /* spi bit width = 8 */
474
+ _spi_ctrl.p_regs ->SPCMD_b [0 ].LSBF = bit_order;
475
+
476
+ _spi_ctrl.p_regs ->SPSR ; /* read to clear OVRF */
477
+ _spi_ctrl.p_regs ->SPSR = 0 ; /* clear status register */
478
+
479
+ _spi_ctrl.p_regs ->SPCR_b .SPE = 1 ; /* enable SPI unit */
480
+
481
+ _spi_ctrl.open = (0x52535049ULL ); /* "SPI" in ASCII, used to determine if channel is open. */
392
482
}
393
483
394
484
void ArduinoSPI::configSpiSci (arduino::SPISettings const & settings)
@@ -459,19 +549,6 @@ std::tuple<spi_clk_phase_t, spi_clk_polarity_t, spi_bit_order_t> ArduinoSPI::toF
459
549
* CALLBACKS FOR FSP FRAMEWORK
460
550
**************************************************************************************/
461
551
462
- void spi_callback (spi_callback_args_t *p_args)
463
- {
464
- if (SPI_EVENT_TRANSFER_COMPLETE == p_args->event )
465
- {
466
- _spi_cb_event[p_args->channel ] = SPI_EVENT_TRANSFER_COMPLETE;
467
- }
468
- else
469
- {
470
- /* Updating the flag here to capture and handle all other error events */
471
- _spi_cb_event[p_args->channel ] = SPI_EVENT_TRANSFER_ABORTED;
472
- }
473
- }
474
-
475
552
void sci_spi_callback (spi_callback_args_t *p_args)
476
553
{
477
554
int const spi_master_offset = SPI_MAX_SPI_CHANNELS;
0 commit comments