diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-06-14 02:08:51 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-06-14 02:08:51 +0300 |
commit | 7caf1bb15bc36392761b5c54735d910f5548d765 (patch) | |
tree | b3635fa1a0fb8c4a130e296ca4cdfb95b95ba756 /src/Hardware/SAME70 | |
parent | 35923f84e6b3d387c1608fa591fa6aa3e218175f (diff) |
Changes for 5LC
Diffstat (limited to 'src/Hardware/SAME70')
-rw-r--r-- | src/Hardware/SAME70/DmacManager.cpp | 64 | ||||
-rw-r--r-- | src/Hardware/SAME70/DmacManager.h | 81 |
2 files changed, 145 insertions, 0 deletions
diff --git a/src/Hardware/SAME70/DmacManager.cpp b/src/Hardware/SAME70/DmacManager.cpp new file mode 100644 index 00000000..052e23dc --- /dev/null +++ b/src/Hardware/SAME70/DmacManager.cpp @@ -0,0 +1,64 @@ +/* + * DmacManager.cpp + * + * Created on: 12 Sep 2018 + * Author: David + * + * The purpose of this module is to service the DMA Complete interrupt from the XDMAC on the SAME70 + * and route the interrupts caused by the various DMA channels to the corresponding drivers. + */ + +#include <RepRapFirmware.h> +#include "DmacManager.h" + +#if SAME70 + +namespace DmacManager +{ + static StandardCallbackFunction callbackFunctions[NumDmaChannelsUsed] = { 0 }; + static CallbackParameter callbackParameters[NumDmaChannelsUsed]; + + void Init() noexcept + { + pmc_enable_periph_clk(ID_XDMAC); + for (unsigned int i = 0; i < NumDmaChannelsUsed; ++i) + { + XDMAC->XDMAC_CHID[i].XDMAC_CID = 0xFFFFFFFF; // disable all XDMAC interrupts from the channel + } + NVIC_EnableIRQ(XDMAC_IRQn); + } + + void SetInterruptCallback(const uint8_t channel, StandardCallbackFunction fn, CallbackParameter param) noexcept + { + if (channel < NumDmaChannelsUsed) + { + callbackFunctions[channel] = fn; + callbackParameters[channel] = param; + } + } +} + +// DMAC interrupt service routine +extern "C" void XDMAC_Handler() noexcept +{ + uint32_t pendingChannels = XDMAC->XDMAC_GIS; + for (size_t i = 0; i < NumDmaChannelsUsed; ++i) + { + if ((pendingChannels & 1u) != 0) + { + if (DmacManager::callbackFunctions[i] != nullptr) + { + DmacManager::callbackFunctions[i](DmacManager::callbackParameters[i]); // we rely on the callback to clear the interrupt + } + else + { + XDMAC->XDMAC_CHID[i].XDMAC_CID = 0xFFFFFFFF; // no callback, so just clear the interrupt + } + } + pendingChannels >>= 1; + } +} + +#endif + +// End diff --git a/src/Hardware/SAME70/DmacManager.h b/src/Hardware/SAME70/DmacManager.h new file mode 100644 index 00000000..4433a4ca --- /dev/null +++ b/src/Hardware/SAME70/DmacManager.h @@ -0,0 +1,81 @@ +/* + * DmacManager.h + * + * Created on: 12 Sep 2018 + * Author: David + */ + +#ifndef SRC_DMACMANAGER_H_ +#define SRC_DMACMANAGER_H_ + +#if SAME70 + +// DMAC peripheral identifiers for the SAME70 form table 36.1 in the data sheet. These don't seem to be defined anywhere in the ASF files. +enum class DmaTrigSource : uint32_t +{ + hsmci = 0, // both transmit and receive + spi0tx, + spi0rx, + spi1tx, + spi1rx, + qspitx, + qspirx, + usart0tx, + usart0rx, + usart1tx, + usart1rx, + usart2tx, + usart2rx, + pwm0tx, + twihs0tx, + twihs0rx, + twihs1tx, + twihs1rx, + twihs2tx, + twihs2rx, + uart0tx, + uart0rx, + uart1tx, + uart1rx, + uart2tx, + uart2rx, + uart3tx, + uart3rx, + uart4tx, + uart4rx, + dacctx, + unused1, // ID 30 does not appear in the table + ssctx, + sscrx, + pioarx, + afec0rx, + afec1rx, + aestx, + aesrx, + pwm1tx, + tc0rx, + tc3rx, + tc6rx, + tc9rx, + i2sc0txl, + i2sc0rxl, + i2sc1txl, + i2sc1rxl, + i2sc0txr, + i2sc0rxr, + i2sc1txr, + i2sc1rxr, + numPeripheralIds +}; + +static_assert((uint32_t)DmaTrigSource::numPeripheralIds == 52, "Error in peripheral ID table"); + +namespace DmacManager +{ + void Init() noexcept; + void SetInterruptCallback(const uint8_t channel, StandardCallbackFunction fn, CallbackParameter param) noexcept; +} + +#endif + +#endif /* SRC_DMACMANAGER_H_ */ |