From d1cd226e4557b42a44aa68934eee22156bb5170f Mon Sep 17 00:00:00 2001 From: David Crocker Date: Fri, 20 May 2022 13:49:39 +0100 Subject: Corrected drivers enable pin for v0.3 FMDC board --- src/Config/Pins_FMDC.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Config/Pins_FMDC.h b/src/Config/Pins_FMDC.h index 10bdc652..982569a3 100644 --- a/src/Config/Pins_FMDC.h +++ b/src/Config/Pins_FMDC.h @@ -113,7 +113,6 @@ constexpr Pin UsbVBusPin = PortBPin(6); // Pin used to monitor VBUS on USB po // The numbers of entries in each array must correspond with the values of DRIVES, AXES, or HEATERS. Set values to NoPin to flag unavailability. // Drivers -constexpr Pin GlobalTmc22xxEnablePin = PortCPin(28); // The pin that drives ENN of all drivers PortGroup * const StepPio = &(PORT->Group[2]); // The PIO that all the step pins are on (port C) constexpr Pin STEP_PINS[NumDirectDrivers] = { PortCPin(26), PortCPin(25), PortCPin(24), PortCPin(20) }; @@ -121,8 +120,10 @@ constexpr Pin DIRECTION_PINS[NumDirectDrivers] = { PortBPin(3), PortAPin(27), Po #if defined(FMDC_V03) constexpr Pin DriverDiagPins[NumDirectDrivers] = { PortCPin(28), PortBPin(8), PortCPin(27), PortCPin(21) }; +constexpr Pin GlobalTmc22xxEnablePin = PortBPin(21); // The pin that drives ENN of all drivers #elif defined(FMDC_V02) constexpr Pin DriverDiagPins[NumDirectDrivers] = { PortAPin(10), PortBPin(8), PortCPin(27), PortCPin(21) }; +constexpr Pin GlobalTmc22xxEnablePin = PortCPin(28); // The pin that drives ENN of all drivers #endif // CCL inputs that the DIAG inputs use. Bits 0-1 are the CCL LUT number. Bits 8-19 are the value to OR in to the control register for that LUT. -- cgit v1.2.3 From 71004ac8c9e457afdd209c22813438be0c46b044 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Sat, 21 May 2022 11:43:31 +0100 Subject: Removed some unecessary code --- src/ObjectModel/ObjectModel.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp index 215c7414..5bffcd3c 100644 --- a/src/ObjectModel/ObjectModel.cpp +++ b/src/ObjectModel/ObjectModel.cpp @@ -1072,10 +1072,6 @@ decrease(strlen(idString)) // recursion variant throw context.ConstructParseException("array index out of bounds"); } - if (context.WantExists()) - { - return ExpressionValue(true); - } return ExpressionValue((int32_t)(Bitmap::MakeFromRaw(val.uVal).GetSetBitNumber(context.GetLastIndex()))); } } @@ -1121,11 +1117,6 @@ decrease(strlen(idString)) // recursion variant throw context.ConstructParseException("array index out of bounds"); } - if (context.WantExists()) - { - return ExpressionValue(true); - } - return ExpressionValue((int32_t)(Bitmap::MakeFromRaw(val.Get56BitValue()).GetSetBitNumber(context.GetLastIndex()))); } } -- cgit v1.2.3 From 780a8c210a69de6ab722171b4ab23da58dbdaa2e Mon Sep 17 00:00:00 2001 From: David Crocker Date: Sat, 21 May 2022 11:45:41 +0100 Subject: Code corrections and tidy up of OutputBuffer class --- src/Platform/OutputMemory.cpp | 62 ++++++++++++++++++++----------------------- src/Platform/OutputMemory.h | 1 - 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/Platform/OutputMemory.cpp b/src/Platform/OutputMemory.cpp index b2ac7433..65ab215c 100644 --- a/src/Platform/OutputMemory.cpp +++ b/src/Platform/OutputMemory.cpp @@ -22,26 +22,29 @@ void OutputBuffer::Append(OutputBuffer *other) noexcept if (other != nullptr) { last->next = other; - last = other->last; + OutputBuffer * const newLast = other->last; if (other->hadOverflow) { hadOverflow = true; } - for (OutputBuffer *item = Next(); item != other; item = item->Next()) + OutputBuffer *item = this; + do { - item->last = last; + item->last = newLast; + item = item->Next(); } + while (item != other); } } void OutputBuffer::IncreaseReferences(size_t refs) noexcept { - if (refs > 0) + if (refs != 0) { TaskCriticalSectionLocker lock; - for(OutputBuffer *item = this; item != nullptr; item = item->Next()) + for (OutputBuffer *item = this; item != nullptr; item = item->Next()) { item->references += refs; item->isReferenced = true; @@ -59,20 +62,6 @@ size_t OutputBuffer::Length() const noexcept return totalLength; } -char &OutputBuffer::operator[](size_t index) noexcept -{ - // Get the right buffer to access - OutputBuffer *itemToIndex = this; - while (index >= itemToIndex->DataLength()) - { - index -= itemToIndex->DataLength(); - itemToIndex = itemToIndex->Next(); - } - - // Return the char reference - return itemToIndex->data[index]; -} - char OutputBuffer::operator[](size_t index) const noexcept { // Get the right buffer to access @@ -89,7 +78,7 @@ char OutputBuffer::operator[](size_t index) const noexcept const char *OutputBuffer::Read(size_t len) noexcept { - size_t offset = bytesRead; + const size_t offset = bytesRead; bytesRead += len; return data + offset; } @@ -120,7 +109,7 @@ size_t OutputBuffer::printf(const char *_ecv_array fmt, ...) noexcept { va_list vargs; va_start(vargs, fmt); - size_t ret = vprintf(fmt, vargs); + const size_t ret = vprintf(fmt, vargs); va_end(vargs); return ret; } @@ -138,7 +127,7 @@ size_t OutputBuffer::catf(const char *_ecv_array fmt, ...) noexcept { va_list vargs; va_start(vargs, fmt); - size_t ret = vcatf(fmt, vargs); + const size_t ret = vcatf(fmt, vargs); va_end(vargs); return ret; } @@ -146,9 +135,13 @@ size_t OutputBuffer::catf(const char *_ecv_array fmt, ...) noexcept size_t OutputBuffer::lcatf(const char *_ecv_array fmt, ...) noexcept { size_t extra = 0; - if (Length() != 0 && operator[](Length() - 1) != '\n') + if (last->dataLength != 0 && last->data[last->dataLength - 1] != '\n') { extra = cat('\n'); + if (extra == 0) + { + return 0; + } } va_list vargs; @@ -235,8 +228,7 @@ size_t OutputBuffer::cat(const char *_ecv_array src, size_t len) noexcept } nextBuffer->references = references; last->next = nextBuffer; - last = nextBuffer->last; - for (OutputBuffer *item = Next(); item != nextBuffer; item = item->Next()) + for (OutputBuffer *item = this; item != nextBuffer; item = item->Next()) { item->last = last; } @@ -251,11 +243,17 @@ size_t OutputBuffer::cat(const char *_ecv_array src, size_t len) noexcept size_t OutputBuffer::lcat(const char *_ecv_array src, size_t len) noexcept { - if (Length() != 0) + size_t extra = 0; + if (last->dataLength != 0 && last->data[last->dataLength - 1] != '\n') { - cat('\n'); + extra = cat('\n'); + if (extra == 0) + { + return 0; + } } - return cat(src, len); + + return cat(src, len) + extra; } size_t OutputBuffer::cat(StringRef &str) noexcept @@ -294,13 +292,11 @@ size_t OutputBuffer::EncodeChar(char c) noexcept if (esc != 0) { - cat('\\'); - cat(esc); - return 2; + const size_t written = cat('\\'); + return (written == 0) ? written : written + cat(esc); } - cat(c); - return 1; + return cat(c); } size_t OutputBuffer::EncodeReply(OutputBuffer *src) noexcept diff --git a/src/Platform/OutputMemory.h b/src/Platform/OutputMemory.h index c8a3f59b..0ef8cd53 100644 --- a/src/Platform/OutputMemory.h +++ b/src/Platform/OutputMemory.h @@ -35,7 +35,6 @@ public: size_t DataLength() const noexcept { return dataLength; } // How many bytes have been written to this instance? size_t Length() const noexcept; // How many bytes have been written to the whole chain? - char& operator[](size_t index) noexcept; char operator[](size_t index) const noexcept; const char *_ecv_array Read(size_t len) noexcept; void Taken(size_t len) noexcept { bytesRead += len; } -- cgit v1.2.3 From 342f74c437afcb9434fc5f824ad9b8810b4fadcd Mon Sep 17 00:00:00 2001 From: David Crocker Date: Sat, 21 May 2022 13:25:50 +0100 Subject: Correction to previous commit --- src/Platform/OutputMemory.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Platform/OutputMemory.cpp b/src/Platform/OutputMemory.cpp index 65ab215c..14a1e368 100644 --- a/src/Platform/OutputMemory.cpp +++ b/src/Platform/OutputMemory.cpp @@ -228,10 +228,12 @@ size_t OutputBuffer::cat(const char *_ecv_array src, size_t len) noexcept } nextBuffer->references = references; last->next = nextBuffer; - for (OutputBuffer *item = this; item != nextBuffer; item = item->Next()) + OutputBuffer *item = this; + do { - item->last = last; - } + item->last = nextBuffer; + item = item->Next(); + } while (item != nextBuffer); } const size_t copyLength = min(len - copied, OUTPUT_BUFFER_SIZE - last->dataLength); memcpy(last->data + last->dataLength, src + copied, copyLength); -- cgit v1.2.3 From e97a816c0183982c26a95b34821f64f14468455e Mon Sep 17 00:00:00 2001 From: David Crocker Date: Sat, 21 May 2022 13:26:43 +0100 Subject: Fixed possible interation between DMA and cache in W5500 network code --- .../W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp | 22 +++++++++++++--------- src/Version.h | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp b/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp index 525767d5..3c1b79db 100644 --- a/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp +++ b/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp @@ -7,6 +7,7 @@ #include "WizSpi.h" #include +#include // Define exactly one of the following as 1, the other as zero #define USE_PDC 1 // use peripheral DMA controller @@ -32,26 +33,25 @@ const unsigned int SpiPeripheralChannelId = 0; // we use NPCS0 as the slave se // Functions called by the W5500 module to transfer data to/from the W5500 via SPI #if USE_PDC -static Pdc *spi_pdc; static inline void spi_rx_dma_enable() noexcept { - pdc_enable_transfer(spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); // we have to transmit in order to receive + pdc_enable_transfer(spi_get_pdc_base(W5500_SPI), PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); // we have to transmit in order to receive } static inline void spi_tx_dma_enable() noexcept { - pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN); + pdc_enable_transfer(spi_get_pdc_base(W5500_SPI), PERIPH_PTCR_TXTEN); } static inline void spi_rx_dma_disable() noexcept { - pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); // we have to transmit in order to receive + pdc_disable_transfer(spi_get_pdc_base(W5500_SPI), PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); // we have to transmit in order to receive } static inline void spi_tx_dma_disable() noexcept { - pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS); + pdc_disable_transfer(spi_get_pdc_base(W5500_SPI), PERIPH_PTCR_TXTDIS); } static inline bool spi_dma_check_rx_complete() noexcept @@ -69,7 +69,7 @@ static void spi_tx_dma_setup(const uint8_t *buf, uint32_t length) noexcept pdc_packet_t pdc_spi_packet; pdc_spi_packet.ul_addr = reinterpret_cast(buf); pdc_spi_packet.ul_size = length; - pdc_tx_init(spi_pdc, &pdc_spi_packet, nullptr); + pdc_tx_init(spi_get_pdc_base(W5500_SPI), &pdc_spi_packet, nullptr); } static void spi_rx_dma_setup(uint8_t *buf, uint32_t length) noexcept @@ -77,8 +77,8 @@ static void spi_rx_dma_setup(uint8_t *buf, uint32_t length) noexcept pdc_packet_t pdc_spi_packet; pdc_spi_packet.ul_addr = reinterpret_cast(buf); pdc_spi_packet.ul_size = length; - pdc_rx_init(spi_pdc, &pdc_spi_packet, nullptr); - pdc_tx_init(spi_pdc, &pdc_spi_packet, nullptr); // we have to transmit in order to receive + pdc_rx_init(spi_get_pdc_base(W5500_SPI), &pdc_spi_packet, nullptr); + pdc_tx_init(spi_get_pdc_base(W5500_SPI), &pdc_spi_packet, nullptr); // we have to transmit in order to receive } #endif @@ -170,7 +170,6 @@ namespace WizSpi void Init() noexcept { #if USE_PDC - spi_pdc = spi_get_pdc_base(W5500_SPI); // The PDCs are masters 2 and 3 and the SRAM is slave 0. Give the receive PDCs the highest priority. matrix_set_master_burst_type(0, MATRIX_ULBT_8_BEAT_BURST); matrix_set_slave_default_master_type(0, MATRIX_DEFMSTR_LAST_DEFAULT_MASTER); @@ -371,7 +370,11 @@ namespace WizSpi { --timeout; } + // The SPI peripheral signals transfer complete at the start of transferring the last byte. If we disable the DMA too soon, there might be a chance + // that the transfer does not complete. Therefore, delay disabling DMA until we have invalidated the cache, which takes some time. + Cache::InvalidateAfterDMAReceive(rx_data, len); spi_rx_dma_disable(); + if (timeout == 0) { return SPI_ERROR_TIMEOUT; @@ -414,6 +417,7 @@ namespace WizSpi if (len != 0) { #if USE_PDC + Cache::FlushBeforeDMASend(tx_data, len); spi_tx_dma_setup(tx_data, len); spi_tx_dma_enable(); uint32_t timeout = SPI_TIMEOUT; diff --git a/src/Version.h b/src/Version.h index 8a6cdf11..f2a71146 100644 --- a/src/Version.h +++ b/src/Version.h @@ -10,7 +10,7 @@ #ifndef VERSION // Note: the complete VERSION string must be in standard version number format and must not contain spaces! This is so that DWC can parse it. -# define MAIN_VERSION "3.4.1rc1" +# define MAIN_VERSION "3.4.1rc1+1" # ifdef USE_CAN0 # define VERSION_SUFFIX "(CAN0)" # else -- cgit v1.2.3 From 386477f433041d9a74143d84605de24aacfd0838 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Mon, 23 May 2022 07:29:51 +0100 Subject: Added conditional code to save files with upload errors --- src/Networking/UploadingNetworkResponder.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Networking/UploadingNetworkResponder.cpp b/src/Networking/UploadingNetworkResponder.cpp index 5b4245de..6cac6b39 100644 --- a/src/Networking/UploadingNetworkResponder.cpp +++ b/src/Networking/UploadingNetworkResponder.cpp @@ -111,7 +111,14 @@ void UploadingNetworkResponder::FinishUpload(uint32_t fileLength, time_t fileLas const char *uploadFilename = filenameBeingProcessed.c_str(); if (uploadError) { +#if 0 // Temporary code to save files with upload errors and report successful uploads + String newName; + MassStorage::CombineName(newName.GetRef(), Platform::GetGCodeDir(), "uploadError_"); + newName.catf("%04u", (unsigned int)(millis() % 10000)); + MassStorage::Rename(uploadFilename, newName.c_str(), true, true); +#else MassStorage::Delete(uploadFilename, true); +#endif } else { @@ -126,6 +133,9 @@ void UploadingNetworkResponder::FinishUpload(uint32_t fileLength, time_t fileLas // Update the file timestamp if it was specified (void)MassStorage::SetLastModifiedTime(origFilename.c_str(), fileLastModified); } +#if 0 // Temporary code to save files with upload errors and report successful uploads + GetPlatform().Message(GenericMessage, "Successful upload\n"); +#endif } filenameBeingProcessed.Clear(); } -- cgit v1.2.3 From 93c65793846c22a204989d9acc64483b462e9a20 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Mon, 23 May 2022 19:40:12 +0100 Subject: Added definitions of potential Ethernet DMA channels to Pins_DuetNG.h --- src/Config/Pins_DuetNG.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Config/Pins_DuetNG.h b/src/Config/Pins_DuetNG.h index c4339c34..09e53fe6 100644 --- a/src/Config/Pins_DuetNG.h +++ b/src/Config/Pins_DuetNG.h @@ -564,6 +564,12 @@ constexpr DmaChannel DmacChanWiFiTx = 1; constexpr DmaChannel DmacChanWiFiRx = 2; #endif +#if HAS_W5500_NETWORKING +// We can use the same DMA channels as for WiFi because only one of them will be present +constexpr DmaChannel DmacChanW5500Tx = 1; +constexpr DmaChannel DmacChanW5500Rx = 2; +#endif + namespace StepPins { // *** These next three functions must use the same bit assignments in the drivers bitmap *** -- cgit v1.2.3 From 583564eec77039c3943cdeef029eed319b96a0ef Mon Sep 17 00:00:00 2001 From: David Crocker Date: Mon, 23 May 2022 19:43:47 +0100 Subject: Simplified code to save flash memory in Duet 2 build --- src/GCodes/GCodes2.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 3a9406b5..0c923c73 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -2533,19 +2533,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx bool dummy = false; String title; - gb.TryGetQuotedString('R', title.GetRef(), dummy); + (void)gb.TryGetQuotedString('R', title.GetRef(), dummy); - int32_t sParam = 1; - gb.TryGetIValue('S', sParam, dummy); - if (sParam < 0 || sParam > 3) - { - reply.copy("Invalid message box mode"); - result = GCodeResult::error; - break; - } + uint32_t sParam = 1; + (void)gb.TryGetLimitedUIValue('S', sParam, dummy, 4); float tParam; - if (sParam == 0 || sParam == 1) + if (sParam <= 1) { tParam = DefaultMessageTimeout; gb.TryGetFValue('T', tParam, dummy); @@ -2572,7 +2566,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx } // Don't lock the movement system, because if we do then only the channel that issues the M291 can move the axes - if (sParam == 2 || sParam == 3) + if (sParam >= 2) { #if HAS_SBC_INTERFACE if (reprap.UsingSbcInterface()) @@ -2675,7 +2669,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx break; case 305: // Set/report specific heater parameters - reply.copy("M305 has been replaced by M308 and M950 in RepRapFirmware 3"); + reply.copy("M305 has been replaced by M308 and M950"); result = GCodeResult::error; break; -- cgit v1.2.3 From 22629149b8bbbeb41362b420c08e161d9f5d24cf Mon Sep 17 00:00:00 2001 From: David Crocker Date: Mon, 23 May 2022 20:30:15 +0100 Subject: Reduced W5500 SPI frequency to 25MHz to avoid upload errors Also made some corrections to the option to use the DMAC instead of the PDC, but using the DMAC still doesn't work, --- .../W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp | 84 +++++++++++----------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp b/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp index 3c1b79db..b4cc0e97 100644 --- a/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp +++ b/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp @@ -27,7 +27,8 @@ // SPI data rate. I tried 60MHz and we got some data corruption when uploading files, so I reduced it to 40MHz. // 2018-01-11: We have now received one report of data corruption at 40MHz, so reduced this to 30MHz -const uint32_t SpiClockFrequency = 30000000; +// 2022-05-23: Very occasionally we get data corruption when uploading files, with a character being replaced by the following character. So reduced to 25MHz. +const uint32_t SpiClockFrequency = 25000000; const unsigned int SpiPeripheralChannelId = 0; // we use NPCS0 as the slave select signal // Functions called by the W5500 module to transfer data to/from the W5500 via SPI @@ -85,71 +86,73 @@ static void spi_rx_dma_setup(uint8_t *buf, uint32_t length) noexcept #if USE_DMAC -// Our choice of DMA channels to use -const uint32_t CONF_SPI_DMAC_TX_CH = 1; -const uint32_t CONF_SPI_DMAC_RX_CH = 2; - -// Hardware IDs of the SPI transmit and receive DMA interfaces. See atsam datasheet. -const uint32_t DMA_HW_ID_SPI_TX = 1; -const uint32_t DMA_HW_ID_SPI_RX = 2; - static inline void spi_rx_dma_enable() noexcept { - dmac_channel_enable(DMAC, CONF_SPI_DMAC_RX_CH); + dmac_channel_enable(DMAC, DmacChanW5500Rx); + dmac_channel_enable(DMAC, DmacChanW5500Tx); } static inline void spi_tx_dma_enable() noexcept { - dmac_channel_enable(DMAC, CONF_SPI_DMAC_TX_CH); + dmac_channel_enable(DMAC, DmacChanW5500Tx); } static inline void spi_rx_dma_disable() noexcept { - dmac_channel_disable(DMAC, CONF_SPI_DMAC_RX_CH); + dmac_channel_disable(DMAC, DmacChanW5500Tx); + dmac_channel_disable(DMAC, DmacChanW5500Rx); } static inline void spi_tx_dma_disable() noexcept { - dmac_channel_disable(DMAC, CONF_SPI_DMAC_TX_CH); + dmac_channel_disable(DMAC, DmacChanW5500Tx); } static bool spi_dma_check_rx_complete() noexcept { uint32_t status = DMAC->DMAC_CHSR; - if ( ((status & (DMAC_CHSR_ENA0 << CONF_SPI_DMAC_RX_CH)) == 0) // controller is not enabled, perhaps because it finished a full buffer transfer - || ((status & (DMAC_CHSR_EMPT0 << CONF_SPI_DMAC_RX_CH)) != 0) // controller is enabled, probably suspended, and the FIFO is empty + if ( ((status & (DMAC_CHSR_ENA0 << DmacChanW5500Rx)) == 0) // controller is not enabled, perhaps because it finished a full buffer transfer + || ((status & (DMAC_CHSR_EMPT0 << DmacChanW5500Rx)) != 0) // controller is enabled, probably suspended, and the FIFO is empty ) { // Disable the channel. // We also need to set the resume bit, otherwise it remains suspended when we re-enable it. - DMAC->DMAC_CHDR = (DMAC_CHDR_DIS0 << CONF_SPI_DMAC_RX_CH) | (DMAC_CHDR_RES0 << CONF_SPI_DMAC_RX_CH); + DMAC->DMAC_CHDR = (DMAC_CHDR_DIS0 << DmacChanW5500Rx) | (DMAC_CHDR_RES0 << DmacChanW5500Rx); return true; } return false; } -static void spi_tx_dma_setup(const TransactionBuffer *buf, uint32_t maxTransmitLength) noexcept +static inline bool spi_dma_check_tx_complete() noexcept { - DMAC->DMAC_EBCISR; // clear any pending interrupts + uint32_t status = DMAC->DMAC_CHSR; + return ((status & (DMAC_CHSR_ENA0 << DmacChanW5500Tx)) == 0) // controller is not enabled, perhaps because it finished a full buffer transfer + || ((status & (DMAC_CHSR_EMPT0 << DmacChanW5500Tx)) != 0); // controller is enabled, probably suspended, and the FIFO is empty +} - dmac_channel_set_source_addr(DMAC, CONF_SPI_DMAC_TX_CH, reinterpret_cast(buf)); - dmac_channel_set_destination_addr(DMAC, CONF_SPI_DMAC_TX_CH, reinterpret_cast(&(W5500_SPI->SPI_TDR))); - dmac_channel_set_descriptor_addr(DMAC, CONF_SPI_DMAC_TX_CH, 0); - dmac_channel_set_ctrlA(DMAC, CONF_SPI_DMAC_TX_CH, maxTransmitLength | DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_BYTE); - dmac_channel_set_ctrlB(DMAC, CONF_SPI_DMAC_TX_CH, +static void spi_tx_dma_setup(const uint8_t *buf, uint32_t length) noexcept +{ + DMAC->DMAC_EBCISR; // clear any pending interrupts + + dmac_channel_set_source_addr(DMAC, DmacChanW5500Tx, reinterpret_cast(buf)); + dmac_channel_set_destination_addr(DMAC, DmacChanW5500Tx, reinterpret_cast(&(W5500_SPI->SPI_TDR))); + dmac_channel_set_descriptor_addr(DMAC, DmacChanW5500Tx, 0); + dmac_channel_set_ctrlA(DMAC, DmacChanW5500Tx, length | DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_BYTE); + dmac_channel_set_ctrlB(DMAC, DmacChanW5500Tx, DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | DMAC_CTRLB_SRC_INCR_INCREMENTING | DMAC_CTRLB_DST_INCR_FIXED); } -static void spi_rx_dma_setup(const TransactionBuffer *buf) noexcept +static void spi_rx_dma_setup(uint8_t *buf, uint32_t length) noexcept { - DMAC->DMAC_EBCISR; // clear any pending interrupts + DMAC->DMAC_EBCISR; // clear any pending interrupts - dmac_channel_set_source_addr(DMAC, CONF_SPI_DMAC_RX_CH, reinterpret_cast(&(W5500_SPI->SPI_RDR))); - dmac_channel_set_destination_addr(DMAC, CONF_SPI_DMAC_RX_CH, reinterpret_cast(buf)); - dmac_channel_set_descriptor_addr(DMAC, CONF_SPI_DMAC_RX_CH, 0); -// dmac_channel_set_ctrlA(DMAC, CONF_SPI_DMAC_RX_CH, TransactionBuffer::MaxTransferBytes | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_WORD); - dmac_channel_set_ctrlB(DMAC, CONF_SPI_DMAC_RX_CH, + dmac_channel_set_source_addr(DMAC, DmacChanW5500Rx, reinterpret_cast(&(W5500_SPI->SPI_RDR))); + dmac_channel_set_destination_addr(DMAC, DmacChanW5500Rx, reinterpret_cast(buf)); + dmac_channel_set_descriptor_addr(DMAC, DmacChanW5500Rx, 0); + dmac_channel_set_ctrlA(DMAC, DmacChanW5500Rx, length | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_WORD); + dmac_channel_set_ctrlB(DMAC, DmacChanW5500Rx, DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_PER2MEM_DMA_FC | DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING); + spi_tx_dma_setup(buf, length); // we have to transmit in order to receive } #endif @@ -170,14 +173,12 @@ namespace WizSpi void Init() noexcept { #if USE_PDC - // The PDCs are masters 2 and 3 and the SRAM is slave 0. Give the receive PDCs the highest priority. + // The SPI PDC is on peripheral bridge 0 which is master #2. Give the SPI PDC the highest priority. matrix_set_master_burst_type(0, MATRIX_ULBT_8_BEAT_BURST); matrix_set_slave_default_master_type(0, MATRIX_DEFMSTR_LAST_DEFAULT_MASTER); - matrix_set_slave_priority(0, (3 << MATRIX_PRAS0_M2PR_Pos) | (3 << MATRIX_PRAS0_M3PR_Pos)); + matrix_set_slave_priority(0, 3 << MATRIX_PRAS0_M2PR_Pos); matrix_set_slave_slot_cycle(0, 8); -#endif - -#if USE_DMAC +#elif USE_DMAC pmc_enable_periph_clk(ID_DMAC); dmac_init(DMAC); dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN); @@ -202,7 +203,6 @@ namespace WizSpi #if USE_PDC || USE_DMAC spi_dma_disable(); #endif - spi_reset(W5500_SPI); // this clears the transmit and receive registers and puts the SPI into slave mode W5500_SPI->SPI_MR = SPI_MR_MSTR // master mode | SPI_MR_MODFDIS // disable fault detection @@ -220,12 +220,10 @@ namespace WizSpi #if USE_DMAC // Configure DMA RX channel - dmac_channel_set_configuration(DMAC, CONF_SPI_DMAC_RX_CH, - DMAC_CFG_SRC_PER(DMA_HW_ID_SPI_RX) | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG); + dmac_channel_set_configuration(DMAC, DmacChanW5500Rx, DMAC_CFG_SRC_PER(DMA_HW_ID_SPI_RX) | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG); // Configure DMA TX channel - dmac_channel_set_configuration(DMAC, CONF_SPI_DMAC_TX_CH, - DMAC_CFG_DST_PER(DMA_HW_ID_SPI_TX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG); + dmac_channel_set_configuration(DMAC, DmacChanW5500Tx, DMAC_CFG_DST_PER(DMA_HW_ID_SPI_TX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG); #endif } @@ -233,7 +231,7 @@ namespace WizSpi { NVIC_DisableIRQ(W5500_SPI_IRQn); spi_disable(W5500_SPI); -#if USE_PDC || USE_DMA +#if USE_PDC || USE_DMAC spi_dma_disable(); #endif } @@ -362,7 +360,7 @@ namespace WizSpi (void)W5500_SPI->SPI_RDR; // clear previous data } -#if USE_PDC +#if USE_PDC || USE_DMAC spi_rx_dma_setup(rx_data, len); spi_rx_dma_enable(); uint32_t timeout = SPI_TIMEOUT; @@ -416,7 +414,7 @@ namespace WizSpi { if (len != 0) { -#if USE_PDC +#if USE_PDC || USE_DMAC Cache::FlushBeforeDMASend(tx_data, len); spi_tx_dma_setup(tx_data, len); spi_tx_dma_enable(); -- cgit v1.2.3 From fff25c50df4b8889416e9e822b7005791fc36614 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Wed, 25 May 2022 08:32:16 +0100 Subject: Added a comment --- src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp b/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp index b4cc0e97..74da25e4 100644 --- a/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp +++ b/src/Networking/W5500Ethernet/Wiznet/Ethernet/WizSpi.cpp @@ -28,7 +28,7 @@ // SPI data rate. I tried 60MHz and we got some data corruption when uploading files, so I reduced it to 40MHz. // 2018-01-11: We have now received one report of data corruption at 40MHz, so reduced this to 30MHz // 2022-05-23: Very occasionally we get data corruption when uploading files, with a character being replaced by the following character. So reduced to 25MHz. -const uint32_t SpiClockFrequency = 25000000; +const uint32_t SpiClockFrequency = 25000000; // actually gets rounded down to 120/5 = 24MHz const unsigned int SpiPeripheralChannelId = 0; // we use NPCS0 as the slave select signal // Functions called by the W5500 module to transfer data to/from the W5500 via SPI -- cgit v1.2.3 From eb99dcb57a8c7ed2044db633a020e5be87e93600 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Wed, 25 May 2022 11:07:37 +0100 Subject: Changed version to 3.4.1rc2 --- src/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Version.h b/src/Version.h index f2a71146..ea28bdb2 100644 --- a/src/Version.h +++ b/src/Version.h @@ -10,7 +10,7 @@ #ifndef VERSION // Note: the complete VERSION string must be in standard version number format and must not contain spaces! This is so that DWC can parse it. -# define MAIN_VERSION "3.4.1rc1+1" +# define MAIN_VERSION "3.4.1rc2" # ifdef USE_CAN0 # define VERSION_SUFFIX "(CAN0)" # else -- cgit v1.2.3 From 57fcfb4e277b2f99e243438878176f027f2a4153 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Wed, 25 May 2022 11:59:04 +0100 Subject: Added support for Duet 3 MB6XD version 1.0 --- src/Config/Pins_Duet3_MB6XD.h | 3 ++- src/Platform/Platform.cpp | 48 +++++++++---------------------------------- src/Platform/Platform.h | 4 +++- 3 files changed, 15 insertions(+), 40 deletions(-) diff --git a/src/Config/Pins_Duet3_MB6XD.h b/src/Config/Pins_Duet3_MB6XD.h index 59a8b140..2aee62ce 100644 --- a/src/Config/Pins_Duet3_MB6XD.h +++ b/src/Config/Pins_Duet3_MB6XD.h @@ -98,7 +98,8 @@ constexpr Pin UsbVBusPin = PortCPin(21); // Pin used to monitor VBUS on USB po // Drivers constexpr Pin STEP_PINS[NumDirectDrivers] = { PortCPin(18), PortCPin(16), PortCPin(28), PortCPin(01), PortCPin(4), PortCPin(9) }; constexpr Pin DIRECTION_PINS[NumDirectDrivers] = { PortBPin(5), PortDPin(10), PortAPin(4), PortAPin(22), PortCPin(3), PortDPin(14) }; -constexpr Pin ENABLE_PINS[NumDirectDrivers] = { PortBPin(4), PortAPin(21), PortAPin(9), PortAPin(23), PortAPin(2), PortDPin(17) }; +constexpr Pin ENABLE_PINS_v01[NumDirectDrivers] = { PortBPin(4), PortAPin(21), PortAPin(9), PortAPin(23), PortAPin(2), PortDPin(17) }; +constexpr Pin ENABLE_PINS_v100[NumDirectDrivers] = { PortBPin(4), PortAPin(21), PortCPin(20), PortAPin(23), PortAPin(2), PortDPin(17) }; constexpr Pin DRIVER_ERR_PINS[NumDirectDrivers] = { PortDPin(29), PortCPin(17), PortDPin(13), PortCPin(02), PortDPin(31), PortCPin(10) }; constexpr Pin StepGatePin = PortDPin(22); constexpr GpioPinFunction StepGatePinFunction = GpioPinFunction::C; // TIOB11 diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp index fc1afd3f..54fd7916 100644 --- a/src/Platform/Platform.cpp +++ b/src/Platform/Platform.cpp @@ -551,40 +551,6 @@ void Platform::Init() noexcept # endif #endif -#if defined(DUET_06_085) - ARRAY_INIT(defaultMacAddress, DefaultMacAddress); - - // Motor current setting on Duet 0.6 and 0.8.5 - I2C::Init(); - mcpExpansion.setMCP4461Address(0x2E); // not required for mcpDuet, as this uses the default address - ARRAY_INIT(potWipes, POT_WIPES); - senseResistor = SENSE_RESISTOR; - maxStepperDigipotVoltage = MAX_STEPPER_DIGIPOT_VOLTAGE; - stepperDacVoltageRange = STEPPER_DAC_VOLTAGE_RANGE; - stepperDacVoltageOffset = STEPPER_DAC_VOLTAGE_OFFSET; -#elif defined(__ALLIGATOR__) - pinMode(EthernetPhyResetPin, INPUT); // Init Ethernet Phy Reset Pin - - // Alligator Init DAC for motor current vref - ARRAY_INIT(spiDacCS, SPI_DAC_CS); - dacAlligator.Init(spiDacCS[0]); - dacPiggy.Init(spiDacCS[1]); - // Get macaddress from EUI48 eeprom - eui48MacAddress.Init(Eui48csPin); - if (!eui48MacAddress.getEUI48(defaultMacAddress)) - { - ARRAY_INIT(defaultMacAddress, DefaultMacAddress); - } - - Microstepping::Init(); // Init Motor FAULT detect Pin - pinMode(ExpansionVoltageLevelPin, ExpansionVoltageLevel==3 ? OUTPUT_LOW : OUTPUT_HIGH); // Init Expansion Voltage Level Pin - pinMode(MotorFaultDetectPin,INPUT); // Init Motor FAULT detect Pin - pinMode(ExpansionPiggyDetectPin,INPUT); // Init Expansion Piggy module presence Pin - pinMode(FTDIconverterResetPin,INPUT); // Init FTDI Serial Converter Reset Pin - pinMode(SpiEEPROMcsPin,OUTPUT_HIGH); // Init Spi EEPROM Cs pin, not implemented, default unselected - pinMode(SpiFLASHcsPin,OUTPUT_HIGH); // Init Spi FLASH Cs pin, not implemented, default unselected -#endif - #if defined(__LPC17xx__) if (hasDriverCurrentControl) { @@ -646,6 +612,7 @@ void Platform::Init() noexcept // Set up the local drivers. Do this after we have read any direction pins that specify the board type. #ifdef DUET3_MB6XD + ENABLE_PINS = (GetBoardType() == BoardType::Duet3_6XD_v01) ? ENABLE_PINS_v01 : ENABLE_PINS_v100; unsigned int numErrorHighDrivers = 0; #endif for (size_t driver = 0; driver < NumDirectDrivers; ++driver) @@ -3793,12 +3760,15 @@ void Platform::SetBoardType(BoardType bt) noexcept ? BoardType::Duet3Mini_WiFi : BoardType::Duet3Mini_Ethernet; #elif defined(DUET3_MB6HC) - // Driver 0 direction has a pulldown resistor on v0.6 and v1.0 boards, but won't on v1.01 boards + // Driver 0 direction has a pulldown resistor on v0.6 and v1.0 boards, but not on v1.01 boards pinMode(DIRECTION_PINS[0], INPUT_PULLUP); delayMicroseconds(20); // give the pullup resistor time to work board = (digitalRead(DIRECTION_PINS[0])) ? BoardType::Duet3_6HC_v101 : BoardType::Duet3_6HC_v06_100; #elif defined(DUET3_MB6XD) - board = BoardType::Duet3_6XD; + // Driver 0 direction has a pulldown resistor on v1.0 boards, but not on v0.1 boards + pinMode(DIRECTION_PINS[0], INPUT_PULLUP); + delayMicroseconds(20); // give the pullup resistor time to work + board = (digitalRead(DIRECTION_PINS[0])) ? BoardType::Duet3_6XD_v01 : BoardType::Duet3_6XD_v100; #elif defined(FMDC_V02) || defined(FMDC_V03) board = BoardType::FMDC; #elif defined(SAME70XPLD) @@ -3878,7 +3848,8 @@ const char *_ecv_array Platform::GetElectronicsString() const noexcept case BoardType::Duet3_6HC_v06_100: return "Duet 3 " BOARD_SHORT_NAME " v0.6 or 1.0"; case BoardType::Duet3_6HC_v101: return "Duet 3 " BOARD_SHORT_NAME " v1.01 or later"; #elif defined(DUET3_MB6XD) - case BoardType::Duet3_6XD: return "Duet 3 " BOARD_SHORT_NAME; // we have only one version at present + case BoardType::Duet3_6XD_v01: return "Duet 3 " BOARD_SHORT_NAME " v0.1"; + case BoardType::Duet3_6XD_v100: return "Duet 3 " BOARD_SHORT_NAME " v1.0 or later"; #elif defined(FMDC_V02) || defined(FMDC_V03) case BoardType::FMDC: return "Duet 3 " BOARD_SHORT_NAME; #elif defined(SAME70XPLD) @@ -3917,7 +3888,8 @@ const char *_ecv_array Platform::GetBoardString() const noexcept case BoardType::Duet3_6HC_v06_100: return "duet3mb6hc100"; case BoardType::Duet3_6HC_v101: return "duet3mb6hc101"; #elif defined(DUET3_MB6XD) - case BoardType::Duet3_6XD: return "duet3mb6xd"; // we have only one version at present + case BoardType::Duet3_6XD_v01: return "duet3mb6xd001"; // we have only one version at present + case BoardType::Duet3_6XD_v100: return "duet3mb6xd100"; // we have only one version at present #elif defined(FMDC_V02) || defined(FMDC_V03) case BoardType::FMDC: return "fmdc"; #elif defined(SAME70XPLD) diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h index b38533a5..585bf64a 100644 --- a/src/Platform/Platform.h +++ b/src/Platform/Platform.h @@ -127,7 +127,8 @@ enum class BoardType : uint8_t Duet3_6HC_v06_100 = 1, Duet3_6HC_v101 = 2, #elif defined(DUET3_MB6XD) - Duet3_6XD = 1, + Duet3_6XD_v01 = 1, + Duet3_6XD_v100 = 2, #elif defined(FMDC_V02) || defined(FMDC_V03) FMDC, #elif defined(SAME70XPLD) @@ -790,6 +791,7 @@ private: uint32_t stepPulseMinimumPeriodClocks; // minimum period between leading edges of step pulses, in step clocks uint32_t directionSetupClocks; // minimum direction change to step high time, in step clocks uint32_t directionHoldClocksFromLeadingEdge; // minimum step high to direction low step clocks, calculated from the step low to direction change hold time + const Pin *ENABLE_PINS; // 6XD version 0.1 uses different enable pins from version 1.0 and later #else uint32_t slowDriversBitmap; // bitmap of driver port bits that need extended step pulse timing uint32_t slowDriverStepTimingClocks[4]; // minimum step high, step low, dir setup and dir hold timing for slow drivers -- cgit v1.2.3