You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BALibrary/examples/Tests/DMA_MEM0_test/DMA_MEM0_test.ino

324 lines
8.7 KiB

/*************************************************************************
* This demo uses the BALibrary to provide enhanced control of
* the TGA Pro board.
*
* The latest copy of BALibrary can be obtained from
* https://github.com/Blackaddr/BALibrary
*
* This demo will perform a DMA memory test on MEM0 attached
* to SPI.
*
* NOTE: SPI MEM0 can be used by a Teensy 3.2/3.5/3.6.
* pins.
*
*/
#include <Wire.h>
#include "BALibrary.h"
using namespace BALibrary;
//#define SANITY
#define DMA_SIZE 256
#define SPI_WRITE_CMD 0x2
#define SPI_READ_CMD 0x3
#define SPI_ADDR_2_MASK 0xFF0000
#define SPI_ADDR_2_SHIFT 16
#define SPI_ADDR_1_MASK 0x00FF00
#define SPI_ADDR_1_SHIFT 8
#define SPI_ADDR_0_MASK 0x0000FF
SPISettings memSettings(20000000, MSBFIRST, SPI_MODE0);
const int cs0pin = SPI0_CS_PIN;
BAGpio gpio; // access to User LED
BASpiMemoryDMA spiMem0(SpiDeviceId::SPI_DEVICE0);
bool compareBuffers(uint8_t *a, uint8_t *b, size_t numBytes)
{
bool pass=true;
int errorCount = 0;
for (size_t i=0; i<numBytes; i++) {
if (a[i] != b[i]) {
if (errorCount < 10) {
Serial.print(i); Serial.print(":: a:"); Serial.print(a[i]); Serial.print(" does not match b:"); Serial.println(b[i]);
pass=false;
errorCount++;
} else { return false; }
}
}
return pass;
}
bool compareBuffers16(uint16_t *a, uint16_t *b, size_t numWords)
{
return compareBuffers(reinterpret_cast<uint8_t *>(a), reinterpret_cast<uint8_t*>(b), sizeof(uint16_t)*numWords);
}
size_t SPI_MAX_ADDR;
void setup() {
TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using.
//TGA_PRO_REVB(x);
//TGA_PRO_REVA(x);
gpio.begin();
Serial.begin(57600);
while (!Serial) { yield(); }
delay(5);
SPI_MEM0_1M();
SPI_MAX_ADDR = BAHardwareConfig.getSpiMemMaxAddr(MemSelect::MEM0);
Serial.printf("Enabling SPI, testing MEM0 up to addres %08X\n\r", SPI_MAX_ADDR);
spiMem0.begin();
}
bool spi8BitTest(void) {
size_t spiAddress = 0;
int spiPhase = 0;
constexpr uint8_t MASK80 = 0xaa;
constexpr uint8_t MASK81 = 0x55;
uint8_t src8[DMA_SIZE];
uint8_t dest8[DMA_SIZE];
// Write to the memory using 8-bit transfers
Serial.println("\nStarting 8-bit test Write/Read");
while (spiPhase < 4) {
spiAddress = 0;
while (spiAddress <= SPI_MAX_ADDR) {
// fill the write data buffer
switch (spiPhase) {
case 0 :
for (int i=0; i<DMA_SIZE; i++) {
src8[i] = ( (spiAddress+i) & 0xff) ^ MASK80;
}
break;
case 1 :
for (int i=0; i<DMA_SIZE; i++) {
src8[i] = ((spiAddress+i) & 0xff) ^ MASK81;
}
break;
case 2 :
for (int i=0; i<DMA_SIZE; i++) {
src8[i] = ((spiAddress+i) & 0xff) ^ (!MASK80);
}
break;
case 3 :
for (int i=0; i<DMA_SIZE; i++) {
src8[i] = ((spiAddress+i) & 0xff) ^ (!MASK81);
}
break;
}
// Send the DMA transfer
spiMem0.write(spiAddress, src8, DMA_SIZE);
// wait until write is done
while (spiMem0.isWriteBusy()) {}
spiAddress += DMA_SIZE;
}
// Read back the data using 8-bit transfers
spiAddress = 0;
while (spiAddress <= SPI_MAX_ADDR) {
// generate the golden data
switch (spiPhase) {
case 0 :
for (int i=0; i<DMA_SIZE; i++) {
src8[i] = ( (spiAddress+i) & 0xff) ^ MASK80;
}
break;
case 1 :
for (int i=0; i<DMA_SIZE; i++) {
src8[i] = ((spiAddress+i) & 0xff) ^ MASK81;
}
break;
case 2 :
for (int i=0; i<DMA_SIZE; i++) {
src8[i] = ((spiAddress+i) & 0xff) ^ (!MASK80);
}
break;
case 3 :
for (int i=0; i<DMA_SIZE; i++) {
src8[i] = ((spiAddress+i) & 0xff) ^ (!MASK81);
}
break;
}
// Read back the DMA data
spiMem0.read(spiAddress, dest8, DMA_SIZE);
// wait until read is done
while (spiMem0.isReadBusy()) {}
if (!compareBuffers(src8, dest8, DMA_SIZE)) {
Serial.println(String("ERROR @") + spiAddress);
return false; } // stop the test
spiAddress += DMA_SIZE;
}
Serial.println(String("Phase ") + spiPhase + String(": 8-bit Write/Read test passed!"));
spiPhase++;
}
#ifdef SANITY
for (int i=0; i<DMA_SIZE; i++) {
Serial.print(src8[i], HEX); Serial.print("="); Serial.println(dest8[i],HEX);
}
#endif
Serial.println("\nStarting 8-bit test Zero/Read");
// Clear the memory
spiAddress = 0;
memset(src8, 0, DMA_SIZE);
while (spiAddress <= SPI_MAX_ADDR) {
// Send the DMA transfer
spiMem0.zero(spiAddress, DMA_SIZE);
// wait until write is done
while (spiMem0.isWriteBusy()) {}
spiAddress += DMA_SIZE;
}
// Check the memory is clear
spiAddress = 0;
while (spiAddress <= SPI_MAX_ADDR) {
// Read back the DMA data
spiMem0.read(spiAddress, dest8, DMA_SIZE);
// wait until read is done
while (spiMem0.isReadBusy()) {}
if (!compareBuffers(src8, dest8, DMA_SIZE)) { return false; } // stop the test
spiAddress += DMA_SIZE;
}
Serial.println(String(": 8-bit Zero/Read test passed!"));
return true;
}
bool spi16BitTest(void) {
size_t spiAddress = 0;
int spiPhase = 0;
constexpr uint16_t MASK160 = 0xaaaa;
constexpr uint16_t MASK161 = 0x5555;
constexpr int NUM_DATA = DMA_SIZE / sizeof(uint16_t);
uint16_t src16[NUM_DATA];
uint16_t dest16[NUM_DATA];
// Write to the memory using 16-bit transfers
Serial.println("\nStarting 16-bit test");
while (spiPhase < 4) {
spiAddress = 0;
while (spiAddress <= SPI_MAX_ADDR) {
// fill the write data buffer
switch (spiPhase) {
case 0 :
for (int i=0; i<NUM_DATA; i++) {
src16[i] = ( (spiAddress+i) & 0xffff) ^ MASK160;
}
break;
case 1 :
for (int i=0; i<NUM_DATA; i++) {
src16[i] = ((spiAddress+i) & 0xffff) ^ MASK161;
}
break;
case 2 :
for (int i=0; i<NUM_DATA; i++) {
src16[i] = ((spiAddress+i) & 0xffff) ^ (!MASK160);
}
break;
case 3 :
for (int i=0; i<NUM_DATA; i++) {
src16[i] = ((spiAddress+i) & 0xffff) ^ (!MASK161);
}
break;
}
// Send the DMA transfer
spiMem0.write16(spiAddress, src16, NUM_DATA);
// wait until write is done
while (spiMem0.isWriteBusy()) {}
spiAddress += DMA_SIZE;
}
// Read back the data using 8-bit transfers
spiAddress = 0;
while (spiAddress <= SPI_MAX_ADDR) {
// generate the golden data
switch (spiPhase) {
case 0 :
for (int i=0; i<NUM_DATA; i++) {
src16[i] = ( (spiAddress+i) & 0xffff) ^ MASK160;
}
break;
case 1 :
for (int i=0; i<NUM_DATA; i++) {
src16[i] = ((spiAddress+i) & 0xffff) ^ MASK161;
}
break;
case 2 :
for (int i=0; i<NUM_DATA; i++) {
src16[i] = ((spiAddress+i) & 0xffff) ^ (!MASK160);
}
break;
case 3 :
for (int i=0; i<NUM_DATA; i++) {
src16[i] = ((spiAddress+i) & 0xffff) ^ (!MASK161);
}
break;
}
// Read back the DMA data
spiMem0.read16(spiAddress, dest16, NUM_DATA);
// wait until read is done
while (spiMem0.isReadBusy()) {}
if (!compareBuffers16(src16, dest16, NUM_DATA)) {
Serial.print("ERROR @"); Serial.println(spiAddress, HEX);
return false; } // stop the test
spiAddress += DMA_SIZE;
}
Serial.println(String("Phase ") + spiPhase + String(": 16-bit test passed!"));
spiPhase++;
}
#ifdef SANITY
for (int i=0; i<NUM_DATA; i++) {
Serial.print(src16[i], HEX); Serial.print("="); Serial.println(dest16[i],HEX);
}
#endif
Serial.println("\nStarting 16-bit test Zero/Read");
// Clear the memory
spiAddress = 0;
memset(src16, 0, DMA_SIZE);
while (spiAddress <= SPI_MAX_ADDR) {
// Send the DMA transfer
spiMem0.zero16(spiAddress, NUM_DATA);
// wait until write is done
while (spiMem0.isWriteBusy()) {}
spiAddress += DMA_SIZE;
}
// Check the memory is clear
spiAddress = 0;
while (spiAddress <= SPI_MAX_ADDR) {
// Read back the DMA data
spiMem0.read16(spiAddress, dest16, NUM_DATA);
// wait until read is done
while (spiMem0.isReadBusy()) {}
if (!compareBuffers16(src16, dest16, NUM_DATA)) { return false; } // stop the test
spiAddress += DMA_SIZE;
}
Serial.println(String(": 16-bit Zero/Read test passed!"));
return true;
}
void loop() {
spi8BitTest();
spi16BitTest();
Serial.println("\nTEST DONE!");
while(true) {}
}