Skip to content

Commit cf597fc

Browse files
committed
- more cleanup and testing
- adapted transfer(buf, t count) to use the faster code of transfer(buf, rxbuf, count) from @greiman
1 parent c6299c3 commit cf597fc

File tree

1 file changed

+132
-149
lines changed

1 file changed

+132
-149
lines changed

libraries/SPI/SPI.cpp

Lines changed: 132 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -260,39 +260,58 @@ void ArduinoSPI::transfer(void *buf, size_t count)
260260
else
261261
{
262262
if(buf) {
263-
264263
uint32_t *buffer32 = (uint32_t *) buf;
264+
size_t ir = 0;
265+
size_t it = 0;
266+
size_t n32 = count / 4U;
267+
count &= 3U;
265268

266-
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
267-
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */
268-
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */
269-
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
269+
if(n32) {
270+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
271+
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */
272+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */
273+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
274+
275+
while ((it < 2U) && (it < n32)) {
276+
if (_spi_ctrl.p_regs->SPSR_b.SPTEF) {
277+
_spi_ctrl.p_regs->SPDR = buffer32[it];
278+
it++;
279+
}
280+
}
270281

271-
size_t n32 = count / 4;
272-
count &= 3U;
282+
while (it < n32) {
283+
if (_spi_ctrl.p_regs->SPSR_b.SPRF) {
284+
uint32_t tmp = _spi_ctrl.p_regs->SPDR;
285+
_spi_ctrl.p_regs->SPDR = buffer32[it];
286+
buffer32[ir] = tmp;
287+
ir++;
288+
it++;
289+
}
290+
}
273291

274-
for (;n32 > 0; n32--) {
275-
_spi_ctrl.p_regs->SPDR = buffer32[0];
276-
while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
277-
buffer32[0] = _spi_ctrl.p_regs->SPDR;
278-
buffer32++;
279-
}
292+
while (ir < n32) { /* collect the last word received */
293+
if (_spi_ctrl.p_regs->SPSR_b.SPRF) {
294+
uint32_t tmp = _spi_ctrl.p_regs->SPDR;
295+
buffer32[ir] = tmp;
296+
ir++;
297+
}
298+
}
280299

281-
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
282-
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */
283-
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */
284-
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
300+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
301+
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */
302+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */
303+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
304+
}
285305

286-
uint8_t *buffer = (uint8_t *) buffer32;
306+
uint8_t *buffer = (uint8_t *) &buffer32[ir];
287307

288-
for (; count > 0; count--) {
308+
/* send the remaining bytes with 8-bit transfers */
309+
for (; count > 0U; count--) {
289310
_spi_ctrl.p_regs->SPDR_BY = buffer[0];
290-
while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
311+
while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
291312
buffer[0] = _spi_ctrl.p_regs->SPDR_BY;
292313
buffer++;
293314
}
294-
295-
// while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {}
296315
}
297316
}
298317
}
@@ -315,66 +334,65 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count)
315334
}
316335
}
317336
else {
318-
size_t n32 = count / 4;
337+
size_t n32 = count / 4U;
319338
if (n32) {
339+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
340+
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */
341+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */
342+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
320343

321-
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
322-
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */
323-
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */
324-
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
325-
326-
const uint32_t* tx32 = (const uint32_t *) buf;
327-
uint32_t* rx32 = (uint32_t *) rxbuf;
328-
size_t ir = 0;
329-
size_t it = 0;
344+
const uint32_t* tx32 = (const uint32_t *) buf;
345+
uint32_t* rx32 = (uint32_t *) rxbuf;
346+
size_t ir = 0;
347+
size_t it = 0;
330348

331-
while ((it < 2) && (it < n32)) {
332-
if (_spi_ctrl.p_regs->SPSR_b.SPTEF) {
333-
_spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF;
334-
it++;
349+
while ((it < 2U) && (it < n32)) {
350+
if (_spi_ctrl.p_regs->SPSR_b.SPTEF) {
351+
_spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF;
352+
it++;
353+
}
335354
}
336-
}
337355

338-
while (it < n32) {
339-
if (_spi_ctrl.p_regs->SPSR_b.SPRF) {
340-
uint32_t tmp = _spi_ctrl.p_regs->SPDR;
341-
_spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF;
342-
if (rxbuf) {
343-
rx32[ir] = tmp;
356+
while (it < n32) {
357+
if (_spi_ctrl.p_regs->SPSR_b.SPRF) {
358+
uint32_t tmp = _spi_ctrl.p_regs->SPDR;
359+
_spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF;
360+
if (rxbuf) {
361+
rx32[ir] = tmp;
362+
}
363+
ir++;
364+
it++;
344365
}
345-
ir++;
346-
it++;
347366
}
348-
}
349367

350-
while (ir < n32) { /* collect the last word received */
351-
if (_spi_ctrl.p_regs->SPSR_b.SPRF) {
352-
uint32_t tmp = _spi_ctrl.p_regs->SPDR;
353-
if (rxbuf) {
354-
rx32[ir] = tmp;
368+
while (ir < n32) { /* collect the last word received */
369+
if (_spi_ctrl.p_regs->SPSR_b.SPRF) {
370+
uint32_t tmp = _spi_ctrl.p_regs->SPDR;
371+
if (rxbuf) {
372+
rx32[ir] = tmp;
373+
}
374+
ir++;
355375
}
356-
ir++;
357376
}
358-
}
359-
}
360377

361-
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
362-
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */
363-
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */
364-
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
378+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
379+
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */
380+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */
381+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
382+
}
365383

366-
/* send the remaining bytes with 8-bit transfers */
367-
if (count != 4 * n32) {
368-
uint8_t* rx = (uint8_t *) rxbuf;
369-
const uint8_t* tx = (const uint8_t *) buf;
370-
for (size_t i = 4 * n32; i < count; i++) {
371-
uint8_t tmp = transfer((buf) ? tx[i] : 0xFF);
372-
if (rxbuf) {
373-
rx[i] = tmp;
384+
/* send the remaining bytes with 8-bit transfers */
385+
if (count != (4U * n32)) {
386+
uint8_t *rx = (uint8_t *) rxbuf;
387+
const uint8_t* tx = (const uint8_t *) buf;
388+
for (size_t i = 4U * n32; i < count; i++) {
389+
uint8_t tmp = transfer((buf) ? tx[i] : 0xFF);
390+
if (rxbuf) {
391+
rx[i] = tmp;
392+
}
374393
}
375394
}
376395
}
377-
}
378396
}
379397

380398

@@ -491,106 +509,71 @@ void ArduinoSPI::configSpiSettings(arduino::SPISettings const & settings)
491509

492510
void ArduinoSPI::configSpi(arduino::SPISettings const & settings)
493511
{
494-
#if 0
495-
auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig(settings);
496-
497-
rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div;
498-
R_SPI_CalculateBitrate(settings.getClockFreq(), &spck_div);
499-
500-
uint32_t spcmd0 = _spi_ctrl.p_regs->SPCMD[0];
501-
502-
/* Configure CPHA setting. */
503-
spcmd0 |= (uint32_t) clk_phase;
504-
505-
/* Configure CPOL setting. */
506-
spcmd0 |= (uint32_t) clk_polarity << 1;
512+
/** SPI base register access macro. */
513+
#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \
514+
((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * (channel)))
507515

508-
/* Configure Bit Order (MSB,LSB) */
509-
spcmd0 |= (uint32_t) bit_order << 12;
516+
_spi_ctrl.p_cfg = &_spi_cfg;
517+
_spi_ctrl.p_callback = _spi_cfg.p_callback;
518+
_spi_ctrl.p_context = _spi_cfg.p_context;
519+
_spi_ctrl.p_callback_memory = NULL;
520+
_spi_ctrl.p_regs = SPI_REG(_spi_ctrl.p_cfg->channel);
510521

511-
/* Configure the Bit Rate Division Setting */
512-
spcmd0 &= !(((uint32_t)0xFF) << 2);
513-
spcmd0 |= (uint32_t) spck_div.brdv << 2;
522+
auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig(settings);
523+
rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div;
524+
R_SPI_CalculateBitrate(settings.getClockFreq(), &spck_div);
514525

515-
/* Update settings. */
516-
_spi_ctrl.p_regs->SPCMD[0] = (uint16_t) spcmd0;
517-
_spi_ctrl.p_regs->SPBR = (uint8_t) spck_div.spbr;
518-
#endif
526+
_spi_ctrl.p_regs->SPCR = 0; /* disable SPI unit */
519527

520-
#if 1
521-
/** SPI base register access macro. */
522-
#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \
523-
((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * (channel)))
528+
/* Power up the SPI module. */
529+
R_BSP_MODULE_START(FSP_IP_SPI, _spi_cfg.channel);
524530

525-
_spi_ctrl.p_cfg = &_spi_cfg;
526-
_spi_ctrl.p_callback = _spi_cfg.p_callback;
527-
_spi_ctrl.p_context = _spi_cfg.p_context;
528-
_spi_ctrl.p_callback_memory = NULL;
529-
_spi_ctrl.p_regs = SPI_REG(_spi_ctrl.p_cfg->channel);
531+
/* configure SSLn polarity setting. */
532+
uint32_t sslp = 0;
533+
sslp |= (uint32_t) _spi_ext_cfg.ssl_polarity << _spi_ext_cfg.ssl_select;
534+
_spi_ctrl.p_regs->SSLP = (uint8_t) sslp;
530535

531-
auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig(settings);
536+
uint32_t sppcr = 0;
537+
/* set MOSI idle value to low */
538+
sppcr |= R_SPI0_SPPCR_MOIFE_Msk;
539+
_spi_ctrl.p_regs->SPPCR = (uint8_t) sppcr;
532540

533-
rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div;
534-
R_SPI_CalculateBitrate(settings.getClockFreq(), &spck_div);
535-
536-
uint32_t spcmd0 = 0;
537-
uint32_t spcr = 0;
538-
uint32_t sslp = 0;
539-
uint32_t sppcr = 0;
540-
uint32_t spcr2 = 0;
541-
uint32_t spckd = 0;
542-
uint32_t sslnd = 0;
543-
uint32_t spnd = 0;
544-
545-
spcmd0 |= (uint32_t) clk_phase; /* Configure CPHA setting. */
546-
spcmd0 |= (uint32_t) clk_polarity << 1; /* Configure CPOL setting. */
547-
spcmd0 |= (uint32_t) spck_div.brdv << 2; /* Configure the Bit Rate Division Setting */
548-
spcmd0 |= (uint32_t) SPI_BIT_WIDTH_8_BITS << 8; /* Configure 8 bit data width */
549-
spcmd0 |= (uint32_t) bit_order << 12; /* Configure Bit Order (MSB,LSB) */
550-
551-
/* SPMS = 0 -> SPI operation, TXMD = 0 -> full duplex, SPxIE = 0 -> no interrupts */
552-
if(SPI_MODE_MASTER == _spi_cfg.operating_mode)
553-
{
554-
spcr |= R_SPI0_SPCR_MSTR_Msk;
555-
spcr2 |= R_SPI0_SPCR2_SCKASE_Msk;
556-
}
541+
/* configure bit rate */
542+
_spi_ctrl.p_regs->SPBR = (uint8_t) spck_div.spbr;
557543

558-
/* Configure SSLn polarity setting. */
559-
sslp |= (uint32_t) _spi_ext_cfg.ssl_polarity << _spi_ext_cfg.ssl_select;
544+
/* the SPBYT bit in SPDCR is documented only by "Technical Update" */
545+
_spi_ctrl.p_regs->SPDCR_b.SPBYT = 1; /* SPI byte access */
560546

561-
/* set MOSI idle value to low */
562-
sppcr |= R_SPI0_SPPCR_MOIFE_Msk;
547+
/* register undocumented for the RA4M1 but found to be working and necessary */
548+
/* BYSW - Byte Swap Operating Mode Select - 1 = Byte Swap ON - essential for 32 bit transfers */
549+
_spi_ctrl.p_regs->SPDCR2_b.BYSW = 1;
563550

564-
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
551+
_spi_ctrl.p_regs->SPCKD = 0;
565552

566-
/* Power up the SPI module. */
567-
R_BSP_MODULE_START(FSP_IP_SPI, _spi_cfg.channel);
553+
_spi_ctrl.p_regs->SSLND = 0;
568554

569-
/* Write registers */
570-
_spi_ctrl.p_regs->SPCR = (uint8_t) spcr;
571-
_spi_ctrl.p_regs->SSLP = (uint8_t) sslp;
572-
_spi_ctrl.p_regs->SPPCR = (uint8_t) sppcr;
573-
_spi_ctrl.p_regs->SPCKD = (uint8_t) spckd;
574-
_spi_ctrl.p_regs->SSLND = (uint8_t) sslnd;
575-
_spi_ctrl.p_regs->SPND = (uint8_t) spnd;
576-
_spi_ctrl.p_regs->SPCR2 = (uint8_t) spcr2;
555+
_spi_ctrl.p_regs->SPND = 0;
577556

578-
_spi_ctrl.p_regs->SPCMD[0] = (uint16_t) spcmd0;
579-
_spi_ctrl.p_regs->SPBR = (uint8_t) spck_div.spbr;
557+
_spi_ctrl.p_regs->SPCR2 = 0;
580558

581-
_spi_ctrl.p_regs->SPDCR_b.SPBYT = 1; /* SPI byte access */
559+
/* SPMS = 0 -> SPI operation, TXMD = 0 -> full-duplex, SPxIE = 0 -> no interrupts */
560+
if(SPI_MODE_MASTER == _spi_cfg.operating_mode) {
561+
_spi_ctrl.p_regs->SPCR_b.MSTR = 1;
562+
}
582563

583-
/* register undocumented for the RA4M1 but found to be working and necessary */
584-
/* BYSW - Byte Swap Operating Mode Select - 1 = Byte Swap ON - essential for 32 bit transfers */
585-
_spi_ctrl.p_regs->SPDCR2_b.BYSW = 1;
564+
_spi_ctrl.p_regs->SPCMD[0] = 0;
565+
_spi_ctrl.p_regs->SPCMD_b[0].CPHA = clk_phase;
566+
_spi_ctrl.p_regs->SPCMD_b[0].CPOL = clk_polarity;
567+
_spi_ctrl.p_regs->SPCMD_b[0].BRDV = spck_div.brdv; /* set bit rate division */
568+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */
569+
_spi_ctrl.p_regs->SPCMD_b[0].LSBF = bit_order;
586570

587-
_spi_ctrl.p_regs->SPSR; /* read to clear OVRF */
588-
_spi_ctrl.p_regs->SPSR = 0; /* clear status register */
571+
_spi_ctrl.p_regs->SPSR; /* read to clear OVRF */
572+
_spi_ctrl.p_regs->SPSR = 0; /* clear status register */
589573

590-
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
574+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
591575

592-
_spi_ctrl.open = (0x52535049ULL); /* "SPI" in ASCII, used to determine if channel is open. */
593-
#endif
576+
_spi_ctrl.open = (0x52535049ULL); /* "SPI" in ASCII, used to determine if channel is open. */
594577
}
595578

596579
void ArduinoSPI::configSpiSci(arduino::SPISettings const & settings)

0 commit comments

Comments
 (0)