Teensy 4.0 First Beta Test

Status
Not open for further replies.
I did a CodeCompare - you removed a few #ifdef's and such across a few files - added to imxrt.h. I'm still using the Free version - someone here pointed me to it. After I scanned I overwrote my prior files so I can't repeat.

If you trust that you can install and point to your folder and the copy you got from Mike and it will show each changed file and then opening that puts them side by side in DIFF view.
 
As Frank said, with your core it works fine. Right now I reinstalled b8, just in case, and then give it a test. If it doesn't work going to replace imxrt.h and try again. Then it will have to be code compare to see the differences in the core.

EDIT. Nope. Still failed on a clean install of b8. If you just replace imxrt.h with your core imxrt.h it throws a bunch of multiple definition errors. So on to codecompare
 
FlexIO SPI - Now support for DMA/Async transfers...

I now have an implementation of the transfers that uses DMA. I have it all setup using same API as normal SPI:

Code:
bool transfer(const void *txBuffer, void *rxBuffer, size_t count,  EventResponderRef  event_responder);

Yep using @Frank B's favorite EventResponder ;)

Test App modified to use this...

The only real changes I needed to make to test app to use the FLEX one was to define it and set the SPIT define to it.

The only exception is that on beginTransaction(...) I had to edit using SPISettings to FlexSPISettings as the handling of the data is different. Tempted to update the SPISettings object to remember the settings and allow you to query them, and then I could just use it...



Code:
#include <FlexIO_t4.h>
#include <FlexSPI.h>
#include <EventResponder.h>

FlexSPI SPIFLEX(2, 3, 4, -1); // Setup on (int mosiPin, int misoPin, int sckPin, int csPin=-1) :

#define SPIT SPIFLEX
#define DBGSerial Serial4
#define CS_PIN 6
#define SMALL_TRANSFER_SIZE 128
//#define BUFFER_SIZE 70000 //(320*240*2) // size of ILI9341 display... 
#define BUFFER_SIZE 0x12000l   // More than 64K
//uint8_t buffer[BUFFER_SIZE];
uint8_t *buffer;  // lets malloc it...
//uint8_t rxBuffer[SMALL_TRANSFER_SIZE];
DMAMEM uint8_t rxBuffer[BUFFER_SIZE];
//uint8_t *rxBuffer;
uint8_t *foo_bar = nullptr;
uint8_t static_buffer[16];

EventResponder event;
volatile bool event_happened = false;
void asyncEventResponder(EventResponderRef event_responder)
{
  digitalWriteFast(CS_PIN, HIGH);
  event_happened = true;
}

void setup() {
  // debug pins
  uint8_t stack_buffer[10];
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
extern unsigned long _heap_start;
extern unsigned long _heap_end;

  pinMode(CS_PIN, OUTPUT);
  digitalWriteFast(CS_PIN, HIGH);
  while (!Serial && millis() < 4000) ;  // wait for Serial port
  DBGSerial.begin(115200);
  SPIT.begin();
  DBGSerial.println("SPI Test program");

  buffer = (uint8_t *)malloc(BUFFER_SIZE);
  //rxBuffer = (uint8_t *)malloc(BUFFER_SIZE);

  DBGSerial.print("Buffer: ");
  DBGSerial.print((uint32_t)buffer, HEX);
  DBGSerial.print(" RX Buffer: ");
  DBGSerial.print((uint32_t)rxBuffer, HEX);
  DBGSerial.print(" ");
  DBGSerial.println(BUFFER_SIZE, DEC);
  DBGSerial.printf("Static buffer: %x, Stack Buffer: %x\n", (uint32_t)static_buffer, (uint32_t)stack_buffer);
  DBGSerial.printf("Heap Start: %x, Heap End: %x\n", (uint32_t)&_heap_start, (uint32_t)&_heap_end);
  event.attachImmediate(&asyncEventResponder);
}

void loop() {
  // put your main code here, to run repeatedly:
  while (DBGSerial.read() != -1) ; // Make sure queue is empty.
  DBGSerial.println("Press any key to run test");
  while (!DBGSerial.available()) ; // will loop until it receives something
  while (DBGSerial.read() != -1) ; // loop until queue is empty
  DBGSerial.println("Ready to start tests");

  SPIT.beginTransaction(FlexSPISettings(8000000, MSBFIRST, SPI_MODE0));
  DBGSerial.println("After Begin Transaction");

  //=================================================================
  // Transfer Sync
  //=================================================================


  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Transfer Small"); //DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, rxBuffer, SMALL_TRANSFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  DBGSerial.println("*** Completed ***"); DBGSerial.flush();
  dumpBuffer(buffer, SMALL_TRANSFER_SIZE);
  DBGSerial.println();
  dumpBuffer(rxBuffer, SMALL_TRANSFER_SIZE);
  validateTXBuffer(0);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  DBGSerial.println("write Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, NULL, SMALL_TRANSFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  DBGSerial.println("*** Completed ***"); DBGSerial.flush();
  validateTXBuffer(0);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  DBGSerial.println("read Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(NULL, rxBuffer, SMALL_TRANSFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  DBGSerial.println("*** Completed ***"); DBGSerial.flush();
  dumpBuffer(rxBuffer, SMALL_TRANSFER_SIZE);
  delay(5);

  SPIT.beginTransaction(FlexSPISettings(2000000, MSBFIRST, SPI_MODE0));
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)buffer[i] = i / 1024;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;

  DBGSerial.println("Transfer Full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, rxBuffer, BUFFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  validateTXBuffer(1);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i / 1024;
  DBGSerial.println("write full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, NULL, BUFFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  validateTXBuffer(1);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  DBGSerial.println("read full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(NULL, buffer, BUFFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  delay(5);
  //=================================================================
  // Transfer Async
  //=================================================================
  for (uint32_t i = 0; i < 5; i++) {
    digitalWriteFast(CS_PIN, LOW);
    delay(1);
    digitalWriteFast(CS_PIN, HIGH);
    delay(1);
  }
  event_happened = false;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  DBGSerial.println("Async write Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, NULL, SMALL_TRANSFER_SIZE, event);
  DBGSerial.println("After write call, waiting for event");
  while (!event_happened) ;
  event_happened = false;
  validateTXBuffer(0);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Async Transfer Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, rxBuffer, SMALL_TRANSFER_SIZE, event);
  DBGSerial.println("After Transfer call, waiting for event");
  while (!event_happened) ;
  event_happened = false;
  dumpBuffer(buffer, SMALL_TRANSFER_SIZE);
  DBGSerial.println();
  dumpBuffer(rxBuffer, SMALL_TRANSFER_SIZE);
  validateTXBuffer(0);
  delay(5);


  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Async read Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.setTransferWriteFill(0x42);
  SPIT.transfer(NULL, rxBuffer, SMALL_TRANSFER_SIZE, event);
  //arm_dcache_delete(rxBuffer, SMALL_TRANSFER_SIZE);
  while (!event_happened) ;
  event_happened = false;
  dumpBuffer(rxBuffer, SMALL_TRANSFER_SIZE);
  validateTXBuffer(0);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i / 1024;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Async Transfer Full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, rxBuffer, BUFFER_SIZE, event);
  while (!event_happened) ;
  event_happened = false;
  dumpBuffer(rxBuffer, 512);
  validateTXBuffer(1);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i / 1024;
  DBGSerial.println("Async write full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, NULL, BUFFER_SIZE, event);
  while (!event_happened) ;
  event_happened = false;
  validateTXBuffer(1);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Async read full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(NULL, rxBuffer, BUFFER_SIZE, event);
  while (!event_happened) ;
  event_happened = false;
  dumpBuffer(rxBuffer, 512);
  validateTXBuffer(0);
  delay(5);


  DBGSerial.println("Tests completed");
  SPIT.endTransaction();
}

void dumpBuffer(uint8_t *pb, int cb) {
  uint8_t i = 0;
  while (cb) {
    DBGSerial.print(*pb++, HEX);
    cb--;
    DBGSerial.print(" ");
    i++;
    if (i == 16) {
      DBGSerial.println();
      i = 0;
    }
  }
  DBGSerial.println();
}
void validateTXBuffer(uint8_t test)
{
  uint8_t error_count = 0;
  for (int i = 0; i < BUFFER_SIZE; i++) {
    if (((test == 0) && (buffer[i] != (i & 0xff)))
        || ((test == 1) && (buffer[i] != (i / 1024)))) {
      DBGSerial.print("Tx Buffer validate failed Index: ");
      DBGSerial.print(i, DEC);
      DBGSerial.print(" Value: ");
      DBGSerial.println(buffer[i], HEX);
      error_count++;
      if (error_count == 10)
        break;
    }
  }
}

But again, how much more to do on this it may depend on if this library will live much longer or not...
@Paul - wondering for example should I merge in some of this into core? Example:
Should the structure:
Code:
typedef struct {
	const 	uint32_t VERID;				// 0x00	(IMXRT_FLEXIO1.offset000)
	volatile uint32_t PARAM;			// 0x04	// (IMXRT_FLEXIO1.offset004)
	volatile uint32_t CTRL;				// 0x08(IMXRT_FLEXIO1.offset008)
	volatile uint32_t PIN;				// 0x0c (IMXRT_FLEXIO1.offset00C)
	volatile uint32_t SHIFTSTAT;		// 0x10 (IMXRT_FLEXIO1.offset010)
	volatile uint32_t SHIFTERR;			// 0x14(IMXRT_FLEXIO1.offset014)
	volatile uint32_t TIMSTAT;			// 0x18 (IMXRT_FLEXIO1.offset018)
	const	uint32_t UNUSED0;			// 0x1c
	volatile uint32_t SHIFTSIEN;		// 0x20 (IMXRT_FLEXIO1.offset020)
	volatile uint32_t SHIFTEIEN;		// 0x24 (IMXRT_FLEXIO1.offset024)
	volatile uint32_t TIMIEN;			// 0x28 (IMXRT_FLEXIO1.offset028)
	const	uint32_t UNUSED1;			// 0x2c
	volatile uint32_t SHIFTSDEN;		// 0x30 (IMXRT_FLEXIO1.offset030)
	const	uint32_t UNUSED2[3];		// 0x34 38 3C
	volatile uint32_t SHIFTSTATE;		// 0x40 (IMXRT_FLEXIO1.offset040)
	const	uint32_t UNUSED3[15];		// 0x44..  50... 60... 70...
	volatile uint32_t SHIFTCTL[4];		// 0x80 84 88 8C
	const	uint32_t UNUSED4[28];		// 0x90 - 0xfc
	volatile uint32_t SHIFTCFG[4];		// 0x100 104 108 10C (IMXRT_FLEXIO1.offset100)
	const	uint32_t UNUSED5[60];		// 0x110 - 0x1FC
	volatile uint32_t SHIFTBUF[4];		// 0x200 204 208 20c (IMXRT_FLEXIO1.offset200)
	const	uint32_t UNUSED6[28];		// 
	volatile uint32_t SHIFTBUFBIS[4];	// 0x280	// (IMXRT_FLEXIO1.offset280)
	const	uint32_t UNUSED7[28];		// 
	volatile uint32_t SHIFTBUFBYS[4];	// 0x300 (IMXRT_FLEXIO1.offset300)
	const	uint32_t UNUSED8[28];		// 
	volatile uint32_t SHIFTBUFBBS[4];	// 0x380 (IMXRT_FLEXIO1.offset380)
	const	uint32_t UNUSED9[28];		// 
	volatile uint32_t TIMCTL[4];		// 0x400 
	const	uint32_t UNUSED10[28];		// 
	volatile uint32_t TIMCFG[4];		// 0x480
	const	uint32_t UNUSED11[28];		// 
	volatile uint32_t TIMCMP[4];		// 0x500
	const	uint32_t UNUSED12[28+64];	// 
	volatile uint32_t SHIFTBUFNBS[4];	// 0x680
	const	uint32_t UNUSED13[28];		// 
	volatile uint32_t SHIFTBUFHWS[4];	// 0x700
	const	uint32_t UNUSED14[28];		// 
	volatile uint32_t SHIFTBUFNIS[4];	// 0x780
} IMXRT_FLEXIO_t;

#define IMXRT_FLEXIO1_S		(*(IMXRT_FLEXIO_t *)0x401AC000)
#define IMXRT_FLEXIO2_S		(*(IMXRT_FLEXIO_t *)0x401B0000)
//#define IMXRT_FLEXIO3		(*(IMXRT_REGISTER32_t *)0x42020000) only RT1062

Be merged into cores (imxrt.h)? Like I did for the SPI object and hardware serial objects?
 
Frank

I just did a code compare the only file differences were for audio in the core and the imxrt.h file.

Do we need to update the imxrt.h file as well?

EDIT: Just tried Zelda without the imxrt.h update. Worked like a charm. So guess we are now all on the same page :)

Thanks Frank and Tim

EDIT: Tried a Zelda, playsyntmusic and waveforms_modulated. They all work. For simpleDrum sketch it prints on the sermon:
Code:
Diagnostics: 0 5
 
Last edited:
To be sure, yes..
And I just updated on github the rest of the audio-lib too, to make sure you have the same version....

My plan was to make i2s input working this evening, but it's too late now. The newest version has already some work for input, but does not work at the moment. I stopped esterday at the point that i made my edits and soldered the microphone... :) well, current problem with input is, "all seems to work, but.." the microphone skecth from the tutorial does not work. LA shows a signal on the t4-RX, interrupts work, DMA works and is receiving "something" (did not check, what exactly), so I think it's a minor thing missing. Have not found the missing part/bug, yet. maybe tomorrow... or one of you find the missing thing? :)
 
@Frank
I had started on input before all this started - going to compare what I started to what you have. Who knows - maybe I will see something.
 
FlexIO SPI - Now support for DMA/Async transfers...

I now have an implementation of the transfers that uses DMA. I have it all setup using same API as normal SPI:
Kurt,
I fetched your latest from gtihub and i'm running beta8. I see nothing on scope or serial monitor. I tried my earlier sketch, i tried your flexspi_simple example, and your big DMA sketch you posted here. Nothing ... ??? (I'm not using Serial4, just Serial)
 
Kurt,
I fetched your latest from gtihub and i'm running beta8. I see nothing on scope or serial monitor. I tried my earlier sketch, i tried your flexspi_simple example, and your big DMA sketch you posted here. Nothing ... ??? (I'm not using Serial4, just Serial)

Maybe try changing flexSPI.cpp and disable the debug output: Comment out Line 5 Or change to Serial...

However one issue is the sketch has defined Serial4 is the DBGSerial...

I went to this as I also have at the start of the loop:
Code:
void loop() {
  // put your main code here, to run repeatedly:
  while (DBGSerial.read() != -1) ; // Make sure queue is empty.
  DBGSerial.println("Press any key to run test");
  while (!DBGSerial.available()) ; // will loop until it receives something
  while (DBGSerial.read() != -1) ; // loop until queue is empty
  DBGSerial.println("Ready to start tests");
And the Serial (USB) would die on me if I tried to do input... So I went to a Hardware Serial port.

Obviously it would not be hard, to edit to get the loop to start either automatically or by pressing a button or...

UPDATE
Here is an updated sketch which appears to run with the debug stuff turned off as mentioned above, plus edited to output to Serial, and setup a logical button on pin 23, which I have tested running jumper from it to gnd to trigger the next run...

Code:
#include <Bounce.h>

#include <FlexIO_t4.h>
#include <FlexSPI.h>
#include <EventResponder.h>

#define BUTTON 23
FlexSPI SPIFLEX(2, 3, 4, -1); // Setup on (int mosiPin, int misoPin, int sckPin, int csPin=-1)
Bounce bounce (BUTTON, 5);

#define SPIT SPIFLEX
#define DBGSerial Serial
#define CS_PIN 6
#define SMALL_TRANSFER_SIZE 128
//#define BUFFER_SIZE 70000 //(320*240*2) // size of ILI9341 display... 
#define BUFFER_SIZE 0x12000l   // More than 64K
//uint8_t buffer[BUFFER_SIZE];
uint8_t *buffer;  // lets malloc it...
//uint8_t rxBuffer[SMALL_TRANSFER_SIZE];
DMAMEM uint8_t rxBuffer[BUFFER_SIZE];
//uint8_t *rxBuffer;
uint8_t *foo_bar = nullptr;
uint8_t static_buffer[16];

EventResponder event;
volatile bool event_happened = false;
void asyncEventResponder(EventResponderRef event_responder)
{
  digitalWriteFast(CS_PIN, HIGH);
  event_happened = true;
}

void setup() {
  // debug pins
  uint8_t stack_buffer[10];
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
extern unsigned long _heap_start;
extern unsigned long _heap_end;

  pinMode(BUTTON, INPUT_PULLUP);
  
  pinMode(CS_PIN, OUTPUT);
  digitalWriteFast(CS_PIN, HIGH);
  while (!DBGSerial && millis() < 4000) ;  // wait for Serial port
  DBGSerial.begin(115200);
  SPIT.begin();
  DBGSerial.println("SPI Test program");

  buffer = (uint8_t *)malloc(BUFFER_SIZE);
  //rxBuffer = (uint8_t *)malloc(BUFFER_SIZE);

  DBGSerial.print("Buffer: ");
  DBGSerial.print((uint32_t)buffer, HEX);
  DBGSerial.print(" RX Buffer: ");
  DBGSerial.print((uint32_t)rxBuffer, HEX);
  DBGSerial.print(" ");
  DBGSerial.println(BUFFER_SIZE, DEC);
  DBGSerial.printf("Static buffer: %x, Stack Buffer: %x\n", (uint32_t)static_buffer, (uint32_t)stack_buffer);
  DBGSerial.printf("Heap Start: %x, Heap End: %x\n", (uint32_t)&_heap_start, (uint32_t)&_heap_end);
  event.attachImmediate(&asyncEventResponder);
}

void loop() {
  // put your main code here, to run repeatedly:
  bounce.update();
  int bounce_value = bounce.read();
  while ((DBGSerial.read() != -1) && (bounce_value))  {
    bounce.update();
    bounce_value = bounce.read();
  }
  DBGSerial.println("Press any key to run test");
  while ((DBGSerial.read() == -1) && (bounce_value))  {
    bounce.update();
    bounce_value = bounce.read();
  }
  if (bounce_value) {
    while (DBGSerial.read() != -1) ; // loop until queue is empty
  }
  DBGSerial.println("Ready to start tests");

  SPIT.beginTransaction(FlexSPISettings(8000000, MSBFIRST, SPI_MODE0));
  DBGSerial.println("After Begin Transaction");

  //=================================================================
  // Transfer Sync
  //=================================================================


  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Transfer Small"); //DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, rxBuffer, SMALL_TRANSFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  DBGSerial.println("*** Completed ***"); DBGSerial.flush();
  dumpBuffer(buffer, SMALL_TRANSFER_SIZE);
  DBGSerial.println();
  dumpBuffer(rxBuffer, SMALL_TRANSFER_SIZE);
  validateTXBuffer(0);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  DBGSerial.println("write Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, NULL, SMALL_TRANSFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  DBGSerial.println("*** Completed ***"); DBGSerial.flush();
  validateTXBuffer(0);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  DBGSerial.println("read Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(NULL, rxBuffer, SMALL_TRANSFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  DBGSerial.println("*** Completed ***"); DBGSerial.flush();
  dumpBuffer(rxBuffer, SMALL_TRANSFER_SIZE);
  delay(5);

  SPIT.beginTransaction(FlexSPISettings(2000000, MSBFIRST, SPI_MODE0));
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)buffer[i] = i / 1024;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;

  DBGSerial.println("Transfer Full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, rxBuffer, BUFFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  validateTXBuffer(1);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i / 1024;
  DBGSerial.println("write full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, NULL, BUFFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  validateTXBuffer(1);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  DBGSerial.println("read full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(NULL, buffer, BUFFER_SIZE);
  digitalWriteFast(CS_PIN, HIGH);
  delay(5);
  //=================================================================
  // Transfer Async
  //=================================================================
  for (uint32_t i = 0; i < 5; i++) {
    digitalWriteFast(CS_PIN, LOW);
    delay(1);
    digitalWriteFast(CS_PIN, HIGH);
    delay(1);
  }
  event_happened = false;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  DBGSerial.println("Async write Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, NULL, SMALL_TRANSFER_SIZE, event);
  DBGSerial.println("After write call, waiting for event");
  while (!event_happened) ;
  event_happened = false;
  validateTXBuffer(0);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Async Transfer Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, rxBuffer, SMALL_TRANSFER_SIZE, event);
  DBGSerial.println("After Transfer call, waiting for event");
  while (!event_happened) ;
  event_happened = false;
  dumpBuffer(buffer, SMALL_TRANSFER_SIZE);
  DBGSerial.println();
  dumpBuffer(rxBuffer, SMALL_TRANSFER_SIZE);
  validateTXBuffer(0);
  delay(5);


  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Async read Small"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.setTransferWriteFill(0x42);
  SPIT.transfer(NULL, rxBuffer, SMALL_TRANSFER_SIZE, event);
  //arm_dcache_delete(rxBuffer, SMALL_TRANSFER_SIZE);
  while (!event_happened) ;
  event_happened = false;
  dumpBuffer(rxBuffer, SMALL_TRANSFER_SIZE);
  validateTXBuffer(0);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i / 1024;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Async Transfer Full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, rxBuffer, BUFFER_SIZE, event);
  while (!event_happened) ;
  event_happened = false;
  dumpBuffer(rxBuffer, 512);
  validateTXBuffer(1);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i / 1024;
  DBGSerial.println("Async write full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(buffer, NULL, BUFFER_SIZE, event);
  while (!event_happened) ;
  event_happened = false;
  validateTXBuffer(1);
  delay(5);

  for (uint32_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i & 0xff;
  for (uint32_t i = 0; i < BUFFER_SIZE; i++)  rxBuffer[i] = 0x5a;
  DBGSerial.println("Async read full"); DBGSerial.flush();
  digitalWriteFast(CS_PIN, LOW);
  SPIT.transfer(NULL, rxBuffer, BUFFER_SIZE, event);
  while (!event_happened) ;
  event_happened = false;
  dumpBuffer(rxBuffer, 512);
  validateTXBuffer(0);
  delay(5);


  DBGSerial.println("Tests completed");
  SPIT.endTransaction();
}

void dumpBuffer(uint8_t *pb, int cb) {
  uint8_t i = 0;
  while (cb) {
    DBGSerial.print(*pb++, HEX);
    cb--;
    DBGSerial.print(" ");
    i++;
    if (i == 16) {
      DBGSerial.println();
      i = 0;
    }
  }
  DBGSerial.println();
}
void validateTXBuffer(uint8_t test)
{
  uint8_t error_count = 0;
  for (int i = 0; i < BUFFER_SIZE; i++) {
    if (((test == 0) && (buffer[i] != (i & 0xff)))
        || ((test == 1) && (buffer[i] != (i / 1024)))) {
      DBGSerial.print("Tx Buffer validate failed Index: ");
      DBGSerial.print(i, DEC);
      DBGSerial.print(" Value: ");
      DBGSerial.println(buffer[i], HEX);
      error_count++;
      if (error_count == 10)
        break;
    }
  }
}
I also pushed up change to turn off debug output
 
Last edited:
Kurt,
OK commenting out debug stuff got simple sketch running. I still get errors requesting SPI CLK of 15mhz with flex clock @30mhz. no errors for slower SPI CLK speedsl
Code:
Updated Flex IO speed: 30000000
SPIHZ 15000000
547 us 15.0 mbs
errs 1023 [3] 1
0  0 0
1  1 0
2  2 129
3  3 1
4  4 130
500  244 250
501  245 122
502  246 251
503  247 123
504  248 252
1020  252 254
1021  253 126
1022  254 255
1023  255 127
scope shows pin 4 running at 14.7 mhz
 
To be sure, yes..
And I just updated on github the rest of the audio-lib too, to make sure you have the same version....

My plan was to make i2s input working this evening, but it's too late now. The newest version has already some work for input, but does not work at the moment. I stopped esterday at the point that i made my edits and soldered the microphone... :) well, current problem with input is, "all seems to work, but.." the microphone skecth from the tutorial does not work. LA shows a signal on the t4-RX, interrupts work, DMA works and is receiving "something" (did not check, what exactly), so I think it's a minor thing missing. Have not found the missing part/bug, yet. maybe tomorrow... or one of you find the missing thing? :)

Frank
I bounced what you did against what I previously started and its pretty close to the same except where you have i2s1 (in input) I was trying to use i2s0. I put a scope on rx and was receiving a signal that pretty much looked like the signal when I was just play synth music. The exception is that I didn't see anything on the TX pin. Can't figure out where the input from i2s1 is linked to i2s2?

EDIT: Doing a little more digging and comparing implementations - in input_i2s I don't see where update is called to transmit the blocks? I am reading this right?
 
Last edited:
As Frank said, with your core it works fine. Right now I reinstalled b8, just in case, and then give it a test. If it doesn't work going to replace imxrt.h and try again. Then it will have to be code compare to see the differences in the core.

EDIT. Nope. Still failed on a clean install of b8. If you just replace imxrt.h with your core imxrt.h it throws a bunch of multiple definition errors. So on to codecompare

I saw the redefine warnings as well - they looked like duplicates from what I saw so I skipped that. Mike going to a fresh B8 and then CodeCompare would show what is different against Frank's - unless Frank does that on his system against what you uploaded.

In the sanity check I did - to make sure I save my local edits - I saw some #ifdef for other MCU's go away
 
I saw the redefine warnings as well - they looked like duplicates from what I saw so I skipped that. Mike going to a fresh B8 and then CodeCompare would show what is different against Frank's - unless Frank does that on his system against what you uploaded.

In the sanity check I did - to make sure I save my local edits - I saw some #ifdef for other MCU's go away

just comment the defines.. this is all still work in progress, and they are just warnings, not errors.
unfortunately I have to work for my money and don't have always the time to make everything perfect for every update.. :)
Now its Monday again and I have to postpone everthing till tonight.. sry guys. Still haven't found the problem with i2s input, and "slave"-mode is a mess.

edit: There might be more examples or other code for which a PROGMEM would be good. I don't know. Haven't looked at every single file.
 
Last edited:
just comment the defines.. this is all still work in progress, and they are just warnings, not errors.
unfortunately I have to work for my money and don't have always the time to make everything perfect for every update.. :)
Now its Monday again and I have to postpone everthing till tonight.. sry guys. Still haven't found the problem with i2s input, and "slave"-mode is a mess.

edit: There might be more examples or other code for which a PROGMEM would be good. I don't know. Haven't looked at every single file.

Indeed Frank - I wasn't worried about the dupes since they didn't show conflict - a work in progress for sure - and working amazingly well that it is working at all given what I thought would have to be bigger changes.

Fortunate you have work that pays you money :) No need for sry - You have to find the balance … this will be going on for some 'days' :)

To clarify - the set to PROGMEM will bring to slow RAM what would otherwise stay in Flash? So when the T4 powers up that is read from FLASH storage into the PROGMEM area for reference?

Frank - with my Beta_T4 I bought a couple of the PT8211 kits - let me know when I could put one of those to use in testing. I think I got some i2s microphones as well. The most I've done with Audio was one quick pass though the Audio tutorial … before the K66 Beta.
 
I think data and code marked with PROGMEM just stays in the flash. It's not that slow.. should be way faster than serial flash and it gets cached, too. For audio, I don't see any problems.
For init-code and other that doesn't run often and some kind of const data(, or when it is just too large for RAM), PROGMEM is a good way to save RAM.
 
I think data and code marked with PROGMEM just stays in the flash. It's not that slow.. should be way faster than serial flash and it gets cached, too. For audio, I don't see any problems.
For init-code and other that doesn't run often and some kind of const data(, or when it is just too large for RAM), PROGMEM is a good way to save RAM.

Okay - what puzzled me was that I assumed those big things were already marked 'const' so would have been in Flash. And PROGMEM is flash on AVR so thought it would be the same - so I wasn't clear where PROGMEM was on T4.
 
IMG-20190204-WA0001.jpg
Got this thing to play with when audio is working..
 
Frank/Tim

Think I need to change my sleep schedule :)

Anyway. Frank don't be sorry that you have to work. Been retired now three years and sometimes I miss it. Finding the balance between work and life is always challenging.

Tim. I did a compare between a fresh install of b8 and Frank's audio lib as well. The only file that had changes that we didn't update was imxrt.h. Right now everything seems to be running in terms of defines except for one that was in the imxrt_hw.cpp in the utility folder:
Code:
#define CCM_ANALOG_PLL_AUDIO_LOCK	((uint32_t)(1<<31))
which i needed to uncomment otherwise i would get errors.

Frank - this is really the first time i played with audio except for playing files off the sdcard so this is even more challenging as i try and sort through things. Still going to try and figure out the input, now its fustrating. Will check out the examples as well for changes to use PROGMEM.
 
what puzzled me was that I assumed those big things were already marked 'const' so would have been in Flash. And PROGMEM is flash on AVR so thought it would be the same - so I wasn't clear where PROGMEM was on T4.

If you only use const, it gets copied into DTCM for fastest possible access. If you use PROGMEM, it's stored only in the QSPI flash chip.

These aren't an absolutely hard rule about IMXRT. It's merely how I wrote the linker script and startup code. When/if we make a lower-cost board with the RT1015 chip, it'll almost certainly have a different linker script with other trade-offs for the much smaller RAM.
 
Status
Not open for further replies.
Back
Top