Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 36 additions & 12 deletions ChipSelect.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,27 @@

#include <core_pins.h>

/** \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
{
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() {}
Expand All @@ -24,18 +33,18 @@ 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
* outputs a message through Serial when something happens
**/
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.
Expand Down Expand Up @@ -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:
Expand All @@ -84,6 +99,7 @@ class ActiveLowChipSelect : public AbstractChipSelect

};

#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
class ActiveLowChipSelect1 : public AbstractChipSelect
{
public:
Expand All @@ -99,24 +115,32 @@ 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:
const unsigned int pin_;
const SPISettings settings_;

};
#endif


#endif // CHIPSELECT_H

117 changes: 112 additions & 5 deletions DmaSpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
};
Expand All @@ -82,9 +84,11 @@ namespace DmaSpi
uint8_t m_fill;
Transfer* m_pNext;
AbstractChipSelect* m_pSelect;
TransferType m_transferType;
};
} // namespace DmaSpi


template<typename DMASPI_INSTANCE, typename SPICLASS, SPICLASS& m_Spi>
class AbstractDmaSpi
{
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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