@@ -102,7 +102,7 @@ void ArduinoSPI::begin()
102102 _cb_event_idx = _channel;
103103
104104 _spi_cfg.p_extend = &_spi_ext_cfg;
105- _spi_cfg.p_callback = spi_callback ;
105+ _spi_cfg.p_callback = nullptr ;
106106 }
107107
108108 /* SPI configuration for SPI HAL driver. */
@@ -164,22 +164,8 @@ void ArduinoSPI::begin()
164164 init_ok = false ;
165165 }
166166 }
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);
176167
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 */
183169
184170 _is_initialized = init_ok;
185171}
@@ -196,24 +182,31 @@ void ArduinoSPI::end()
196182
197183uint8_t ArduinoSPI::transfer (uint8_t data)
198184{
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+ }
206209
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- }
217210 return rxbuf;
218211}
219212
@@ -234,23 +227,78 @@ uint16_t ArduinoSPI::transfer16(uint16_t data)
234227
235228void ArduinoSPI::transfer (void *buf, size_t count)
236229{
237- _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
230+ if (NULL == buf) {
231+ return ;
232+ }
238233
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;
244236
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+ }
254302}
255303
256304void ArduinoSPI::beginTransaction (arduino::SPISettings settings)
@@ -366,29 +414,71 @@ void ArduinoSPI::configSpiSettings(arduino::SPISettings const & settings)
366414
367415void ArduinoSPI::configSpi (arduino::SPISettings const & settings)
368416{
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)))
370420
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 );
373426
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);
375430
376- /* Configure CPHA setting. */
377- spcmd0 |= (uint32_t ) clk_phase;
431+ _spi_ctrl.p_regs ->SPCR = 0 ; /* disable SPI unit */
378432
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 ) ;
381435
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;
384440
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;
388445
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. */
392482}
393483
394484void 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
459549 * CALLBACKS FOR FSP FRAMEWORK
460550 **************************************************************************************/
461551
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-
475552void sci_spi_callback (spi_callback_args_t *p_args)
476553{
477554 int const spi_master_offset = SPI_MAX_SPI_CHANNELS;
0 commit comments