Merge ccd626637c into 05e83bcb71
This commit is contained in:
commit
aed28ad472
2 changed files with 32 additions and 0 deletions
|
|
@ -252,6 +252,11 @@ void SPIClass::transfer(void *buf, size_t count)
|
|||
// a reference back to the originating SPIClass object.
|
||||
static SPIClass *spiPtr[DMAC_CH_NUM] = { 0 }; // Legit inits list to NULL
|
||||
|
||||
// Pointer to a user-defined callback function, one per DMA channel. These
|
||||
// will be duplicated for read & write channels corresponding to the same
|
||||
// SPIClass (see SPIClass::dmaAllocate()).
|
||||
static SPIClass::UserCallbackFunction* userActiveCallback[DMAC_CH_NUM] = { 0 };
|
||||
|
||||
void SPIClass::dmaCallback(Adafruit_ZeroDMA *dma) {
|
||||
// dmaCallback() receives an Adafruit_ZeroDMA object. From this we can get
|
||||
// a channel number (0 to DMAC_CH_NUM-1, always unique per ZeroDMA object),
|
||||
|
|
@ -259,6 +264,10 @@ void SPIClass::dmaCallback(Adafruit_ZeroDMA *dma) {
|
|||
// the dma_busy element 'false' to indicate end of transfer. Doesn't matter
|
||||
// if it's a read or write transfer...both channels get pointers to it.
|
||||
spiPtr[dma->getChannel()]->dma_busy = false;
|
||||
|
||||
if (auto userCallback = userActiveCallback[dma->getChannel()]) {
|
||||
userCallback(dma);
|
||||
}
|
||||
}
|
||||
|
||||
// For read-only and read+write transfers, a callback is assigned only
|
||||
|
|
@ -363,6 +372,24 @@ void SPIClass::dmaAllocate(void) {
|
|||
// transfer() function will fall back on a manual byte-by-byte loop.
|
||||
}
|
||||
|
||||
// User defined callback
|
||||
// SPI uses two DMA channels (read & write), but only one is assigned
|
||||
// a callback (see dmaCallback) for a given transfer, and the other gets
|
||||
// a dummy. Store the user's callback function on both channels, since
|
||||
// we don't know which one will be the source.
|
||||
// See also: Adafruit_ZeroDMA::getChannel()
|
||||
void SPIClass::dmaSetEndOfTransferCallback(UserCallbackFunction* callback)
|
||||
{
|
||||
userActiveCallback[readChannel.getChannel()] = callback;
|
||||
userActiveCallback[writeChannel.getChannel()] = callback;
|
||||
}
|
||||
|
||||
void SPIClass::dmaClearEndOfTransferCallback()
|
||||
{
|
||||
userActiveCallback[readChannel.getChannel()] = nullptr;
|
||||
userActiveCallback[writeChannel.getChannel()] = nullptr;
|
||||
}
|
||||
|
||||
void SPIClass::transfer(const void *txbuf, void *rxbuf, size_t count,
|
||||
bool block) {
|
||||
|
||||
|
|
|
|||
|
|
@ -132,6 +132,11 @@ class SPIClass {
|
|||
void attachInterrupt();
|
||||
void detachInterrupt();
|
||||
|
||||
// DMA Configuation methods
|
||||
using UserCallbackFunction = void(Adafruit_ZeroDMA*);
|
||||
void dmaSetEndOfTransferCallback(UserCallbackFunction* callback);
|
||||
void dmaClearEndOfTransferCallback();
|
||||
|
||||
void begin();
|
||||
void end();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue