Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp')
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp74
1 files changed, 38 insertions, 36 deletions
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp
index 70ebf1d4..e6c9d3ce 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp
@@ -231,11 +231,7 @@ namespace WizSpi
ConfigurePin(g_APinDescription[APIN_SPI_SCK]);
ConfigurePin(g_APinDescription[APIN_SPI_MOSI]);
ConfigurePin(g_APinDescription[APIN_SPI_MISO]);
-#if 1
- pinMode(APIN_SPI_SS0, OUTPUT_HIGH); // use manual SS control for now
-#else
- ConfigurePin(g_APinDescription[APIN_SPI_SS0]);
-#endif
+ pinMode(APIN_SPI_SS0, OUTPUT_HIGH); // use manual SS control
pmc_enable_periph_clk(ID_SPI);
@@ -279,7 +275,10 @@ namespace WizSpi
#endif
}
- // Wait for transmitter ready returning true if timed out
+// The remaining functions are speed-critical, so use full optimisation
+#pragma GCC optimize ("O3")
+
+ // Wait for transmit buffer empty, returning true if timed out
static inline bool waitForTxReady()
{
uint32_t timeout = SPI_TIMEOUT;
@@ -293,7 +292,7 @@ namespace WizSpi
return false;
}
- // Wait for transmitter empty returning true if timed out
+ // Wait for transmitter empty, returning true if timed out
static inline bool waitForTxEmpty()
{
uint32_t timeout = SPI_TIMEOUT;
@@ -307,7 +306,7 @@ namespace WizSpi
return false;
}
- // Wait for receive data available returning true if timed out
+ // Wait for receive data available, returning true if timed out
static inline bool waitForRxReady()
{
uint32_t timeout = SPI_TIMEOUT;
@@ -369,7 +368,7 @@ namespace WizSpi
{
(void)SPI->SPI_RDR; // clear previous data
}
- SPI->SPI_TDR = 0x000000FF | SPI_TDR_LASTXFER;
+ SPI->SPI_TDR = 0x000000FF;
if (!waitForRxReady())
{
return (uint8_t)SPI->SPI_RDR;
@@ -381,49 +380,59 @@ namespace WizSpi
// Write a single byte. Called after sending the address.
void WriteByte(uint8_t b)
{
- const uint32_t dOut = b | SPI_TDR_LASTXFER;
+ const uint32_t dOut = b;
if (!waitForTxReady())
{
SPI->SPI_TDR = dOut;
}
}
+ // Read some data
spi_status_t ReadBurst(uint8_t* rx_data, size_t len)
{
- if (waitForTxEmpty())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- while ((SPI->SPI_SR & SPI_SR_RDRF) != 0)
- {
- (void)SPI->SPI_RDR; // clear previous data
- }
-
- for (size_t i = 0; i < len; ++i)
+ if (len != 0)
{
- const uint32_t dOut = ((i + 1) == len) ? 0x000000FF | SPI_TDR_LASTXFER : 0x000000FF;
- if (waitForTxReady())
+ if (waitForTxEmpty())
{
return SPI_ERROR_TIMEOUT;
}
- // Write to transmit register
- SPI->SPI_TDR = dOut;
+ while ((SPI->SPI_SR & SPI_SR_RDRF) != 0)
+ {
+ (void)SPI->SPI_RDR; // clear previous data
+ }
+
+ const uint32_t dOut = 0x000000FF;
+ SPI->SPI_TDR = dOut; // send first byte
+ while (--len != 0)
+ {
+ // Wait for receive data available and transmit buffer empty
+ uint32_t timeout = SPI_TIMEOUT + 1;
+ do
+ {
+ if (--timeout == 0)
+ {
+ return SPI_ERROR_TIMEOUT;
+ }
+ }
+ while ((SPI->SPI_SR & (SPI_SR_RDRF | SPI_SR_TDRE)) != (SPI_SR_RDRF | SPI_SR_TDRE));
+
+ const uint32_t din = SPI->SPI_RDR; // get data from receive register
+ SPI->SPI_TDR = dOut; // write to transmit register immediately
+ *rx_data++ = (uint8_t)din;
+ }
- // Wait for receive register
if (waitForRxReady())
{
return SPI_ERROR_TIMEOUT;
}
- // Get data from receive register
- *rx_data++ = (uint8_t)SPI->SPI_RDR;
+ *rx_data++ = (uint8_t)SPI->SPI_RDR; // Get last byte from receive register
}
-
return SPI_OK;
}
+ // Send some data
spi_status_t SendBurst(const uint8_t* tx_data, size_t len)
{
for (uint32_t i = 0; i < len; ++i)
@@ -441,13 +450,6 @@ namespace WizSpi
// Write to transmit register
SPI->SPI_TDR = dOut;
- // Wait for receive register
- if (waitForRxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- // Get data from receive register
(void)SPI->SPI_RDR;
}