diff --git a/ChipSelect.h b/ChipSelect.h index 68084ee..d57fff9 100644 --- a/ChipSelect.h +++ b/ChipSelect.h @@ -3,6 +3,15 @@ #include +/** \brief Specifies the desired CS suppression +**/ +enum TransferType +{ + NORMAL, //*< The transfer will use CS at beginning and end **/ + NO_START_CS, //*< Skip the CS activation at the start **/ + NO_END_CS //*< SKip the CS deactivation at the end **/ +}; + /** \brief An abstract base class that provides an interface for chip select classes. **/ class AbstractChipSelect @@ -10,11 +19,11 @@ class AbstractChipSelect public: /** \brief Called to select a chip. The implementing class can do other things as well. **/ - virtual void select() = 0; + virtual void select(TransferType transferType = TransferType::NORMAL) = 0; /** \brief Called to deselect a chip. The implementing class can do other things as well. **/ - virtual void deselect() = 0; + virtual void deselect(TransferType transferType = TransferType::NORMAL) = 0; /** \brief the virtual destructor needed to inherit from this class **/ virtual ~AbstractChipSelect() {} @@ -24,9 +33,9 @@ class AbstractChipSelect /** \brief "do nothing" chip select class **/ class DummyChipSelect : public AbstractChipSelect { - void select() override {} + void select(TransferType transferType = TransferType::NORMAL) override {} - void deselect() override {} + void deselect(TransferType transferType = TransferType::NORMAL) override {} }; /** \brief "do nothing" chip select class that @@ -34,8 +43,8 @@ class DummyChipSelect : public AbstractChipSelect **/ class DebugChipSelect : public AbstractChipSelect { - void select() override {Serial.println("Debug CS: select()");} - void deselect() override {Serial.println("Debug CS: deselect()");} + void select(TransferType transferType = TransferType::NORMAL) override {Serial.println("Debug CS: select()");} + void deselect(TransferType transferType = TransferType::NORMAL) override {Serial.println("Debug CS: deselect()");} }; /** \brief An active low chip select class. This also configures the given pin. @@ -65,17 +74,23 @@ class ActiveLowChipSelect : public AbstractChipSelect /** \brief begins an SPI transaction selects the chip (sets the pin to low) and **/ - void select() override + void select(TransferType transferType = TransferType::NORMAL) override { SPI.beginTransaction(settings_); + if (transferType == TransferType::NO_START_CS) { + return; + } digitalWriteFast(pin_, 0); } /** \brief deselects the chip (sets the pin to high) and ends the SPI transaction **/ - void deselect() override + void deselect(TransferType transferType = TransferType::NORMAL) override { - digitalWriteFast(pin_, 1); + if (transferType == TransferType::NO_END_CS) { + } else { + digitalWriteFast(pin_, 1); + } SPI.endTransaction(); } private: @@ -84,6 +99,7 @@ class ActiveLowChipSelect : public AbstractChipSelect }; +#if defined(__MK64FX512__) || defined(__MK66FX1M0__) class ActiveLowChipSelect1 : public AbstractChipSelect { public: @@ -99,17 +115,23 @@ class ActiveLowChipSelect1 : public AbstractChipSelect /** \brief begins an SPI transaction selects the chip (sets the pin to low) and **/ - void select() override + void select(TransferType transferType = TransferType::NORMAL) override { SPI1.beginTransaction(settings_); + if (transferType == TransferType::NO_START_CS) { + return; + } digitalWriteFast(pin_, 0); } /** \brief deselects the chip (sets the pin to high) and ends the SPI transaction **/ - void deselect() override + void deselect(TransferType transferType = TransferType::NORMAL) override { - digitalWriteFast(pin_, 1); + if (transferType == TransferType::NO_END_CS) { + } else { + digitalWriteFast(pin_, 1); + } SPI1.endTransaction(); } private: @@ -117,6 +139,8 @@ class ActiveLowChipSelect1 : public AbstractChipSelect const SPISettings settings_; }; +#endif + #endif // CHIPSELECT_H diff --git a/DmaSpi.h b/DmaSpi.h index 3d2200d..97df11a 100644 --- a/DmaSpi.h +++ b/DmaSpi.h @@ -54,14 +54,16 @@ namespace DmaSpi const uint16_t& transferCount = 0, volatile uint8_t* pDest = nullptr, const uint8_t& fill = 0, - AbstractChipSelect* cs = nullptr + AbstractChipSelect* cs = nullptr, + TransferType transferType = TransferType::NORMAL ) : m_state(State::idle), m_pSource(pSource), m_transferCount(transferCount), m_pDest(pDest), m_fill(fill), m_pNext(nullptr), - m_pSelect(cs) + m_pSelect(cs), + m_transferType(transferType) { DMASPI_PRINT(("Transfer @ %p\n", this)); }; @@ -82,9 +84,11 @@ namespace DmaSpi uint8_t m_fill; Transfer* m_pNext; AbstractChipSelect* m_pSelect; + TransferType m_transferType; }; } // namespace DmaSpi + template class AbstractDmaSpi { @@ -210,6 +214,7 @@ class AbstractDmaSpi return true; } + /** \brief Check if the DMA SPI is busy, which means that it is currently handling a Transfer. \return true if a Transfer is being handled. * \see start() @@ -347,7 +352,7 @@ class AbstractDmaSpi { if (m_pCurrentTransfer->m_pSelect != nullptr) { - m_pCurrentTransfer->m_pSelect->deselect(); + m_pCurrentTransfer->m_pSelect->deselect(m_pCurrentTransfer->m_transferType); } else { @@ -487,7 +492,7 @@ class AbstractDmaSpi // Select Chip if (m_pCurrentTransfer->m_pSelect != nullptr) { - m_pCurrentTransfer->m_pSelect->select(); + m_pCurrentTransfer->m_pSelect->select(m_pCurrentTransfer->m_transferType); } else { @@ -765,6 +770,108 @@ extern DmaSpi1 DMASPI1; #error Unknown chip -#endif // KINETISK else KINETISL +#endif // KINETISK else KINETISL + +class DmaSpiGeneric +{ +public: + using Transfer = DmaSpi::Transfer; + + DmaSpiGeneric() { + m_spiDma0 = &DMASPI0; + m_spiDma1 = &DMASPI1; + } + DmaSpiGeneric(int spiId) : DmaSpiGeneric() { + m_spiSelect = spiId; + } + + bool begin () { + switch(m_spiSelect) { + case 1 : return m_spiDma1->begin(); + default : + return m_spiDma0->begin(); + } + } + + void start () { + switch(m_spiSelect) { + case 1 : m_spiDma1->start(); return; + default : + m_spiDma0->start(); return; + } + } + + bool running () { + switch(m_spiSelect) { + case 1 : return m_spiDma1->running(); + default : + return m_spiDma0->running(); + } + } + + bool registerTransfer (Transfer& transfer) { + switch(m_spiSelect) { + case 1 : return m_spiDma1->registerTransfer(transfer); + default : + return m_spiDma0->registerTransfer(transfer); + } + } + + + bool busy () { + switch(m_spiSelect) { + case 1 : return m_spiDma1->busy(); + default : + return m_spiDma0->busy(); + } + } + + void stop () { + switch(m_spiSelect) { + case 1 : m_spiDma1->stop(); return; + default : + m_spiDma0->stop(); return; + } + } + + bool stopping () { + switch(m_spiSelect) { + case 1 : return m_spiDma1->stopping(); + default : + return m_spiDma0->stopping(); + } + } + + bool stopped () { + switch(m_spiSelect) { + case 1 : return m_spiDma1->stopped(); + default : + return m_spiDma0->stopped(); + } + } + + void end () { + switch(m_spiSelect) { + case 1 : m_spiDma1->end(); return; + default : + m_spiDma0->end(); return; + } + } + + uint8_t devNull () { + switch(m_spiSelect) { + case 1 : return m_spiDma1->devNull(); + default : + return m_spiDma0->devNull(); + } + } + +private: + int m_spiSelect = 0; + DmaSpi0 *m_spiDma0 = nullptr; + DmaSpi1 *m_spiDma1 = nullptr; + +}; + #endif // DMASPI_H