From 8f5edd91b82b17dced61af6d5979675122742a48 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Mon, 8 Aug 2022 13:35:41 +0100 Subject: SBC SPI interface now uses transfer complete interrupt --- src/Config/Pins_Duet3Mini.h | 4 ++-- src/Networking/ESP8266WiFi/WiFiInterface.cpp | 2 +- src/SBC/DataTransfer.cpp | 28 ++++------------------------ 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/Config/Pins_Duet3Mini.h b/src/Config/Pins_Duet3Mini.h index f40ed90e..3ca4186b 100644 --- a/src/Config/Pins_Duet3Mini.h +++ b/src/Config/Pins_Duet3Mini.h @@ -317,8 +317,8 @@ constexpr Pin SbcSSPin = PortAPin(6); constexpr Pin SbcTfrReadyPin = PortAPin(3); constexpr Pin SbcSpiSercomPins[] = { PortAPin(4), PortAPin(5), PortAPin(6), PortAPin(7) }; constexpr GpioPinFunction SbcSpiSercomPinsMode = GpioPinFunction::D; -constexpr IRQn SbcSpiSercomIRQn = SERCOM0_3_IRQn; // this is the SS Low interrupt, the only one we use -#define SBC_SPI_HANDLER SERCOM0_3_Handler +constexpr IRQn SbcSpiSercomIRQn = SERCOM0_1_IRQn; // this is the transfer complete interrupt, the only one we use +#define SBC_SPI_HANDLER SERCOM0_1_Handler // CAN constexpr unsigned int CanDeviceNumber = 1; // we use CAN1 diff --git a/src/Networking/ESP8266WiFi/WiFiInterface.cpp b/src/Networking/ESP8266WiFi/WiFiInterface.cpp index b4afe547..50c50f62 100644 --- a/src/Networking/ESP8266WiFi/WiFiInterface.cpp +++ b/src/Networking/ESP8266WiFi/WiFiInterface.cpp @@ -1969,7 +1969,7 @@ void WiFiInterface::SpiInterrupt() noexcept const uint8_t status = WiFiSpiSercom->SPI.INTFLAG.reg; if ((status & SERCOM_SPI_INTFLAG_TXC) != 0) { - WiFiSpiSercom->SPI.INTENCLR.reg = SERCOM_SPI_INTENSET_TXC; // disable the interrupt + WiFiSpiSercom->SPI.INTENCLR.reg = SERCOM_SPI_INTENCLR_TXC; // disable the interrupt WiFiSpiSercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC; // clear the status #else const uint32_t status = ESP_SPI->SPI_SR; // read status and clear interrupt diff --git a/src/SBC/DataTransfer.cpp b/src/SBC/DataTransfer.cpp index fe01c60d..4505f320 100644 --- a/src/SBC/DataTransfer.cpp +++ b/src/SBC/DataTransfer.cpp @@ -90,9 +90,6 @@ static xdmac_channel_config_t xdmac_tx_cfg, xdmac_rx_cfg; #endif volatile bool dataReceived = false; // warning: on the SAME5x this just means the transfer has started, not necessarily that it has ended! -#if SAME5x -uint32_t transferStartTime = 0; -#endif volatile bool transferReadyHigh = false; volatile unsigned int spiTxUnderruns = 0, spiRxOverruns = 0; @@ -321,7 +318,7 @@ pre(bytesToTransfer <= inBuffer.limit; bytesToTransfer <= outBuffer.limit) // Enable SPI and notify the SBC we are ready #if SAME5x SbcSpiSercom->SPI.INTFLAG.reg = 0xFF; // clear any pending interrupts - SbcSpiSercom->SPI.INTENSET.reg = SERCOM_SPI_INTENSET_SSL; // enable the start of transfer (SS low) interrupt + SbcSpiSercom->SPI.INTENSET.reg = SERCOM_SPI_INTENSET_TXC; // enable the end of transfer interrupt SbcSpiSercom->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE; while (SbcSpiSercom->SPI.SYNCBUSY.reg & (SERCOM_SPI_SYNCBUSY_SWRST | SERCOM_SPI_SYNCBUSY_ENABLE)) { }; #else @@ -336,9 +333,6 @@ pre(bytesToTransfer <= inBuffer.limit; bytesToTransfer <= outBuffer.limit) NVIC_EnableIRQ(SBC_SPI_IRQn); // Begin transfer -#if SAME5x - transferStartTime = 0; -#endif transferReadyHigh = !transferReadyHigh; digitalWrite(SbcTfrReadyPin, transferReadyHigh); } @@ -351,13 +345,11 @@ pre(bytesToTransfer <= inBuffer.limit; bytesToTransfer <= outBuffer.limit) extern "C" void SBC_SPI_HANDLER() noexcept { #if SAME5x - // On the SAM5x we can't get an end-of-transfer interrupt, only a start-of-transfer interrupt. - // So we can't disable SPI or DMA in this ISR. const uint8_t status = SbcSpiSercom->SPI.INTFLAG.reg; - if ((status & SERCOM_SPI_INTENSET_SSL) != 0) + if ((status & SERCOM_SPI_INTFLAG_TXC) != 0) { - SbcSpiSercom->SPI.INTENCLR.reg = SERCOM_SPI_INTENSET_SSL; // disable the interrupt - SbcSpiSercom->SPI.INTFLAG.reg = SERCOM_SPI_INTENSET_SSL; // clear the status + SbcSpiSercom->SPI.INTENCLR.reg = SERCOM_SPI_INTENCLR_TXC; // disable the interrupt + SbcSpiSercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC; // clear the status // Wake up the SBC task dataReceived = true; @@ -767,18 +759,6 @@ TransferState DataTransfer::DoTransfer() noexcept if (dataReceived) { #if SAME5x - // Unfortunately the SAME5x doesn't have an end-of-transfer interrupt, but SPI transfers typically don't take long - if (!digitalRead(SbcSSPin)) // transfer is complete if SS is high - { - if (transferStartTime == 0) - { - transferStartTime = millis(); - return TransferState::finishingTransfer; - } - return (millis() - transferStartTime > SpiMaxTransferTime) ? TransferState::connectionTimeout : TransferState::finishingTransfer; - } - transferStartTime = 0; - if (SbcSpiSercom->SPI.STATUS.bit.BUFOVF) { ++spiRxOverruns; -- cgit v1.2.3