// Quick and dirty extract of parts of Teensyview to compare speed of different SPI methods to compare
// speed.
#include <SPI.h>
#include <DMAChannel.h>
#define DBGSerial Serial
#define BUFFER_SIZE 128
#define RXBUFFER_FILL_CHAR 0xC5
uint8_t buffer[BUFFER_SIZE];
uint8_t rxbuffer[BUFFER_SIZE+1];
volatile uint8_t our_dma_state = 0;
uint32_t clockRateSetting = 1000000;
// Only define one of these
#define _SPI SPI
//#define _SPI SPI1
//#define _SPI SPI2
#define USE_PIN_PORT
#define PIN_DC 9
#define PIN_CS 10
// BUGBUG Defined for T3.6 beta board
#define MISO2 51
#define MOSI2 52
#define SCK2 53
#ifdef USE_PIN_PORT
#define ASSERT_DC() *_dcport &= ~_dcpinmask
#define RELEASE_DC() *_dcport |= _dcpinmask
#define ASSERT_CS() *_csport &= ~_cspinmask
#define RELEASE_CS() *_csport |= _cspinmask
#else
#define ASSERT_DC() digitalWrite(PIN_DC, LOW)
#define RELEASE_DC() digitalWrite(PIN_DC, HIGH)
#define ASSERT_CS() digitalWrite(PIN_CS, LOW)
#define RELEASE_CS() digitalWrite(PIN_CS, HIGH)
#endif
volatile uint8_t * _csport, * _dcport;
uint8_t _cspinmask, _dcpinmask;
#ifndef _SPI
#define _SPI SPI
#endif
void setup()
{
while (!DBGSerial && millis() < 3000) ;
DBGSerial.begin(115200);
delay(100);
DBGSerial.println("Start setup");
pinMode(PIN_CS, OUTPUT);
#ifdef USE_PIN_PORT
_csport = portOutputRegister(digitalPinToPort(PIN_CS));
_cspinmask = digitalPinToBitMask(PIN_CS);
#endif
RELEASE_CS();
DBGSerial.println("Before pinMode DC"); Serial.flush();
pinMode(PIN_DC, OUTPUT);
#ifdef USE_PIN_PORT
_dcport = portOutputRegister(digitalPinToPort(PIN_DC));
_dcpinmask = digitalPinToBitMask(PIN_DC);
#endif
DBGSerial.println("Before SPI Begin"); Serial.flush();
#if defined(__MK66FX1M0__)
SPI2.setMOSI(MOSI2);
SPI2.setMISO(MISO2);
SPI2.setSCK(SCK2);
#endif
_SPI.begin();
DBGSerial.println("End Setup"); Serial.flush();
}
//===========================================================================
// Main Loop
//===========================================================================
void loop()
{
DBGSerial.println("*** Loop called ***");
InitTestBuffers();
_SPI.beginTransaction(SPISettings(clockRateSetting, MSBFIRST, SPI_MODE0));
//---------------------------------------------------------------------------
// Simple Test to see if simple transfer works
//---------------------------------------------------------------------------
uint8_t i;
uint32_t start_time = micros();
ASSERT_CS();
for (i = 0; i < sizeof(buffer); i++) {
_SPI.transfer(buffer[i]);
}
RELEASE_CS();
Serial.println(micros() - start_time, DEC); Serial.flush();
delayMicroseconds (25);
//---------------------------------------------------------------------------
// Simple Test to see if simple transfer16 works
//---------------------------------------------------------------------------
start_time = micros();
ASSERT_CS();
for (i = 0; i < sizeof(buffer); i += 2) {
_SPI.transfer16((buffer[i] << 8) | buffer[i + 1]);
}
RELEASE_CS();
Serial.println(micros() - start_time, DEC); Serial.flush();
delayMicroseconds (25);
start_time = micros();
ASSERT_CS();
_SPI.transfer(buffer, NULL, sizeof(buffer));
RELEASE_CS();
Serial.println(micros() - start_time, DEC); Serial.flush();
//---------------------------------------------------------------------------
// Simple Test to see if new transfer works.
//---------------------------------------------------------------------------
Serial.println("Try new Transfer!!!"); Serial.flush();
delayMicroseconds (25);
start_time = micros();
ASSERT_CS();
_SPI.transfer( buffer, rxbuffer, sizeof(buffer));
RELEASE_CS();
Serial.println(micros() - start_time, DEC); Serial.flush();
CheckBuffers();
//---------------------------------------------------------------------------
// DMA Transfer operaton - First output one byte to make sure in single mode
//---------------------------------------------------------------------------
// Now try DMA...
InitTestBuffers();
Serial.println("Try DMA Transfer after 8 bit write"); Serial.flush();
//_SPI.transfer16(0xffff); // See if calling with 1 byte changes things...
_SPI.transfer(0);
delayMicroseconds (25);
start_time = micros();
ASSERT_CS();
our_dma_state = 1;
Serial.printf("SPI Pushr: %x\n", SPI0_PUSHR);
_SPI.transfer( buffer, rxbuffer, sizeof(buffer), &Our_DMA_callback);
//while (our_dma_state) ;
uint32_t dma_start_time = millis();
while (our_dma_state && ((millis()-dma_start_time) < 100)) ;
extern void dumpDMA_TCD(DMABaseClass *dmabc);
if (our_dma_state) {
Serial.println("Transfer timed out!");
Serial.printf("DMA CR: %x ES: %x ERQ: %x EEI: %x ERR: %x\n", DMA_CR, DMA_ES, DMA_ERQ, DMA_EEI, DMA_ERR);
dumpDMA_TCD(_SPI._dmaTX);
dumpDMA_TCD(_SPI._dmaRX);
Serial.printf("RXB: %x %x %x %x %x\n", rxbuffer[0], rxbuffer[1], rxbuffer[2], rxbuffer[3], rxbuffer[4]);
}
Serial.println(micros() - start_time, DEC); Serial.flush();
Serial.println(our_dma_state, DEC);
CheckBuffers();
//---------------------------------------------------------------------------
// DMA Write operation
//---------------------------------------------------------------------------
Serial.println("Try DMA Write!!!"); Serial.flush();
delayMicroseconds (10);
start_time = micros();
ASSERT_CS();
our_dma_state = 1;
_SPI.transfer( buffer, NULL, sizeof(buffer), &Our_DMA_callback);
while (our_dma_state) ;
Serial.println(micros() - start_time, DEC); Serial.flush();
//---------------------------------------------------------------------------
// DMA Read operation
//---------------------------------------------------------------------------
Serial.println("Try DMA Read!!!"); Serial.flush();
delayMicroseconds (10);
start_time = micros();
ASSERT_CS();
our_dma_state = 1;
_SPI.transfer( NULL, rxbuffer, sizeof(buffer), &Our_DMA_callback);
while (our_dma_state) ;
Serial.println(micros() - start_time, DEC); Serial.flush();
//---------------------------------------------------------------------------
// DMA Transfer operaton - Output 16 bit to see if we recover
//---------------------------------------------------------------------------
// Now try DMA...
Serial.println("Try DMA Transfer after 16 bit write!!!"); Serial.flush();
_SPI.transfer16(0xffff); // See if calling with 1 byte changes things...
delayMicroseconds (25);
InitTestBuffers();
start_time = micros();
ASSERT_CS();
our_dma_state = 1;
_SPI.transfer( buffer, rxbuffer, sizeof(buffer), &Our_DMA_callback);
//while (our_dma_state) ;
dma_start_time = millis();
while (our_dma_state && ((millis()-dma_start_time) < 100)) ;
Serial.println(micros() - start_time, DEC); Serial.flush();
Serial.println(our_dma_state, DEC);
CheckBuffers();
_SPI.endTransaction();
delay(2500);
}
//=============================================================================
// DMA callback
//=============================================================================
void Our_DMA_callback() {
Serial.println("DMA Callback");
RELEASE_CS();
our_dma_state = 0;
}
//=============================================================================
// Init the test buffer
//=============================================================================
void InitTestBuffers() {
uint8_t i;
for (i = 0; i < BUFFER_SIZE; i++) {
buffer[i] = i;
}
memset(rxbuffer, RXBUFFER_FILL_CHAR, sizeof(rxbuffer));
}
//=============================================================================
// Check Buffers
//=============================================================================
bool CheckBuffers() {
bool OK = true;
for (uint8_t i=0; i < sizeof(buffer); i++) {
if (buffer[i] != i) {
Serial.printf("TX change(%d) %x\n", i, buffer[i]);
OK = false;
}
if (buffer[i] != rxbuffer[i]) {
Serial.printf("Error(%d) %x != %x\n", i, buffer[i], rxbuffer[i]);
OK = false;
break;
}
}
if (OK && (rxbuffer[BUFFER_SIZE] != RXBUFFER_FILL_CHAR)) {
Serial.printf("Error RX Overwrite: %x\n", rxbuffer[BUFFER_SIZE]);
OK = false;
}
//Serial.printf(" %x %x %x %x %x\n", rxbuffer[i+1], rxbuffer[i+2], rxbuffer[i+3], rxbuffer[i+4], rxbuffer[i+5]);
return OK;
}