From 8499f96c8bc3de97769ebfa0f044fcd4e56acba1 Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Sat, 8 Jul 2023 18:35:14 +0200 Subject: [PATCH 01/15] - first draft for a much fast SPI class --- libraries/SPI/SPI.cpp | 104 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index d383473a4..f23ac6619 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -147,6 +147,7 @@ void ArduinoSPI::begin() configSpiSettings(DEFAULT_SPI_SETTINGS); +#if 0 /* Configure the Interrupt Controller. */ if (_is_sci) { @@ -180,6 +181,7 @@ void ArduinoSPI::begin() init_ok = false; } } +#endif _is_initialized = init_ok; } @@ -197,7 +199,8 @@ void ArduinoSPI::end() uint8_t ArduinoSPI::transfer(uint8_t data) { uint8_t rxbuf; - _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; +#if 0 + _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; if (_is_sci) { _write_then_read(&_spi_sci_ctrl, &data, &rxbuf, 1, SPI_BIT_WIDTH_8_BITS); } else { @@ -214,6 +217,16 @@ uint8_t ArduinoSPI::transfer(uint8_t data) end(); return 0; } +#endif + +#if 1 + _spi_ctrl.p_regs->SPDR_BY = data; +// while (0 == _spi_ctrl.p_regs->SPSR_b.SPTEF) {} +// while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} + while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + rxbuf = _spi_ctrl.p_regs->SPDR_BY; +#endif + return rxbuf; } @@ -234,6 +247,7 @@ uint16_t ArduinoSPI::transfer16(uint16_t data) void ArduinoSPI::transfer(void *buf, size_t count) { +#if 0 _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; if (_is_sci) { @@ -251,6 +265,19 @@ void ArduinoSPI::transfer(void *buf, size_t count) { end(); } +#endif + +#if 1 + uint8_t *buffer = (uint8_t *) buf; + + for(size_t index = 0; index < count; index++) + { + _spi_ctrl.p_regs->SPDR_BY = buffer[index]; + while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + buffer[index] = _spi_ctrl.p_regs->SPDR_BY; + } + while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} +#endif } void ArduinoSPI::beginTransaction(arduino::SPISettings settings) @@ -366,6 +393,7 @@ void ArduinoSPI::configSpiSettings(arduino::SPISettings const & settings) void ArduinoSPI::configSpi(arduino::SPISettings const & settings) { +#if 0 auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig(settings); rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div; @@ -383,12 +411,84 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings) spcmd0 |= (uint32_t) bit_order << 12; /* Configure the Bit Rate Division Setting */ - spcmd0 &= ~(((uint32_t) 3) << 2); + spcmd0 &= !(((uint32_t)0xFF) << 2); spcmd0 |= (uint32_t) spck_div.brdv << 2; /* Update settings. */ _spi_ctrl.p_regs->SPCMD[0] = (uint16_t) spcmd0; _spi_ctrl.p_regs->SPBR = (uint8_t) spck_div.spbr; +#endif + +#if 1 +/** SPI base register access macro. */ +#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \ + ((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * \ + (channel))) + + _spi_ctrl.p_cfg = &_spi_cfg; + _spi_ctrl.p_callback = _spi_cfg.p_callback; + _spi_ctrl.p_context = _spi_cfg.p_context; + _spi_ctrl.p_callback_memory = NULL; + _spi_ctrl.p_regs = SPI_REG(_spi_ctrl.p_cfg->channel); + + auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig(settings); + + rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div; + R_SPI_CalculateBitrate(settings.getClockFreq(), &spck_div); + + uint32_t spcmd0 = 0; + uint32_t spcr = 0; + uint32_t sslp = 0; + uint32_t sppcr = 0; + uint32_t spcr2 = 0; + uint32_t spckd = 0; + uint32_t sslnd = 0; + uint32_t spnd = 0; + + spcmd0 |= (uint32_t) clk_phase; /* Configure CPHA setting. */ + spcmd0 |= (uint32_t) clk_polarity << 1; /* Configure CPOL setting. */ + spcmd0 |= (uint32_t) spck_div.brdv << 2; /* Configure the Bit Rate Division Setting */ + spcmd0 |= (uint32_t) SPI_BIT_WIDTH_8_BITS << 8; /* Configure 8 bit data width */ + spcmd0 |= (uint32_t) bit_order << 12; /* Configure Bit Order (MSB,LSB) */ + + /* TXMD = 0 -> full duplex, SPxIE = 0 -> no interrupts */ + spcr |= R_SPI0_SPCR_SPMS_Msk; /* configure 3-Wire Mode */ + if(SPI_MODE_MASTER == _spi_cfg.operating_mode) + { + spcr |= R_SPI0_SPCR_MSTR_Msk; + spcr2 |= R_SPI0_SPCR2_SCKASE_Msk; + } + + /* Configure SSLn polarity setting. */ + sslp |= (uint32_t) _spi_ext_cfg.ssl_polarity << _spi_ext_cfg.ssl_select; + + /* set MOSI idle value to low */ + sppcr |= R_SPI0_SPPCR_MOIFE_Msk; + + /* Power up the SPI module. */ + R_BSP_MODULE_START(FSP_IP_SPI, _spi_cfg.channel); + + /* Write registers */ + _spi_ctrl.p_regs->SPCR = (uint8_t) spcr; + _spi_ctrl.p_regs->SSLP = (uint8_t) sslp; + _spi_ctrl.p_regs->SPPCR = (uint8_t) sppcr; + _spi_ctrl.p_regs->SPCKD = (uint8_t) spckd; + _spi_ctrl.p_regs->SSLND = (uint8_t) sslnd; + _spi_ctrl.p_regs->SPND = (uint8_t) spnd; + _spi_ctrl.p_regs->SPCR2 = (uint8_t) spcr2; + + _spi_ctrl.p_regs->SPCMD[0] = (uint16_t) spcmd0; + _spi_ctrl.p_regs->SPBR = (uint8_t) spck_div.spbr; + + _spi_ctrl.p_regs->SPDCR_b.SPBYT = 1; /* SPI byte access */ + + _spi_ctrl.p_regs->SPSR; /* read to clear OVRF */ + _spi_ctrl.p_regs->SPSR = 0; /* clear status register */ + + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + + _spi_ctrl.open = (0x52535049ULL); /* "SPI" in ASCII, used to determine if channel is open. */ +#endif } void ArduinoSPI::configSpiSci(arduino::SPISettings const & settings) From 6d7c1c213cf19ada365203e9adb6be34cd52ef57 Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Sun, 9 Jul 2023 09:34:44 +0200 Subject: [PATCH 02/15] - buffer transfers are even faster now by switching to 32 bit transfers --- libraries/SPI/SPI.cpp | 55 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index f23ac6619..c706007a1 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -220,11 +220,18 @@ uint8_t ArduinoSPI::transfer(uint8_t data) #endif #if 1 - _spi_ctrl.p_regs->SPDR_BY = data; + if (_is_sci) + { + + } + else + { + _spi_ctrl.p_regs->SPDR_BY = data; // while (0 == _spi_ctrl.p_regs->SPSR_b.SPTEF) {} // while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} - while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - rxbuf = _spi_ctrl.p_regs->SPDR_BY; + while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + rxbuf = _spi_ctrl.p_regs->SPDR_BY; + } #endif return rxbuf; @@ -268,15 +275,43 @@ void ArduinoSPI::transfer(void *buf, size_t count) #endif #if 1 - uint8_t *buffer = (uint8_t *) buf; + if (_is_sci) + { + } + else + { + uint32_t *buffer32 = (uint32_t *) buf; - for(size_t index = 0; index < count; index++) + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ + + size_t n32 = count / 4; + count &= 3U; + + for (;n32 > 0; n32--) { - _spi_ctrl.p_regs->SPDR_BY = buffer[index]; + _spi_ctrl.p_regs->SPDR = buffer32[0]; + while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + buffer32[0] = _spi_ctrl.p_regs->SPDR; + buffer32++; + } + + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ + + uint8_t *buffer = (uint8_t *) buffer32; + + for (; count > 0; count--) + { + _spi_ctrl.p_regs->SPDR_BY = buffer[0]; while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - buffer[index] = _spi_ctrl.p_regs->SPDR_BY; + buffer[0] = _spi_ctrl.p_regs->SPDR_BY; + buffer++; } - while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} + + while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} + } + #endif } @@ -482,6 +517,10 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings) _spi_ctrl.p_regs->SPDCR_b.SPBYT = 1; /* SPI byte access */ + /* register undocumented for the RA4M1 but found to be working and necessary */ + /* BYSW - Byte Swap Operating Mode Select - 1 = Byte Swap ON - essential for 32 bit transfers */ + _spi_ctrl.p_regs->SPDCR2_b.BYSW = 1; + _spi_ctrl.p_regs->SPSR; /* read to clear OVRF */ _spi_ctrl.p_regs->SPSR = 0; /* clear status register */ From c6299c31d27d1a09e0192b9213f995ca186cce26 Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:51:56 +0200 Subject: [PATCH 03/15] - added transfer(void *buf, void *rxbuf, size_t count), contributed by Bill Greiman - WIP --- libraries/SPI/SPI.cpp | 255 ++++++++++++++++++++++++++---------------- libraries/SPI/SPI.h | 1 + 2 files changed, 160 insertions(+), 96 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index c706007a1..afd23a308 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -147,7 +147,6 @@ void ArduinoSPI::begin() configSpiSettings(DEFAULT_SPI_SETTINGS); -#if 0 /* Configure the Interrupt Controller. */ if (_is_sci) { @@ -167,6 +166,8 @@ void ArduinoSPI::begin() } else { +#if 0 +/* not using FSP for SPI anymore and no interrupts */ SpiMasterIrqReq_t irq_req { .ctrl = &_spi_ctrl, @@ -180,8 +181,8 @@ void ArduinoSPI::begin() } else { init_ok = false; } - } #endif + } _is_initialized = init_ok; } @@ -198,123 +199,185 @@ void ArduinoSPI::end() uint8_t ArduinoSPI::transfer(uint8_t data) { - uint8_t rxbuf; -#if 0 - _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; - if (_is_sci) { - _write_then_read(&_spi_sci_ctrl, &data, &rxbuf, 1, SPI_BIT_WIDTH_8_BITS); - } else { - _write_then_read(&_spi_ctrl, &data, &rxbuf, 1, SPI_BIT_WIDTH_8_BITS); - } + uint8_t rxbuf; - for (auto const start = millis(); - (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) - { - __NOP(); - } - if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) - { - end(); - return 0; - } -#endif - -#if 1 - if (_is_sci) - { + if (_is_sci) { + _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; - } - else - { - _spi_ctrl.p_regs->SPDR_BY = data; -// while (0 == _spi_ctrl.p_regs->SPSR_b.SPTEF) {} -// while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} - while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - rxbuf = _spi_ctrl.p_regs->SPDR_BY; - } -#endif + for (auto const start = millis(); + (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) + { + __NOP(); + } + if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) + { + end(); + return 0; + } + } + else + { + _spi_ctrl.p_regs->SPDR_BY = data; + while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + rxbuf = _spi_ctrl.p_regs->SPDR_BY; + } return rxbuf; } uint16_t ArduinoSPI::transfer16(uint16_t data) { - union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t; - t.val = data; + union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t; + t.val = data; - if (_settings.getBitOrder() == LSBFIRST) { - t.lsb = transfer(t.lsb); - t.msb = transfer(t.msb); - } else { - t.msb = transfer(t.msb); - t.lsb = transfer(t.lsb); - } - return t.val; + if (_settings.getBitOrder() == LSBFIRST) { + t.lsb = transfer(t.lsb); + t.msb = transfer(t.msb); + } else { + t.msb = transfer(t.msb); + t.lsb = transfer(t.lsb); + } + return t.val; } void ArduinoSPI::transfer(void *buf, size_t count) { -#if 0 - _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; + if (_is_sci) { + _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; - if (_is_sci) { - _write_then_read(&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS); - } else { - _write_then_read(&_spi_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS); - } + _write_then_read(&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS); - for (auto const start = millis(); - (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) - { - __NOP(); - } - if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) - { - end(); - } -#endif + for (auto const start = millis(); + (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) + { + __NOP(); + } + if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) + { + end(); + } + } + else + { + if(buf) { -#if 1 - if (_is_sci) - { - } - else - { - uint32_t *buffer32 = (uint32_t *) buf; + uint32_t *buffer32 = (uint32_t *) buf; - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ - size_t n32 = count / 4; - count &= 3U; + size_t n32 = count / 4; + count &= 3U; - for (;n32 > 0; n32--) - { - _spi_ctrl.p_regs->SPDR = buffer32[0]; - while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - buffer32[0] = _spi_ctrl.p_regs->SPDR; - buffer32++; + for (;n32 > 0; n32--) { + _spi_ctrl.p_regs->SPDR = buffer32[0]; + while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + buffer32[0] = _spi_ctrl.p_regs->SPDR; + buffer32++; + } + + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + + uint8_t *buffer = (uint8_t *) buffer32; + + for (; count > 0; count--) { + _spi_ctrl.p_regs->SPDR_BY = buffer[0]; + while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + buffer[0] = _spi_ctrl.p_regs->SPDR_BY; + buffer++; + } + +// while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} + } } +} - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ +void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) +{ + if (_is_sci) { + _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; - uint8_t *buffer = (uint8_t *) buffer32; + _write_then_read(&_spi_sci_ctrl, buf, rxbuf, count, SPI_BIT_WIDTH_8_BITS); - for (; count > 0; count--) - { - _spi_ctrl.p_regs->SPDR_BY = buffer[0]; - while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - buffer[0] = _spi_ctrl.p_regs->SPDR_BY; - buffer++; + for (auto const start = millis(); + (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) + { + __NOP(); + } + if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) + { + end(); + } } + else { + size_t n32 = count / 4; + if (n32) { + + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + + const uint32_t* tx32 = (const uint32_t *) buf; + uint32_t* rx32 = (uint32_t *) rxbuf; + size_t ir = 0; + size_t it = 0; + + while ((it < 2) && (it < n32)) { + if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { + _spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF; + it++; + } + } - while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} - } + while (it < n32) { + if (_spi_ctrl.p_regs->SPSR_b.SPRF) { + uint32_t tmp = _spi_ctrl.p_regs->SPDR; + _spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF; + if (rxbuf) { + rx32[ir] = tmp; + } + ir++; + it++; + } + } -#endif + while (ir < n32) { /* collect the last word received */ + if (_spi_ctrl.p_regs->SPSR_b.SPRF) { + uint32_t tmp = _spi_ctrl.p_regs->SPDR; + if (rxbuf) { + rx32[ir] = tmp; + } + ir++; + } + } + } + + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + + /* send the remaining bytes with 8-bit transfers */ + if (count != 4 * n32) { + uint8_t* rx = (uint8_t *) rxbuf; + const uint8_t* tx = (const uint8_t *) buf; + for (size_t i = 4 * n32; i < count; i++) { + uint8_t tmp = transfer((buf) ? tx[i] : 0xFF); + if (rxbuf) { + rx[i] = tmp; + } + } + } + } } + void ArduinoSPI::beginTransaction(arduino::SPISettings settings) { if (!_is_initialized) @@ -456,9 +519,8 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings) #if 1 /** SPI base register access macro. */ -#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \ - ((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * \ - (channel))) +#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \ + ((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * (channel))) _spi_ctrl.p_cfg = &_spi_cfg; _spi_ctrl.p_callback = _spi_cfg.p_callback; @@ -486,8 +548,7 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings) spcmd0 |= (uint32_t) SPI_BIT_WIDTH_8_BITS << 8; /* Configure 8 bit data width */ spcmd0 |= (uint32_t) bit_order << 12; /* Configure Bit Order (MSB,LSB) */ - /* TXMD = 0 -> full duplex, SPxIE = 0 -> no interrupts */ - spcr |= R_SPI0_SPCR_SPMS_Msk; /* configure 3-Wire Mode */ + /* SPMS = 0 -> SPI operation, TXMD = 0 -> full duplex, SPxIE = 0 -> no interrupts */ if(SPI_MODE_MASTER == _spi_cfg.operating_mode) { spcr |= R_SPI0_SPCR_MSTR_Msk; @@ -500,6 +561,8 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings) /* set MOSI idle value to low */ sppcr |= R_SPI0_SPPCR_MOIFE_Msk; + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + /* Power up the SPI module. */ R_BSP_MODULE_START(FSP_IP_SPI, _spi_cfg.channel); diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index a76ce13f0..de521306f 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -71,6 +71,7 @@ class ArduinoSPI : public SPIClass virtual uint8_t transfer(uint8_t data); virtual uint16_t transfer16(uint16_t data); virtual void transfer(void *buf, size_t count); + virtual void transfer(void *buf, void *rxbuf, size_t count); // Transaction Functions virtual void usingInterrupt(int __attribute__((unused)) interruptNumber) { } From cf597fce05816baedf92d34e66ae68d198dbe78e Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Mon, 10 Jul 2023 21:51:55 +0200 Subject: [PATCH 04/15] - more cleanup and testing - adapted transfer(buf, t count) to use the faster code of transfer(buf, rxbuf, count) from @greiman --- libraries/SPI/SPI.cpp | 281 ++++++++++++++++++++---------------------- 1 file changed, 132 insertions(+), 149 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index afd23a308..5c6f0ccaf 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -260,39 +260,58 @@ void ArduinoSPI::transfer(void *buf, size_t count) else { if(buf) { - uint32_t *buffer32 = (uint32_t *) buf; + size_t ir = 0; + size_t it = 0; + size_t n32 = count / 4U; + count &= 3U; - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + if(n32) { + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + + while ((it < 2U) && (it < n32)) { + if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { + _spi_ctrl.p_regs->SPDR = buffer32[it]; + it++; + } + } - size_t n32 = count / 4; - count &= 3U; + while (it < n32) { + if (_spi_ctrl.p_regs->SPSR_b.SPRF) { + uint32_t tmp = _spi_ctrl.p_regs->SPDR; + _spi_ctrl.p_regs->SPDR = buffer32[it]; + buffer32[ir] = tmp; + ir++; + it++; + } + } - for (;n32 > 0; n32--) { - _spi_ctrl.p_regs->SPDR = buffer32[0]; - while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - buffer32[0] = _spi_ctrl.p_regs->SPDR; - buffer32++; - } + while (ir < n32) { /* collect the last word received */ + if (_spi_ctrl.p_regs->SPSR_b.SPRF) { + uint32_t tmp = _spi_ctrl.p_regs->SPDR; + buffer32[ir] = tmp; + ir++; + } + } - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + } - uint8_t *buffer = (uint8_t *) buffer32; + uint8_t *buffer = (uint8_t *) &buffer32[ir]; - for (; count > 0; count--) { + /* send the remaining bytes with 8-bit transfers */ + for (; count > 0U; count--) { _spi_ctrl.p_regs->SPDR_BY = buffer[0]; - while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {} buffer[0] = _spi_ctrl.p_regs->SPDR_BY; buffer++; } - -// while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {} } } } @@ -315,66 +334,65 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) } } else { - size_t n32 = count / 4; + size_t n32 = count / 4U; if (n32) { + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ - - const uint32_t* tx32 = (const uint32_t *) buf; - uint32_t* rx32 = (uint32_t *) rxbuf; - size_t ir = 0; - size_t it = 0; + const uint32_t* tx32 = (const uint32_t *) buf; + uint32_t* rx32 = (uint32_t *) rxbuf; + size_t ir = 0; + size_t it = 0; - while ((it < 2) && (it < n32)) { - if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { - _spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF; - it++; + while ((it < 2U) && (it < n32)) { + if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { + _spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF; + it++; + } } - } - while (it < n32) { - if (_spi_ctrl.p_regs->SPSR_b.SPRF) { - uint32_t tmp = _spi_ctrl.p_regs->SPDR; - _spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF; - if (rxbuf) { - rx32[ir] = tmp; + while (it < n32) { + if (_spi_ctrl.p_regs->SPSR_b.SPRF) { + uint32_t tmp = _spi_ctrl.p_regs->SPDR; + _spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF; + if (rxbuf) { + rx32[ir] = tmp; + } + ir++; + it++; } - ir++; - it++; } - } - while (ir < n32) { /* collect the last word received */ - if (_spi_ctrl.p_regs->SPSR_b.SPRF) { - uint32_t tmp = _spi_ctrl.p_regs->SPDR; - if (rxbuf) { - rx32[ir] = tmp; + while (ir < n32) { /* collect the last word received */ + if (_spi_ctrl.p_regs->SPSR_b.SPRF) { + uint32_t tmp = _spi_ctrl.p_regs->SPDR; + if (rxbuf) { + rx32[ir] = tmp; + } + ir++; } - ir++; } - } - } - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + } - /* send the remaining bytes with 8-bit transfers */ - if (count != 4 * n32) { - uint8_t* rx = (uint8_t *) rxbuf; - const uint8_t* tx = (const uint8_t *) buf; - for (size_t i = 4 * n32; i < count; i++) { - uint8_t tmp = transfer((buf) ? tx[i] : 0xFF); - if (rxbuf) { - rx[i] = tmp; + /* send the remaining bytes with 8-bit transfers */ + if (count != (4U * n32)) { + uint8_t *rx = (uint8_t *) rxbuf; + const uint8_t* tx = (const uint8_t *) buf; + for (size_t i = 4U * n32; i < count; i++) { + uint8_t tmp = transfer((buf) ? tx[i] : 0xFF); + if (rxbuf) { + rx[i] = tmp; + } } } } - } } @@ -491,106 +509,71 @@ void ArduinoSPI::configSpiSettings(arduino::SPISettings const & settings) void ArduinoSPI::configSpi(arduino::SPISettings const & settings) { -#if 0 - auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig(settings); - - rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div; - R_SPI_CalculateBitrate(settings.getClockFreq(), &spck_div); - - uint32_t spcmd0 = _spi_ctrl.p_regs->SPCMD[0]; - - /* Configure CPHA setting. */ - spcmd0 |= (uint32_t) clk_phase; - - /* Configure CPOL setting. */ - spcmd0 |= (uint32_t) clk_polarity << 1; +/** SPI base register access macro. */ +#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \ + ((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * (channel))) - /* Configure Bit Order (MSB,LSB) */ - spcmd0 |= (uint32_t) bit_order << 12; + _spi_ctrl.p_cfg = &_spi_cfg; + _spi_ctrl.p_callback = _spi_cfg.p_callback; + _spi_ctrl.p_context = _spi_cfg.p_context; + _spi_ctrl.p_callback_memory = NULL; + _spi_ctrl.p_regs = SPI_REG(_spi_ctrl.p_cfg->channel); - /* Configure the Bit Rate Division Setting */ - spcmd0 &= !(((uint32_t)0xFF) << 2); - spcmd0 |= (uint32_t) spck_div.brdv << 2; + auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig(settings); + rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div; + R_SPI_CalculateBitrate(settings.getClockFreq(), &spck_div); - /* Update settings. */ - _spi_ctrl.p_regs->SPCMD[0] = (uint16_t) spcmd0; - _spi_ctrl.p_regs->SPBR = (uint8_t) spck_div.spbr; -#endif + _spi_ctrl.p_regs->SPCR = 0; /* disable SPI unit */ -#if 1 -/** SPI base register access macro. */ -#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \ - ((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * (channel))) + /* Power up the SPI module. */ + R_BSP_MODULE_START(FSP_IP_SPI, _spi_cfg.channel); - _spi_ctrl.p_cfg = &_spi_cfg; - _spi_ctrl.p_callback = _spi_cfg.p_callback; - _spi_ctrl.p_context = _spi_cfg.p_context; - _spi_ctrl.p_callback_memory = NULL; - _spi_ctrl.p_regs = SPI_REG(_spi_ctrl.p_cfg->channel); + /* configure SSLn polarity setting. */ + uint32_t sslp = 0; + sslp |= (uint32_t) _spi_ext_cfg.ssl_polarity << _spi_ext_cfg.ssl_select; + _spi_ctrl.p_regs->SSLP = (uint8_t) sslp; - auto [clk_phase, clk_polarity, bit_order] = toFspSpiConfig(settings); + uint32_t sppcr = 0; + /* set MOSI idle value to low */ + sppcr |= R_SPI0_SPPCR_MOIFE_Msk; + _spi_ctrl.p_regs->SPPCR = (uint8_t) sppcr; - rspck_div_setting_t spck_div = _spi_ext_cfg.spck_div; - R_SPI_CalculateBitrate(settings.getClockFreq(), &spck_div); - - uint32_t spcmd0 = 0; - uint32_t spcr = 0; - uint32_t sslp = 0; - uint32_t sppcr = 0; - uint32_t spcr2 = 0; - uint32_t spckd = 0; - uint32_t sslnd = 0; - uint32_t spnd = 0; - - spcmd0 |= (uint32_t) clk_phase; /* Configure CPHA setting. */ - spcmd0 |= (uint32_t) clk_polarity << 1; /* Configure CPOL setting. */ - spcmd0 |= (uint32_t) spck_div.brdv << 2; /* Configure the Bit Rate Division Setting */ - spcmd0 |= (uint32_t) SPI_BIT_WIDTH_8_BITS << 8; /* Configure 8 bit data width */ - spcmd0 |= (uint32_t) bit_order << 12; /* Configure Bit Order (MSB,LSB) */ - - /* SPMS = 0 -> SPI operation, TXMD = 0 -> full duplex, SPxIE = 0 -> no interrupts */ - if(SPI_MODE_MASTER == _spi_cfg.operating_mode) - { - spcr |= R_SPI0_SPCR_MSTR_Msk; - spcr2 |= R_SPI0_SPCR2_SCKASE_Msk; - } + /* configure bit rate */ + _spi_ctrl.p_regs->SPBR = (uint8_t) spck_div.spbr; - /* Configure SSLn polarity setting. */ - sslp |= (uint32_t) _spi_ext_cfg.ssl_polarity << _spi_ext_cfg.ssl_select; + /* the SPBYT bit in SPDCR is documented only by "Technical Update" */ + _spi_ctrl.p_regs->SPDCR_b.SPBYT = 1; /* SPI byte access */ - /* set MOSI idle value to low */ - sppcr |= R_SPI0_SPPCR_MOIFE_Msk; + /* register undocumented for the RA4M1 but found to be working and necessary */ + /* BYSW - Byte Swap Operating Mode Select - 1 = Byte Swap ON - essential for 32 bit transfers */ + _spi_ctrl.p_regs->SPDCR2_b.BYSW = 1; - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPCKD = 0; - /* Power up the SPI module. */ - R_BSP_MODULE_START(FSP_IP_SPI, _spi_cfg.channel); + _spi_ctrl.p_regs->SSLND = 0; - /* Write registers */ - _spi_ctrl.p_regs->SPCR = (uint8_t) spcr; - _spi_ctrl.p_regs->SSLP = (uint8_t) sslp; - _spi_ctrl.p_regs->SPPCR = (uint8_t) sppcr; - _spi_ctrl.p_regs->SPCKD = (uint8_t) spckd; - _spi_ctrl.p_regs->SSLND = (uint8_t) sslnd; - _spi_ctrl.p_regs->SPND = (uint8_t) spnd; - _spi_ctrl.p_regs->SPCR2 = (uint8_t) spcr2; + _spi_ctrl.p_regs->SPND = 0; - _spi_ctrl.p_regs->SPCMD[0] = (uint16_t) spcmd0; - _spi_ctrl.p_regs->SPBR = (uint8_t) spck_div.spbr; + _spi_ctrl.p_regs->SPCR2 = 0; - _spi_ctrl.p_regs->SPDCR_b.SPBYT = 1; /* SPI byte access */ + /* SPMS = 0 -> SPI operation, TXMD = 0 -> full-duplex, SPxIE = 0 -> no interrupts */ + if(SPI_MODE_MASTER == _spi_cfg.operating_mode) { + _spi_ctrl.p_regs->SPCR_b.MSTR = 1; + } - /* register undocumented for the RA4M1 but found to be working and necessary */ - /* BYSW - Byte Swap Operating Mode Select - 1 = Byte Swap ON - essential for 32 bit transfers */ - _spi_ctrl.p_regs->SPDCR2_b.BYSW = 1; + _spi_ctrl.p_regs->SPCMD[0] = 0; + _spi_ctrl.p_regs->SPCMD_b[0].CPHA = clk_phase; + _spi_ctrl.p_regs->SPCMD_b[0].CPOL = clk_polarity; + _spi_ctrl.p_regs->SPCMD_b[0].BRDV = spck_div.brdv; /* set bit rate division */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ + _spi_ctrl.p_regs->SPCMD_b[0].LSBF = bit_order; - _spi_ctrl.p_regs->SPSR; /* read to clear OVRF */ - _spi_ctrl.p_regs->SPSR = 0; /* clear status register */ + _spi_ctrl.p_regs->SPSR; /* read to clear OVRF */ + _spi_ctrl.p_regs->SPSR = 0; /* clear status register */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ - _spi_ctrl.open = (0x52535049ULL); /* "SPI" in ASCII, used to determine if channel is open. */ -#endif + _spi_ctrl.open = (0x52535049ULL); /* "SPI" in ASCII, used to determine if channel is open. */ } void ArduinoSPI::configSpiSci(arduino::SPISettings const & settings) From 8c6c694542b1acaff62c7ff7bb5a3bc69deaa067 Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Mon, 10 Jul 2023 22:11:59 +0200 Subject: [PATCH 05/15] - minor coding guideline fixes --- libraries/SPI/SPI.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 5c6f0ccaf..40fe31a52 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -218,7 +218,7 @@ uint8_t ArduinoSPI::transfer(uint8_t data) else { _spi_ctrl.p_regs->SPDR_BY = data; - while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {} rxbuf = _spi_ctrl.p_regs->SPDR_BY; } @@ -259,14 +259,14 @@ void ArduinoSPI::transfer(void *buf, size_t count) } else { - if(buf) { + if (buf) { uint32_t *buffer32 = (uint32_t *) buf; size_t ir = 0; size_t it = 0; size_t n32 = count / 4U; count &= 3U; - if(n32) { + if (n32) { _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ @@ -557,7 +557,7 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings) _spi_ctrl.p_regs->SPCR2 = 0; /* SPMS = 0 -> SPI operation, TXMD = 0 -> full-duplex, SPxIE = 0 -> no interrupts */ - if(SPI_MODE_MASTER == _spi_cfg.operating_mode) { + if (SPI_MODE_MASTER == _spi_cfg.operating_mode) { _spi_ctrl.p_regs->SPCR_b.MSTR = 1; } From 2d0bedc701eb26337bd2fd5d2b97ec4f9b3247af Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Tue, 11 Jul 2023 15:58:47 +0200 Subject: [PATCH 06/15] - sped up transfer(buf, rxbuf, count) a little by making it use direct byte transfers and not calling transfer(data) --- libraries/SPI/SPI.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 40fe31a52..f76c782bc 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -386,7 +386,9 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) uint8_t *rx = (uint8_t *) rxbuf; const uint8_t* tx = (const uint8_t *) buf; for (size_t i = 4U * n32; i < count; i++) { - uint8_t tmp = transfer((buf) ? tx[i] : 0xFF); + _spi_ctrl.p_regs->SPDR_BY = (buf) ? tx[i] : 0xFF; + while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + uint8_t tmp = _spi_ctrl.p_regs->SPDR_BY; if (rxbuf) { rx[i] = tmp; } @@ -395,7 +397,6 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) } } - void ArduinoSPI::beginTransaction(arduino::SPISettings settings) { if (!_is_initialized) From aa013bdcf086af90298eb960edc92deb3362647d Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:11:41 +0200 Subject: [PATCH 07/15] - more minor coding standard fixes --- libraries/SPI/SPI.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index f76c782bc..db1fe6c1a 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -259,14 +259,14 @@ void ArduinoSPI::transfer(void *buf, size_t count) } else { - if (buf) { + if (buf != NULL) { uint32_t *buffer32 = (uint32_t *) buf; size_t ir = 0; size_t it = 0; - size_t n32 = count / 4U; - count &= 3U; + size_t const n32 = count / 4U; + uint8_t const bytes_remaining = (uint8_t) (count & 3U); - if (n32) { + if (n32 != 0U) { _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ @@ -303,14 +303,13 @@ void ArduinoSPI::transfer(void *buf, size_t count) _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ } + /* send the remaining bytes with 8-bit transfers */ uint8_t *buffer = (uint8_t *) &buffer32[ir]; - /* send the remaining bytes with 8-bit transfers */ - for (; count > 0U; count--) { - _spi_ctrl.p_regs->SPDR_BY = buffer[0]; + for (uint8_t index = 0; index < bytes_remaining; index++) { + _spi_ctrl.p_regs->SPDR_BY = buffer[index]; while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - buffer[0] = _spi_ctrl.p_regs->SPDR_BY; - buffer++; + buffer[index] = _spi_ctrl.p_regs->SPDR_BY; } } } @@ -335,7 +334,7 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) } else { size_t n32 = count / 4U; - if (n32) { + if (n32 != 0U) { _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ @@ -348,7 +347,7 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) while ((it < 2U) && (it < n32)) { if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { - _spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF; + _spi_ctrl.p_regs->SPDR = (buf != NULL) ? tx32[it] : 0xFFFFFFFF; it++; } } @@ -356,8 +355,8 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) while (it < n32) { if (_spi_ctrl.p_regs->SPSR_b.SPRF) { uint32_t tmp = _spi_ctrl.p_regs->SPDR; - _spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF; - if (rxbuf) { + _spi_ctrl.p_regs->SPDR = (buf != NULL) ? tx32[it] : 0xFFFFFFFF; + if (rxbuf != NULL) { rx32[ir] = tmp; } ir++; @@ -368,7 +367,7 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) while (ir < n32) { /* collect the last word received */ if (_spi_ctrl.p_regs->SPSR_b.SPRF) { uint32_t tmp = _spi_ctrl.p_regs->SPDR; - if (rxbuf) { + if (rxbuf != NULL) { rx32[ir] = tmp; } ir++; @@ -386,10 +385,10 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) uint8_t *rx = (uint8_t *) rxbuf; const uint8_t* tx = (const uint8_t *) buf; for (size_t i = 4U * n32; i < count; i++) { - _spi_ctrl.p_regs->SPDR_BY = (buf) ? tx[i] : 0xFF; + _spi_ctrl.p_regs->SPDR_BY = (buf != NULL) ? tx[i] : 0xFF; while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {} uint8_t tmp = _spi_ctrl.p_regs->SPDR_BY; - if (rxbuf) { + if (rxbuf != NULL) { rx[i] = tmp; } } From 7df21447d74ee15237c5619a2900cfa61670b4db Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Tue, 11 Jul 2023 22:01:38 +0200 Subject: [PATCH 08/15] - fix, a line from the SCI code in transfer(data) was missing --- libraries/SPI/SPI.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index db1fe6c1a..209e8d480 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -204,6 +204,8 @@ uint8_t ArduinoSPI::transfer(uint8_t data) if (_is_sci) { _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; + _write_then_read(&_spi_sci_ctrl, &data, &rxbuf, 1, SPI_BIT_WIDTH_8_BITS); + for (auto const start = millis(); (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) { From 33d8348ab6797d3360c9c82ccd6c108b944d54a7 Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:56:41 +0200 Subject: [PATCH 09/15] - changes as requested for the pull-request --- libraries/SPI/SPI.cpp | 93 ++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 55 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 209e8d480..bd0b95cfa 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -164,25 +164,8 @@ void ArduinoSPI::begin() init_ok = false; } } - else - { -#if 0 -/* not using FSP for SPI anymore and no interrupts */ - SpiMasterIrqReq_t irq_req - { - .ctrl = &_spi_ctrl, - .cfg = &_spi_cfg, - .hw_channel = (uint8_t)_channel, - }; - init_ok &= IRQManager::getInstance().addPeripheral(IRQ_SPI_MASTER, &irq_req); - if (FSP_SUCCESS == _open(&_spi_ctrl, &_spi_cfg)) { - init_ok &= true; - } else { - init_ok = false; - } -#endif - } + /* not using FSP for SPI anymore and no interrupts */ _is_initialized = init_ok; } @@ -229,17 +212,17 @@ uint8_t ArduinoSPI::transfer(uint8_t data) uint16_t ArduinoSPI::transfer16(uint16_t data) { - union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t; - t.val = data; + union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t; + t.val = data; - if (_settings.getBitOrder() == LSBFIRST) { - t.lsb = transfer(t.lsb); - t.msb = transfer(t.msb); - } else { - t.msb = transfer(t.msb); - t.lsb = transfer(t.lsb); - } - return t.val; + if (_settings.getBitOrder() == LSBFIRST) { + t.lsb = transfer(t.lsb); + t.msb = transfer(t.msb); + } else { + t.msb = transfer(t.msb); + t.lsb = transfer(t.lsb); + } + return t.val; } void ArduinoSPI::transfer(void *buf, size_t count) @@ -263,8 +246,8 @@ void ArduinoSPI::transfer(void *buf, size_t count) { if (buf != NULL) { uint32_t *buffer32 = (uint32_t *) buf; - size_t ir = 0; - size_t it = 0; + size_t index_rx = 0; + size_t index_tx = 0; size_t const n32 = count / 4U; uint8_t const bytes_remaining = (uint8_t) (count & 3U); @@ -274,28 +257,28 @@ void ArduinoSPI::transfer(void *buf, size_t count) _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ - while ((it < 2U) && (it < n32)) { + while ((index_tx < 2U) && (index_tx < n32)) { if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { - _spi_ctrl.p_regs->SPDR = buffer32[it]; - it++; + _spi_ctrl.p_regs->SPDR = buffer32[index_tx]; + index_tx++; } } - while (it < n32) { + while (index_tx < n32) { if (_spi_ctrl.p_regs->SPSR_b.SPRF) { uint32_t tmp = _spi_ctrl.p_regs->SPDR; - _spi_ctrl.p_regs->SPDR = buffer32[it]; - buffer32[ir] = tmp; - ir++; - it++; + _spi_ctrl.p_regs->SPDR = buffer32[index_tx]; + buffer32[index_rx] = tmp; + index_rx++; + index_tx++; } } - while (ir < n32) { /* collect the last word received */ + while (index_rx < n32) { /* collect the last word received */ if (_spi_ctrl.p_regs->SPSR_b.SPRF) { uint32_t tmp = _spi_ctrl.p_regs->SPDR; - buffer32[ir] = tmp; - ir++; + buffer32[index_rx] = tmp; + index_rx++; } } @@ -306,7 +289,7 @@ void ArduinoSPI::transfer(void *buf, size_t count) } /* send the remaining bytes with 8-bit transfers */ - uint8_t *buffer = (uint8_t *) &buffer32[ir]; + uint8_t *buffer = (uint8_t *) &buffer32[index_rx]; for (uint8_t index = 0; index < bytes_remaining; index++) { _spi_ctrl.p_regs->SPDR_BY = buffer[index]; @@ -344,35 +327,35 @@ void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) const uint32_t* tx32 = (const uint32_t *) buf; uint32_t* rx32 = (uint32_t *) rxbuf; - size_t ir = 0; - size_t it = 0; + size_t index_rx = 0; + size_t index_tx = 0; - while ((it < 2U) && (it < n32)) { + while ((index_tx < 2U) && (index_tx < n32)) { if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { - _spi_ctrl.p_regs->SPDR = (buf != NULL) ? tx32[it] : 0xFFFFFFFF; - it++; + _spi_ctrl.p_regs->SPDR = (buf != NULL) ? tx32[index_tx] : 0xFFFFFFFF; + index_tx++; } } - while (it < n32) { + while (index_tx < n32) { if (_spi_ctrl.p_regs->SPSR_b.SPRF) { uint32_t tmp = _spi_ctrl.p_regs->SPDR; - _spi_ctrl.p_regs->SPDR = (buf != NULL) ? tx32[it] : 0xFFFFFFFF; + _spi_ctrl.p_regs->SPDR = (buf != NULL) ? tx32[index_tx] : 0xFFFFFFFF; if (rxbuf != NULL) { - rx32[ir] = tmp; + rx32[index_rx] = tmp; } - ir++; - it++; + index_rx++; + index_tx++; } } - while (ir < n32) { /* collect the last word received */ + while (index_rx < n32) { /* collect the last word received */ if (_spi_ctrl.p_regs->SPSR_b.SPRF) { uint32_t tmp = _spi_ctrl.p_regs->SPDR; if (rxbuf != NULL) { - rx32[ir] = tmp; + rx32[index_rx] = tmp; } - ir++; + index_rx++; } } From 32446a57f7849658231a25e072b9ec1bcb077f39 Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Wed, 12 Jul 2023 13:19:48 +0200 Subject: [PATCH 10/15] - removed transfer(buf, rxbuf, t count) to comply with the requirement that no new functions shall be added that are not defined in the standard Arduino API --- libraries/SPI/SPI.cpp | 81 ------------------------------------------- libraries/SPI/SPI.h | 1 - 2 files changed, 82 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index bd0b95cfa..1a25ab947 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -300,87 +300,6 @@ void ArduinoSPI::transfer(void *buf, size_t count) } } -void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count) -{ - if (_is_sci) { - _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; - - _write_then_read(&_spi_sci_ctrl, buf, rxbuf, count, SPI_BIT_WIDTH_8_BITS); - - for (auto const start = millis(); - (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) - { - __NOP(); - } - if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) - { - end(); - } - } - else { - size_t n32 = count / 4U; - if (n32 != 0U) { - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ - - const uint32_t* tx32 = (const uint32_t *) buf; - uint32_t* rx32 = (uint32_t *) rxbuf; - size_t index_rx = 0; - size_t index_tx = 0; - - while ((index_tx < 2U) && (index_tx < n32)) { - if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { - _spi_ctrl.p_regs->SPDR = (buf != NULL) ? tx32[index_tx] : 0xFFFFFFFF; - index_tx++; - } - } - - while (index_tx < n32) { - if (_spi_ctrl.p_regs->SPSR_b.SPRF) { - uint32_t tmp = _spi_ctrl.p_regs->SPDR; - _spi_ctrl.p_regs->SPDR = (buf != NULL) ? tx32[index_tx] : 0xFFFFFFFF; - if (rxbuf != NULL) { - rx32[index_rx] = tmp; - } - index_rx++; - index_tx++; - } - } - - while (index_rx < n32) { /* collect the last word received */ - if (_spi_ctrl.p_regs->SPSR_b.SPRF) { - uint32_t tmp = _spi_ctrl.p_regs->SPDR; - if (rxbuf != NULL) { - rx32[index_rx] = tmp; - } - index_rx++; - } - } - - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ - } - - /* send the remaining bytes with 8-bit transfers */ - if (count != (4U * n32)) { - uint8_t *rx = (uint8_t *) rxbuf; - const uint8_t* tx = (const uint8_t *) buf; - for (size_t i = 4U * n32; i < count; i++) { - _spi_ctrl.p_regs->SPDR_BY = (buf != NULL) ? tx[i] : 0xFF; - while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - uint8_t tmp = _spi_ctrl.p_regs->SPDR_BY; - if (rxbuf != NULL) { - rx[i] = tmp; - } - } - } - } -} - void ArduinoSPI::beginTransaction(arduino::SPISettings settings) { if (!_is_initialized) diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index de521306f..a76ce13f0 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -71,7 +71,6 @@ class ArduinoSPI : public SPIClass virtual uint8_t transfer(uint8_t data); virtual uint16_t transfer16(uint16_t data); virtual void transfer(void *buf, size_t count); - virtual void transfer(void *buf, void *rxbuf, size_t count); // Transaction Functions virtual void usingInterrupt(int __attribute__((unused)) interruptNumber) { } From 0cc34e0d87009cc772fc13c49953be49dda7a699 Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Wed, 12 Jul 2023 13:29:41 +0200 Subject: [PATCH 11/15] - moved the null-pointer check in transfer(buf, count) to start of the function --- libraries/SPI/SPI.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 1a25ab947..601de7ed3 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -227,24 +227,23 @@ uint16_t ArduinoSPI::transfer16(uint16_t data) void ArduinoSPI::transfer(void *buf, size_t count) { - if (_is_sci) { - _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; + if (buf != NULL) { + if (_is_sci) { + _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; - _write_then_read(&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS); + _write_then_read(&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS); - for (auto const start = millis(); - (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) - { - __NOP(); - } - if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) - { - end(); + for (auto const start = millis(); + (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) + { + __NOP(); + } + if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) + { + end(); + } } - } - else - { - if (buf != NULL) { + else { uint32_t *buffer32 = (uint32_t *) buf; size_t index_rx = 0; size_t index_tx = 0; From 65072f17d5263d50cd90d0909e769e9352df7cdf Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 13 Jul 2023 09:13:18 +0200 Subject: [PATCH 12/15] There's no longer a need to register the SPI callback, since we are not using interrupts for the SPI driver. --- libraries/SPI/SPI.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 601de7ed3..467d859c3 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -102,7 +102,7 @@ void ArduinoSPI::begin() _cb_event_idx = _channel; _spi_cfg.p_extend = &_spi_ext_cfg; - _spi_cfg.p_callback = spi_callback; + _spi_cfg.p_callback = nullptr; } /* SPI configuration for SPI HAL driver. */ @@ -547,19 +547,6 @@ std::tuple ArduinoSPI::toF * CALLBACKS FOR FSP FRAMEWORK **************************************************************************************/ -void spi_callback(spi_callback_args_t *p_args) -{ - if (SPI_EVENT_TRANSFER_COMPLETE == p_args->event) - { - _spi_cb_event[p_args->channel] = SPI_EVENT_TRANSFER_COMPLETE; - } - else - { - /* Updating the flag here to capture and handle all other error events */ - _spi_cb_event[p_args->channel] = SPI_EVENT_TRANSFER_ABORTED; - } -} - void sci_spi_callback(spi_callback_args_t *p_args) { int const spi_master_offset = SPI_MAX_SPI_CHANNELS; From 23b9a0018b93895d2626f853f019d4d8d84c7a1d Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Thu, 13 Jul 2023 09:31:44 +0200 Subject: [PATCH 13/15] - as requested in the pull-request, changed the test for nullpointer at top of tranfer(buf, count) to include a return statement --- libraries/SPI/SPI.cpp | 116 +++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 601de7ed3..7f5cf587d 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -227,74 +227,76 @@ uint16_t ArduinoSPI::transfer16(uint16_t data) void ArduinoSPI::transfer(void *buf, size_t count) { - if (buf != NULL) { - if (_is_sci) { - _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; + if (NULL == buf) { + return; + } + + if (_is_sci) { + _spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED; - _write_then_read(&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS); + _write_then_read(&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS); - for (auto const start = millis(); - (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) - { - __NOP(); - } - if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) - { - end(); - } + for (auto const start = millis(); + (SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); ) + { + __NOP(); } - else { - uint32_t *buffer32 = (uint32_t *) buf; - size_t index_rx = 0; - size_t index_tx = 0; - size_t const n32 = count / 4U; - uint8_t const bytes_remaining = (uint8_t) (count & 3U); - - if (n32 != 0U) { - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ - - while ((index_tx < 2U) && (index_tx < n32)) { - if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { - _spi_ctrl.p_regs->SPDR = buffer32[index_tx]; - index_tx++; - } + if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx]) + { + end(); + } + } + else { + uint32_t *buffer32 = (uint32_t *) buf; + size_t index_rx = 0; + size_t index_tx = 0; + size_t const n32 = count / 4U; + uint8_t const bytes_remaining = (uint8_t) (count & 3U); + + if (n32 != 0U) { + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + + while ((index_tx < 2U) && (index_tx < n32)) { + if (_spi_ctrl.p_regs->SPSR_b.SPTEF) { + _spi_ctrl.p_regs->SPDR = buffer32[index_tx]; + index_tx++; } + } - while (index_tx < n32) { - if (_spi_ctrl.p_regs->SPSR_b.SPRF) { - uint32_t tmp = _spi_ctrl.p_regs->SPDR; - _spi_ctrl.p_regs->SPDR = buffer32[index_tx]; - buffer32[index_rx] = tmp; - index_rx++; - index_tx++; - } + while (index_tx < n32) { + if (_spi_ctrl.p_regs->SPSR_b.SPRF) { + uint32_t tmp = _spi_ctrl.p_regs->SPDR; + _spi_ctrl.p_regs->SPDR = buffer32[index_tx]; + buffer32[index_rx] = tmp; + index_rx++; + index_tx++; } + } - while (index_rx < n32) { /* collect the last word received */ - if (_spi_ctrl.p_regs->SPSR_b.SPRF) { - uint32_t tmp = _spi_ctrl.p_regs->SPDR; - buffer32[index_rx] = tmp; - index_rx++; - } + while (index_rx < n32) { /* collect the last word received */ + if (_spi_ctrl.p_regs->SPSR_b.SPRF) { + uint32_t tmp = _spi_ctrl.p_regs->SPDR; + buffer32[index_rx] = tmp; + index_rx++; } - - _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ - _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ - _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ - _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ } - /* send the remaining bytes with 8-bit transfers */ - uint8_t *buffer = (uint8_t *) &buffer32[index_rx]; + _spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */ + _spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */ + _spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */ + _spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */ + } - for (uint8_t index = 0; index < bytes_remaining; index++) { - _spi_ctrl.p_regs->SPDR_BY = buffer[index]; - while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {} - buffer[index] = _spi_ctrl.p_regs->SPDR_BY; - } + /* send the remaining bytes with 8-bit transfers */ + uint8_t *buffer = (uint8_t *) &buffer32[index_rx]; + + for (uint8_t index = 0; index < bytes_remaining; index++) { + _spi_ctrl.p_regs->SPDR_BY = buffer[index]; + while (0U == _spi_ctrl.p_regs->SPSR_b.SPRF) {} + buffer[index] = _spi_ctrl.p_regs->SPDR_BY; } } } From 0d5733f89de44c23545c2ffe64d7af71c3f9c66e Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 13 Jul 2023 09:40:03 +0200 Subject: [PATCH 14/15] Also remove forward declaration of FSP callback "spi_callback" which is no longer needed. --- libraries/SPI/SPI.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index a76ce13f0..ffab671e3 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -34,7 +34,6 @@ **************************************************************************************/ extern "C" { - void spi_callback(spi_callback_args_t *p_args); void sci_spi_callback(spi_callback_args_t *p_args); } From 1cb311192e5dd25ce3c9e52272b95bc7e2d0c622 Mon Sep 17 00:00:00 2001 From: RudolphRiedel <31180093+RudolphRiedel@users.noreply.github.com> Date: Thu, 13 Jul 2023 22:41:36 +0200 Subject: [PATCH 15/15] - fix: SPCR2.SCKASE needs to be set to protect the SPI from delays in the communication by interrupts from other units, thanks for finding the issue to @greiman ! --- libraries/SPI/SPI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index b1a892efd..e4d5b40d4 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -459,7 +459,7 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings) _spi_ctrl.p_regs->SPND = 0; - _spi_ctrl.p_regs->SPCR2 = 0; + _spi_ctrl.p_regs->SPCR2 = R_SPI0_SPCR2_SCKASE_Msk; /* SPMS = 0 -> SPI operation, TXMD = 0 -> full-duplex, SPxIE = 0 -> no interrupts */ if (SPI_MODE_MASTER == _spi_cfg.operating_mode) {