| 
				
			 | 
			
			 | 
			@@ -11,7 +11,7 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "SPI.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "pins_arduino.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//#define DEBUG_DMA_TRANSFERS | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/**********************************************************/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/*     8 bit AVR-based boards				  */ | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -1282,7 +1282,7 @@ void SPIClass::begin() | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint32_t fastio = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				//uint32_t fastio = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				Serial.printf("SPI MISO: %d MOSI: %d, SCK: %d\n", hardware().miso_pin[miso_pin_index], hardware().mosi_pin[mosi_pin_index], hardware().sck_pin[sck_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				//Serial.printf("SPI MISO: %d MOSI: %d, SCK: %d\n", hardware().miso_pin[miso_pin_index], hardware().mosi_pin[mosi_pin_index], hardware().sck_pin[sck_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*(portControlRegister(hardware().miso_pin[miso_pin_index])) = fastio; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*(portControlRegister(hardware().mosi_pin[mosi_pin_index])) = fastio; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*(portControlRegister(hardware().sck_pin[sck_pin_index])) = fastio; | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -1385,8 +1385,11 @@ void SPIClass::setDataMode(uint8_t dataMode) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				//SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void _spi_dma_rxISR0(void) {SPI.dma_rxisr();} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			const SPIClass::SPI_Hardware_t  SPIClass::spiclass_lpspi4_hardware = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				DMAMUX_SOURCE_LPSPI4_TX, DMAMUX_SOURCE_LPSPI4_RX, _spi_dma_rxISR0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				12,  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				3 | 0x10, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				11, | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -1435,7 +1438,7 @@ void SPIClass::transfer(const void * buf, void * retbuf, size_t count) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Pass 1 keep it simple and don't try packing 8 bits into 16 yet.. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Lets clear the reader queue | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				//port().CR = LPSPI_CR_RRF; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().CR = LPSPI_CR_RRF | LPSPI_CR_MEN;	// clear the queue and make sure still enabled.  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				while (count > 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// Push out the next byte;  | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -1465,6 +1468,202 @@ void SPIClass::transfer(const void * buf, void * retbuf, size_t count) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::end(){} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//============================================================================= | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// ASYNCH Support | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//============================================================================= | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//========================================================================= | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// Try Transfer using DMA. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//========================================================================= | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef SPI_HAS_TRANSFER_ASYNC | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static uint8_t bit_bucket; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define dontInterruptAtCompletion(dmac) (dmac)->TCD->CSR &= ~DMA_TCD_CSR_INTMAJOR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//========================================================================= | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// Init the DMA channels | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//========================================================================= | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			bool SPIClass::initDMAChannels() { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Allocate our channels.  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaTX = new DMAChannel(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (_dmaTX == nullptr) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return false; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX = new DMAChannel(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (_dmaRX == nullptr) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					delete _dmaTX; // release it | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaTX = nullptr;  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return false; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Let's setup the RX chain | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->disable(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->source((volatile uint8_t&)port().RDR); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->disableOnCompletion(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->attachInterrupt(hardware().dma_rxisr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->interruptAtCompletion(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// We may be using settings chain here so lets set it up.  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Now lets setup TX chain.  Note if trigger TX is not set | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// we need to have the RX do it for us. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaTX->disable(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaTX->destination((volatile uint8_t&)port().TDR); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaTX->disableOnCompletion(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (hardware().tx_dma_channel) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//		Serial.printf("SPI InitDMA tx triger by RX: %x\n", (uint32_t)_dmaRX); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				    _dmaTX->triggerAtTransfersOf(*_dmaRX); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dma_state = DMAState::idle;  // Should be first thing set! | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return true; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//========================================================================= | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// Main Async Transfer function | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//========================================================================= | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifndef TRANSFER_COUNT_FIXED | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// note does no validation of length... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				DMABaseClass::TCD_t *tcd = dmac->TCD; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (!(tcd->BITER & DMA_TCD_BITER_ELINK)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					tcd->BITER = len & 0x7fff; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					tcd->BITER = (tcd->BITER & 0xFE00) | (len & 0x1ff); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				tcd->CITER = tcd->BITER;  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#else  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				dmac->transferCount(len); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef DEBUG_DMA_TRANSFERS | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void dumpDMA_TCD(DMABaseClass *dmabc) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				Serial4.printf("%x %x:", (uint32_t)dmabc, (uint32_t)dmabc->TCD); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				Serial4.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dmabc->TCD->SADDR, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					dmabc->TCD->SOFF, dmabc->TCD->ATTR, dmabc->TCD->NBYTES, dmabc->TCD->SLAST, (uint32_t)dmabc->TCD->DADDR,  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					dmabc->TCD->DOFF, dmabc->TCD->CITER, dmabc->TCD->DLASTSGA, dmabc->TCD->CSR, dmabc->TCD->BITER); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (_dma_state == DMAState::notAllocated) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (!initDMAChannels()) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						return false; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (_dma_state == DMAState::active) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return false; // already active | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				event_responder.clearEvent();	// Make sure it is not set yet | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (count < 2) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// Use non-async version to simplify cases... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					transfer(buf, retbuf, count); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					event_responder.triggerEvent(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return true; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Now handle the cases where the count > then how many we can output in one DMA request | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (count > MAX_DMA_COUNT) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dma_count_remaining = count - MAX_DMA_COUNT; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					count = MAX_DMA_COUNT; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dma_count_remaining = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Now See if caller passed in a source buffer.  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaTX->TCD->ATTR_DST = 0;		// Make sure set for 8 bit mode | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint8_t *write_data = (uint8_t*) buf; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (buf) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaTX->sourceBuffer((uint8_t*)write_data, count);   | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaTX->TCD->SLAST = 0;	// Finish with it pointing to next location | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if ((uint32_t)write_data >= 0x20200000u)  arm_dcache_flush(write_data, count); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaTX->source((uint8_t&)_transferWriteFill);   // maybe have setable value | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					DMAChanneltransferCount(_dmaTX, count); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}	 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (retbuf) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// On T3.5 must handle SPI1/2 differently as only one DMA channel | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaRX->TCD->ATTR_SRC = 0;		//Make sure set for 8 bit mode... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaRX->destinationBuffer((uint8_t*)retbuf, count); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaRX->TCD->DLASTSGA = 0;		// At end point after our bufffer | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if ((uint32_t)retbuf >= 0x20200000u)  arm_dcache_delete(retbuf, count); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						// Write  only mode | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaRX->TCD->ATTR_SRC = 0;		//Make sure set for 8 bit mode... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaRX->destination((uint8_t&)bit_bucket); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					DMAChanneltransferCount(_dmaRX, count); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dma_event_responder = &event_responder; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Now try to start it? | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Setup DMA main object | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				yield(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef DEBUG_DMA_TRANSFERS | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Lets dump TX, RX | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				dumpDMA_TCD(_dmaTX); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				dumpDMA_TCD(_dmaRX); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Make sure port is in 8 bit mode and clear watermark | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().TCR = (port().TCR & ~(LPSPI_TCR_FRAMESZ(31))) | LPSPI_TCR_FRAMESZ(7);	 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().FCR = 0;  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Lets try to output the first byte to make sure that we are in 8 bit mode... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 	port().DER = LPSPI_DER_TDDE | LPSPI_DER_RDDE;	//enable DMA on both TX and RX | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().SR = 0x3f00;	// clear out all of the other status... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->enable(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaTX->enable(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dma_state = DMAState::active; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return true; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//------------------------------------------------------------------------- | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// DMA RX ISR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//------------------------------------------------------------------------- | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::dma_rxisr(void) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->clearInterrupt(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaTX->clearComplete(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_dmaRX->clearComplete(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (_dma_count_remaining) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// What do I need to do to start it back up again... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// We will use the BITR/CITR from RX as TX may have prefed some stuff | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (_dma_count_remaining > MAX_DMA_COUNT) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						_dma_count_remaining -= MAX_DMA_COUNT; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						DMAChanneltransferCount(_dmaTX, _dma_count_remaining); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						DMAChanneltransferCount(_dmaRX, _dma_count_remaining); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						_dma_count_remaining = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaRX->enable(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dmaTX->enable(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					port().FCR = LPSPI_FCR_TXWATER(15); // _spi_fcr_save;	// restore the FSR status...  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 		port().DER = 0;		// DMA no longer doing TX (or RX) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					port().CR = LPSPI_CR_MEN | LPSPI_CR_RRF | LPSPI_CR_RTF;   // actually clear both... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					port().SR = 0x3f00;	// clear out all of the other status... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dma_state = DMAState::completed;   // set back to 1 in case our call wants to start up dma again | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_dma_event_responder->triggerEvent(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif // SPI_HAS_TRANSFER_ASYNC | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif |