Teensy 4.1 Beta Test

The AUTO init of PSRAM has some value - but indeed some issues if those pins are in other use - and it isn't needed for Teensy startup to get to setup().
and current code doesn't get a warm fuzzy confirmation the PSRAM is the right one yet:
Code:
ERAM ID: 0D FD DF FF FF FF FF FF
at 0x 7000000
Wrong ID  :-(

To use current lib for above SD test takes just this simple code when user adds PSRAM:
Code:
#include <extRAM_t4.h>
extRAM_t4 eRAM;
uint8_t config = INIT_PSRAM_ONLY;
// …
void setup() {
	eRAM.begin(config);

Funny thing I moved this SD sketch before PSRAM to T_4.0 { the FRDM 4236 board that looks about the same } to test for another thread.
Then adding above CODE to get eRAM - I compiled a couple of times wondering why it wasn't working and what else I needed … then it worked when I switch to T_4.1

Having eram_malloc() would be a better add. Because this is confusing and UGLY getting the numbers right:
Code:
struct datrec *dbuff0 = (datrec *)0x70050000;
struct datrec *dbuff1 = (datrec *)0x70090000;
 
I hear you, and would agree if they were actually shipped with chips installed.

And we don't currently initialize other hardware, like SD cards or ... So just sort of wondering. The options I currently see for this include:
a) Automatic - More foolproof (maybe) - For RAM I understand for Flash, do you assume that the it will be used as a drive or do you expect that some other user init code will be called?

b) Keep it sort of like today, where maybe the user has to call some method to initialize external memory. We could keep it as external library or bring into core. Nice thing about this is you are flexible and your sketch only takes a code size init time hit if your program actually says it wants to use it.

c) Fault handling? - If the user sketch tries to use the external ram and has not called the init function, could we detect this in fault handler and do it for them...


I think this could be another nice application for adding "-I{build.path}/sketch" to plattform.txt (see here https://forum.pjrc.com/threads/6074...Arduino-sketch?p=238051&viewfull=1#post238051). The core could then read an optional config file from the sketch folder, in which such and other configuration stuff could be defined conveniently and in project scope.
 
I think this could be another nice application for adding "-I{build.path}/sketch" to plattform.txt
Or the more general defs.h solution which allows even more ;)

Luni, both will not happen.
Me and a few others are suggesting these things since years - without any reaction from Paul. Not even a "No, because...<insert reason here>".

:)

I hope new versions will - at least - not overwrite my changes in the future.
But I don't see much chance for that either. Not worth to write lenghty posts about it. I gave that up.
 
Or the more general defs.h solution which allows even more ;)

Don't let yourself get frustrated, at the end of the day this is all just fun. :)

Anyway, where can I read about your 'def.h' thing?
 
Last edited:
Sadly, since packaging up 1.52-beta4, nearly every available hour this week has been prepping to release the product (soon-ish). Haven't had time to do any software stuff since beta4.

Planning to add the PSRAM auto-init and fix audio ADC on Teensy 3 (dunno how that slipped in... I tested it many times on both boards) on Saturday. Might get to the malloc thing, might not. I still have a long list of urgent things to complete before we can release the product.
If we have a generic heap alloc, where we pass in which heap or like ESP32 where you pass in attributes desired, we could have 3 heaps, ram, dmamem,extmem... and potentially only init one of these like extmem, if user asks for it... just a thought
 
If we have a generic heap alloc, where we pass in which heap or like ESP32 where you pass in attributes desired, we could have 3 heaps, ram, dmamem,extmem... and potentially only init one of these like extmem, if user asks for it... just a thought

Or a more clever one which uses all three automagically..
Nice Idea, Kurt.
 
Using the Teensy 4.1, I just tested quad audio out using the two Teensy Audio Shields. Success!

Interestingly, I was not able to get it to work using flying leads. I had to stack the boards (cutting the traces and whatnot, as required) in order for this to work. I was able to use flying leads for T3.6 and T4.0. I don't know why it wouldn't work with T4.1. User error is the best explanation, but unsatisfying.

So far, I've only tested the audio output, not input. Still, it's nice to see that the quad works.

Here are the mods required for the second audio shield:

* Cut the trace between the two pads for the audio board's RX (Pin 7)
* Cut the tracce between the two pads for the audio board's TX (Pin 8)
* Add a wire from pin 6 over to the pad that had been connected to pin 8
* Add a wire from pin 32 to the pad that had been connected to pin 7
* Cut the trace between the 3 pads that set the audio sheild's address (was LOW)
* Solder-bridge the center pad to the other pad (sets the address to HIGH)

Here is the ToneSweep code that made audio on all four output channels:

Code:
/*
  Demo of the audio sweep function.
  The user specifies the amplitude,
  start and end frequencies (which can sweep up or down)
  and the length of time of the sweep.
   
  May 2020: Chip Audette (OpenAudio)
    * I tested this with the Teensy 4.1 and two Teensy Audio Shields
    * One shield was unmodified
    * The second shield was modified
      * Cut the trace between the two pads for the audio board's RX (Pin 7) 
      * Cut the tracce between the two pads for the audio board's TX (Pin 8)
      * Add a wire from pin 6 over to the pad that had been connected to pin 8
      * Add a wire from pin 32 to the pad that had been connected to pin 7
      * Cut the trace between the 3 pads that set the audio sheild's address (was LOW)
      * Solder-bridge the center pad to the other pad (sets the address to HIGH)

    * I based this sketch on the standard ToneSweep example
    * I extended for quad audio
    * This only tests the audio output
*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce.h>

AudioSynthToneSweep     myEffect1,myEffect2;
AudioOutputI2SQuad      audioOutput;        // audio shield: headphones & line-out

// The tone sweep goes to left and right channels
AudioConnection         c1(myEffect1, 0, audioOutput, 0);
AudioConnection         c2(myEffect1, 0, audioOutput, 1);
AudioConnection         c3(myEffect2, 0, audioOutput, 2);
AudioConnection         c4(myEffect2, 0, audioOutput, 3);

AudioControlSGTL5000 audioShield1;
AudioControlSGTL5000 audioShield2;


float t_ampx = 0.8;
int t_lox = 10;
int t_hix = 22000;
// Length of time for the sweep in seconds
float t_timex = 5;
// <<<<<<<<<<<<<<>>>>>>>>>>>>>>>>
void setup(void)
{
  
  Serial.begin(9600);
  while (!Serial) ;
  delay(3000);

  AudioMemory(10);

  audioShield1.setAddress(LOW);
  audioShield1.enable();
  audioShield1.volume(0.5);
  
  audioShield2.setAddress(HIGH);
  audioShield2.enable();
  audioShield2.volume(0.5);

  Serial.println("setup done");

  //play upward tone sweep through first audio shield
  Serial.println("Playing tone sweep from FIRST audio shield.");
  if(!myEffect1.play(t_ampx,t_lox,t_hix,t_timex)) {
    Serial.println("AudioSynthToneSweep 1 - begin failed");
    while(1);
  }  
  while(myEffect1.isPlaying());    // wait for the sweep to end

  //play upward tone sweep through the second audio shield
  Serial.println("Playing tone sweep from SECOND audio shield.");
  if(!myEffect2.play(t_ampx,t_lox,t_hix,t_timex)) {
    Serial.println("AudioSynthToneSweep 2 - begin failed");
    while(1);
  }  
  while(myEffect2.isPlaying());    // wait for the sweep to end

  Serial.println("Done");
}

void loop(void)
{
}

FYI, the USB connector on the T4.1 is intermittent when using a sparkfun logo'd USB cable. If you wiggle the cable or if you wiggle the stack of Teensy boards (as happens when you need to plug in some headphones), the system loses power. Jiggle it some more and it comes back on. I'm not saying that it's the T4.1; it could be the cable. But, this cable does seem to work OK with my other Teensy devices.

Next, I'll test the audio inputs. I have to attach some cables, first.

Chip
 
@Kurt- @Frank: I like the idea of Tri Heap alloc - would be nice to have the ability to declare where it is.

Back to PSRAM and SDFat Beta logging - SD FORMATTED exFAT - Code below just gave this:
Code:
skipped 19	236691, 240062026, 2303054275, 0	
skipped 19	[COLOR="#FF0000"]236692[/COLOR], 240063026, 2303654275, 0	
skipped 3	[B]239149[/B], 242520026, 3777854281, 1	 	 ????
skipped 19	239150, 242521026, 3778454268, 1	 	 ????
skipped 19	239151, 242522026, 3779054268, 1	
skipped 19	239152, 242523026, 3779654268, 1	
skipped 19	239153, 242524026, 3780254268, 1	
skipped 19	239154, 242525026, 3780854268, 1	
skipped 19	239155, 242526026, 3781454268, 1	
skipped 19	239156, 242527026, 3782054268, 1	
skipped 19	239157, 242528026, 3782654268, 1	
skipped 19	239158, 242529026, 3783254268, 1	
skipped 19	239159, 242530026, 3783854268, 1	
skipped 19	239160, 242531026, 3784454268, 1	
skipped 19	239161, 242532026, 3785054268, 1	
skipped 19	239162, 242533026, 3785654268, 1	
skipped 19	239163, 242534026, 3786254268, 1	
skipped 19	239164, 242535026, 3786854268, 1	
skipped 8	[COLOR="#FF0000"]236707[/COLOR], 240078676, 2313044275, 0	 	 ????
skipped 6	236708, 240079026, 2313254275, 0	 	 ????
skipped 19	236709, 240080026, 2313854275, 0	 	 ????
skipped 19	236710, 240081026, 2314454275, 0

Code:
Code:
/**************************************************************
  Simple SD card timing datalogger for Teensy 3.6

  https://forum.pjrc.com/threads/60754-Teensy-3-6-SD-Card-missing-time-in-milliseconds?p=238352&viewfull=1#post238352

  This example shows how to log timing data to an SD card using the SD library
  and SDFat 2.0b
  As much as possible, the code uses the simplest Arduino functions, adding
  teensy-specific code only where necessary (such as IntervalTimer).

  The circuit:

   SD card attached to built-in SD Card slot on t3.6


  This example uses  buffering and interval timer to collect at regular
  intervals without collection timing jitter caused by SDC writes.
  A time stamp is saved with each record.

  A minimal user interface is added with three one-letter commands:
      'r'   Open file and start recording data with verbose output
      'g'   Open file and start recording data with only block write delay output
      'q'   Quit logging data and close file
      'p'   Play back data in CSV format


  NOTES:
    1. Unlike the Simple Logger, this version saves only the binary data.
       Conversion to strings is done on playback.
    2. Playback is done one record at a time.  This is less efficient,
       but output is going to the Serial port, so speed isn't as much
       of an issue.
    3. if you uncomment #define USE_EXFAT the program will use the EXFat
       file system of SDFat 2.0beta.  You will need an SD Card formatted
       for the EXFat file system.  That can be done with the tools
       in the SDFat examples




  Written for Teensy 3.6 by M. Borgerson  May 7, 2020
********************************************************************/

// SPI library not needed with Teensy built-in SD card

#define USE_EXFAT

#ifdef USE_EXFAT

#include "SdFat.h"
#include "sdios.h"
#include "ExFatlib\ExFatLib.h"
SdExFat sd;
SdioCard sdc;
ExFile dataFile;
#define SD_CONFIG SdioConfig(FIFO_SDIO)

#else

#include <SD.h>
File dataFile;

#endif

IntervalTimer ADCTimer;



// A simple structure to hold time stamp and three analog values
// The structure takes up 16 bytes to align millitime on 4-byte boundary
struct datrec {
	uint32_t millitime;
	uint32_t microtime;
	uint32_t DWTCount;
	uint32_t byteswritten;
};
// Allocate two buffers, each holding over 1 second of data.
// For efficiency, the total length should be a multiple of 512.
// Note that the T3.6 will run out of RAM at about 8000Hz sampling
// as each buffer would have to be 8000 * 16 or 128,000 bytes, leaving
// very little room for the stack, heap, and USB buffers.
//#define BUFFSIZE  1024

// allocate two buffers, each of which holds 1024 records
// each buffer is 1024 * 16 or 16KBytes

#define SAMPLERATE 20000
#define USE_PSRAM 1
#ifdef USE_PSRAM // 128KB apart
#define BUFFSIZE  8190*8
const char *logfilename = "TIMELG_R1.DAT";
#include <extRAM_t4.h>
extRAM_t4 eRAM;
//uint8_t config = 2; //0 - init eram only, 1-init flash only, 2-init both
//These have been replaced with defines for:
//INIT_PSRAM_ONLY
//INIT_FLASH_ONLY
//INIT_PSRM_FLASH
uint8_t config = INIT_PSRAM_ONLY;
struct datrec *dbuff0 = (datrec *)0x70050000;
struct datrec *dbuff1 = (datrec *)0x70090000;
#else
#define BUFFSIZE  1024
const char *logfilename = "TIMELOG1.DAT";
struct datrec dbuff0[BUFFSIZE];
struct datrec dbuff1[BUFFSIZE];
#endif


#define DEBUGPRINT true


// when graphout is true, during recording, only the block write
// interval is displayed.  This allows graphing with the Arduino
// Serial Plotter display.
bool graphout = false;

// these variables are declared volatile because they are changed or used in the
// interrupt handler
volatile uint16_t saveidx = 0;
volatile int16_t writebuffnum = -1;
volatile uint16_t savebuffnum = 0;
volatile uint32_t filestartmilli = 0;
volatile uint32_t byteswritten = 0;

#ifndef USE_EXFAT
const int chipSelect = BUILTIN_SDCARD;
#endif
const int ledpin = 13;

#define LEDON  digitalWriteFast(ledpin, HIGH);
#define LEDOFF digitalWriteFast(ledpin, LOW);

const char compileTime [] = "Timing Data Logger  Compiled on " __DATE__ " " __TIME__;
void setup() {
	if ( ARM_DWT_CYCCNT == ARM_DWT_CYCCNT ) {	  // activate ARM cycle counter
		ARM_DEMCR |= ARM_DEMCR_TRCENA; // Assure Cycle Counter active
		ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
	}

	pinMode(ledpin, OUTPUT);
	// Open serial communications and wait for port to open:
	Serial.begin(9600);
	while (!Serial && millis() < 4000 );
	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
	Serial.println(compileTime);
	// see if the card is present and can be initialized:
	Serial.print("Initializing SD card...");
#ifdef USE_EXFAT
	StartEXFat();
#else
	StartSD();
#endif

#ifdef USE_PSRAM // 128KB apart
	eRAM.begin(config);
	Serial.print("Start PSRAM for LOGGING :: ");
	Serial.println( logfilename );
#else
	Serial.print("LOGGING from RAM :: ");
	Serial.println( logfilename );
#endif

	Serial.printf("\nTwin buffers of size %u Bytes\n" , sizeof(datrec)*BUFFSIZE );
	Serial.println("Enter command selected from (r, g, q, p, s)");
}


#ifdef USE_EXFAT
void StartEXFat(void) {
	if (!sd.cardBegin(SD_CONFIG)) {
		Serial.print("cardBegin failed");
	}
	if (!sd.volumeBegin()) {
		Serial.print("  volumeBegin failed");
	}
	if (!sd.begin(SdioConfig(FIFO_SDIO))) {
		Serial.println("\nSD File  system initialization failed.\n");
		FastBlink();
	} else  Serial.print("EXFat initialization done.");

	if (sd.fatType() == FAT_TYPE_EXFAT) {
		Serial.println("  Card Type is exFAT");
	} else {
		FastBlink();
	}
	Serial.println("card initialized.");
}

#else
void StartSD(void) {
	if (!SD.begin(chipSelect)) {
		Serial.println("Card failed, not FAT32, or not present");
		// don't do anything more except fast blink LED
		FastBlink();
	}
	Serial.println("card initialized.");
}
#endif

void FastBlink(void) {  // blink forever
	while (1) {
		LEDON
		delay(50);
		LEDOFF
		delay(50);
	}
}

static uint32_t elapsedUS = 0;
uint32_t loopCnt = 0, loopSpd;
elapsedMillis elapsedLoop = 0;
void loop() {
	// put your main code here, to run repeatedly:
	char ch;
	uint32_t microselapsed;
	elapsedMicros wrtelapsed = 0;
	loopCnt++;
	if ( elapsedLoop >= 1000 ) {
		loopSpd = loopCnt;
		loopCnt = 0;
		elapsedLoop -= 1000;
	}

	if (Serial.available()) {
		ch = Serial.read();
		if (ch == 'r') {
			graphout = false;
			StartLogging();
		}
		if (ch == 'g') {
			graphout = true;
			StartLogging();
		}
		if (ch == 'q') StopLogging();
		if (ch == 'p') PlaybackLog();
		if (ch == 's') sPlaybackLog(); // Sparse playback
	}
	// Now check to see if a buffer is ready to be written to SD
	// writebuffnum will be set in the interrupt handler
	if (writebuffnum == 0) { //is dbuff0 ready?
		LEDON
		writebuffnum = -1;
		if (dataFile) { //if the file is open write dbuff0
			wrtelapsed = 0;
			WriteBinary(&dbuff0[0], BUFFSIZE);
			microselapsed = wrtelapsed;
			if (DEBUGPRINT) {
				if (graphout) {
					Serial.println((float)microselapsed / 1000.0);
				} else {
					loopCnt = loopCnt / (micros() - elapsedUS);
					Serial.printf("0] %6.2f mSec fill [lp#%lu] \t", (float)(micros() - elapsedUS) / 1000.0, loopSpd );
					Serial.print("Writing dbuff0 to data file.  tmilli = ");
					Serial.printf(" %lu  took %6.2f mSec\n", dbuff0[0].millitime, (float)microselapsed / 1000.0);
					elapsedUS = micros();
				}
			}
		}
		LEDOFF
	}
	else if (writebuffnum == 1) { // is dbuff1 ready?
		LEDON
		writebuffnum = -1;
		if (dataFile) { //if the file is open write dbuff0
			wrtelapsed = 0;
			WriteBinary(&dbuff1[0], BUFFSIZE);
			microselapsed = wrtelapsed;
			if (DEBUGPRINT) {
				if (graphout) {
					Serial.println((float)microselapsed / 1000.0);
				} else {
					loopCnt = loopCnt / (micros() - elapsedUS);
					Serial.printf("1] %6.2f mSec fill [lp#%lu] \t", (float)(micros() - elapsedUS) / 1000.0, loopSpd );
					Serial.print("Writing dbuff1 to data file.  tmilli = ");
					Serial.printf(" %lu  took %6.2f mSec\n", dbuff1[0].millitime, (float)(microselapsed) / 1000.0);
					elapsedUS = micros();
				}
			}
		}
		LEDOFF
	}
	//delay(5);
}  // end of the loop() function

// write a buffer to the file as binary record. This  takes more time and file space than
// binary format, but can be directly read on PC.
// Note that we have to cast datrec pointer to a uint8_t pointer
// to keep the SD libraryhappy
void WriteBinary(volatile struct datrec *drp, size_t numstructs) {
	dataFile.write((uint8_t *)drp, numstructs * sizeof(datrec));

#ifdef USE_EXFAT
// sync() updates directory and puts SD card in low-power idle mode
// it increases the block write time to 6-10mSec, since the file system
// must wait for the long block write to finish before it can update the
// directory and put the SD card into idle mode
// Without the sync, the block write returns in 0.88mSec on T3.6 at 168MHz
// because all the multi-block write stuff happens in interrupt routines in
// the SDFat driver.
// Sync() will reduce power consumption by about 20 to 40mA in the ~1 second
// between block writes. That can be significant for low-power loggers.

//    dataFile.sync(); // uncomment for slower writes, but reduced SD power
#endif
}

// This is the interrupt handler for the interval timer.
// It saves the data in the data buffer structures.  The output is converted
// to CSV text when it is saved to the output file in the main loop.
// We don't want to do the conversion to a string in the interrupt handler
// since it takes a lot more time and many of the string routines are not
// reentrant. (Programmer talk for "They don't play nicely when interrupted")
void ADCChore(void) {
	uint32_t tmilli;
	tmilli = millis() - filestartmilli;
	byteswritten += sizeof(datrec); // update global bytes written count
	// save in  the proper buffer--defined by savebuffnum
	if (savebuffnum == 0) { // put data in dbuff0
		dbuff0[saveidx].millitime = tmilli;
		dbuff0[saveidx].microtime =  micros();
		dbuff0[saveidx].DWTCount = ARM_DWT_CYCCNT;
		//dbuff0[saveidx].byteswritten = byteswritten;
		dbuff0[saveidx].byteswritten = 0;
		saveidx++;
		if (saveidx >= BUFFSIZE) { // mark buffer for write to  SD
			writebuffnum = 0;
			savebuffnum = 1;   // start saving in other buffer on next interrupt
			saveidx = 0;  // start at beginning of next buffer
		}
	} else {  // must be saving to dbuff1
		dbuff1[saveidx].millitime = tmilli;
		dbuff1[saveidx].microtime =  micros();
		dbuff1[saveidx].DWTCount = ARM_DWT_CYCCNT;
		//dbuff1[saveidx].byteswritten = byteswritten;
		dbuff1[saveidx].byteswritten = 1;
		saveidx++;
		if (saveidx >= BUFFSIZE) { // mark buffer for write to  SD
			writebuffnum = 1;
			savebuffnum = 0;   // start saving in other buffer on next interrupt
			saveidx = 0;   // start at beginning of next buffer
		}
	}
}

void StartLogging(void) {
	if (dataFile) {
		Serial.println("Already collecting!");
		return;
	}
	// we open in a mode that creates a new file each time
	// instead of appending as in the Arduino example
	elapsedUS = micros();
	loopCnt = 0;
#ifdef USE_EXFAT

	if (!dataFile.open(logfilename, O_WRITE | O_CREAT | O_TRUNC)) {
		Serial1.println("Open File failed");
		return;
	}
	// pre-allocate 1GB
	uint64_t alloclength = (uint64_t)(1024l * 1024l * 1024l);
	Serial1.print("Pre-allocating 1GB file space ");
	if (!dataFile.preAllocate(alloclength)) {
		Serial.println("Allocation failed. Proceeding anyway.");
	} else {
		Serial.println("Allocation succeeded.");
	}

#else

	if (SD.exists(logfilename)) SD.remove(logfilename);
	dataFile = SD.open(logfilename, FILE_WRITE);

#endif
	// if the file can't be opened, say so
	if (!dataFile) {
		Serial.println("Could not open output file!");
		return;
	}

	Serial.println("Starting logging");
	// initialize some variables for the buffers
	saveidx = 0;   // start saving at beginning of buffer
	savebuffnum = 0;  // start saving in dbuff0
	writebuffnum = -1;  // indicates no buffer ready yet
	//  start the interval timer to begin logging
	filestartmilli = millis();
	byteswritten = 0;
	ADCTimer.begin(ADCChore, 1000000 / SAMPLERATE); //begin() expects timer period in microseconds
}

void StopLogging(void) {
	Serial.println("Stopping logging");
	ADCTimer.end();
	if (DEBUGPRINT) Serial.println("ADCTimer halted");
	delay(10);
	if (dataFile) {
		Serial.println("Data file closed.");
#ifdef USE_EXFAT
		dataFile.truncate();  // Truncate down to data actually written
#endif
		dataFile.close();  // if file was open, close it.
	} else {
		if (DEBUGPRINT) Serial.println("dataFile was not open!");
	}
	writebuffnum = -1;
	// dont' write tottal bytes if graphing--it messes up the plot!
	if (!graphout) {
		Serial.printf("%lu KBytes written to file.\n", byteswritten / 1024);
	}
	// in the interest of simplicity, we ignore any partial buffer at the end
}

void PlaybackLog(void) {
	struct datrec temprec;
	if (dataFile) StopLogging(); // if still recording, stop and close file
#ifdef USE_EXFAT
	if (!dataFile.open(logfilename, O_READ)) {
		Serial1.println("Open File failed");
		return;
	}
#else
	dataFile = SD.open(logfilename, FILE_READ);
#endif
	if (!dataFile) {
		Serial.println("Could not open data file for reading.");
		return;
	}
	while (dataFile.available()) {
		dataFile.read(&temprec, sizeof(datrec));
		Serial.printf("%lu, %lu, %lu, %lu\n", temprec.millitime, temprec.microtime, temprec.DWTCount, temprec.byteswritten);
	}
	dataFile.close();
	Serial.println("\nPlayback complete.");
}

void sPlaybackLog(void) {
	struct datrec temprec;
	if (dataFile) StopLogging(); // if still recording, stop and close file
#ifdef USE_EXFAT
	if (!dataFile.open(logfilename, O_READ)) {
		Serial1.println("Open File failed");
		return;
	}
#else
	dataFile = SD.open(logfilename, FILE_READ);
#endif
	if (!dataFile) {
		Serial.println("Could not open data file for reading.");
		return;
	}
	uint32_t lastM = 0;
	uint32_t lastB = 5;
	uint32_t ii = 0, iiL = 0;
	while (dataFile.available()) {
		dataFile.read(&temprec, sizeof(datrec));
		if ( lastM != temprec.millitime || lastB != temprec.byteswritten ) {
			Serial.printf("skipped %lu\t", ii);
			Serial.printf("%lu, %lu, %lu, %lu\t", temprec.millitime, temprec.microtime, temprec.DWTCount, temprec.byteswritten);
			if ( lastM != temprec.millitime )
				lastM = temprec.millitime;
			//else
			if (  lastB != temprec.byteswritten )
				lastB = temprec.byteswritten;
			if ( ii != iiL ) {
				Serial.print(" \t ????\n");
			}
			else
				Serial.print('\n');
			iiL = ii;
			ii = 0;
		}
		else
			ii++;
	}
	dataFile.close();
	Serial.println("\nSparse Playback complete.");
}
 
Alright I just pushed an update to my FNET fork, there is a new example already setup to use with FBENCH to do speed tests.

This is my average speed for large TCP transfers and seems to be the max: View attachment 19984
Keep in mind this speed test doesn't account for the overhead of TCP packets so it likely is reaching the 100Mb speeds it should be.

I added some FNET TCP/UDP performance numbers for T41 native ethernet to table in post #108
 
I threw together a wrapper library to bridge the gap between FNET and Ethernet.h.
https://github.com/vjmuzik/NativeEthernet
And a small update to my FNET fork to remove conflicts
https://github.com/vjmuzik/FNET

I've done as much testing as I could using the normal examples and some of my own sketches, so far they all appear to work as intended with no changes except for sketches that make direct calls to w5100.h. This instance of FNET is not multithreaded like my other examples have been, so this uses one IntervalTimer to poll the stack every 1ms in the background. Also in an effort to make sure this compiles from a fresh install I made a portable Teensyduino instance, installed libraries straight from GitHub, and tested it so I can confirm that it should compile without issues.

Because I tried to maintain compatibility with the standard Ethernet library some impact to the performance may have taken place.
 
@ vjmuzik:: I just got both updates to sketchbook libraries. Using IDE 1.8.12 and TD 1.52 B4

Same issues seen before? What's missing here?

Compiling this "T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino" gives::
Code:
Compiling sketch...
"T:\\arduino-1.8.12\\hardware\\teensy/../tools/precompile_helper" "T:\\arduino-1.8.12\\hardware\\teensy\\avr/cores/teensy4" "T:\\TEMP\\arduino_build_Functions.ino" "T:\\arduino-1.8.12\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -x c++-header -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=152 -DARDUINO=10600 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IT:\\arduino-1.8.12\\hardware\\teensy\\avr/cores/teensy4" "T:\\TEMP\\arduino_build_Functions.ino/pch/Arduino.h" -o "T:\\TEMP\\arduino_build_Functions.ino/pch/Arduino.h.gch"
Using previously compiled file: T:\TEMP\arduino_build_Functions.ino\pch\Arduino.h.gch
"T:\\arduino-1.8.12\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=152 -DARDUINO=10600 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IT:\\TEMP\\arduino_build_Functions.ino/pch" "-IT:\\arduino-1.8.12\\hardware\\teensy\\avr\\cores\\teensy4" "-IT:\\arduino-1.8.12\\hardware\\teensy\\avr\\libraries\\USBHost_t36" "-IT:\\tCode\\libraries\\TeensyASIXEthernet" "-IT:\\arduino-1.8.12\\hardware\\teensy\\avr\\libraries\\TeensyThreads" "-IT:\\tCode\\libraries\\FNET\\src" "T:\\TEMP\\arduino_build_Functions.ino\\sketch\\Functions.ino.cpp" -o "T:\\TEMP\\arduino_build_Functions.ino\\sketch\\Functions.ino.cpp.o"
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:26:32: error: variable or field 'dhcp_cln_callback_updated' declared void
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:26:32: error: 'fnet_dhcp_cln_desc_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:26:65: error: 'fnet_netif_desc_t' was not declared in this scope
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                                                 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:26:90: error: expected primary-expression before 'void'
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                                                                          ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:19: error: variable or field 'handleOutput' declared void
 void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
                   ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:19: error: 'fnet_netif_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:33: error: 'netif' was not declared in this scope
 void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
                                 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:40: error: 'fnet_netbuf_t' was not declared in this scope
 void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
                                        ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:55: error: 'nb' was not declared in this scope
 void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
                                                       ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:256:26: error: variable or field 'handleGetMACAddress' declared void
 void handleGetMACAddress(fnet_mac_addr_t * hw_addr) { //Gets called everytime a message is sent
                          ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:256:26: error: 'fnet_mac_addr_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:256:44: error: 'hw_addr' was not declared in this scope
 void handleGetMACAddress(fnet_mac_addr_t * hw_addr) { //Gets called everytime a message is sent
                                            ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:277:20: error: variable or field 'handlePHYRead' declared void
 void handlePHYRead(fnet_uint32_t reg_addr, fnet_uint16_t *data) { //Could be called, don't think it works correctly
                    ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:277:20: error: 'fnet_uint32_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:277:44: error: 'fnet_uint16_t' was not declared in this scope
 void handlePHYRead(fnet_uint32_t reg_addr, fnet_uint16_t *data) { //Could be called, don't think it works correctly
                                            ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:277:59: error: 'data' was not declared in this scope
 void handlePHYRead(fnet_uint32_t reg_addr, fnet_uint16_t *data) { //Could be called, don't think it works correctly
                                                           ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:285:21: error: variable or field 'handlePHYWrite' declared void
 void handlePHYWrite(fnet_uint32_t reg_addr, fnet_uint16_t data) { //Could be called, might work correctly
                     ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:285:21: error: 'fnet_uint32_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:285:45: error: 'fnet_uint16_t' was not declared in this scope
 void handlePHYWrite(fnet_uint32_t reg_addr, fnet_uint16_t data) { //Could be called, might work correctly
                                             ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:291:26: error: variable or field 'handleMulticastJoin' declared void
 void handleMulticastJoin(fnet_netif_t *netif, fnet_mac_addr_t multicast_addr) { //Called when joining multicast group
                          ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:291:26: error: 'fnet_netif_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:291:40: error: 'netif' was not declared in this scope
 void handleMulticastJoin(fnet_netif_t *netif, fnet_mac_addr_t multicast_addr) { //Called when joining multicast group
                                        ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:291:47: error: 'fnet_mac_addr_t' was not declared in this scope
 void handleMulticastJoin(fnet_netif_t *netif, fnet_mac_addr_t multicast_addr) { //Called when joining multicast group
                                               ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:310:27: error: variable or field 'handleMulticastLeave' declared void
 void handleMulticastLeave(fnet_netif_t *netif, fnet_mac_addr_t multicast_addr) { //Called when leaving multicast group
                           ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:310:27: error: 'fnet_netif_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:310:41: error: 'netif' was not declared in this scope
 void handleMulticastLeave(fnet_netif_t *netif, fnet_mac_addr_t multicast_addr) { //Called when leaving multicast group
                                         ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:310:48: error: 'fnet_mac_addr_t' was not declared in this scope
 void handleMulticastLeave(fnet_netif_t *netif, fnet_mac_addr_t multicast_addr) { //Called when leaving multicast group
                                                ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:335:1: error: 'fnet_bool_t' does not name a type
 fnet_bool_t handleIsConnected() {
 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:363:44: error: variable or field 'bench_srv_callback_session_end' declared void
 static void bench_srv_callback_session_end(fnet_bench_srv_desc_t desc, const struct fnet_bench_srv_result *bench_srv_result, void *cookie) {
                                            ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:363:44: error: 'fnet_bench_srv_desc_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:363:72: error: expected primary-expression before 'const'
 static void bench_srv_callback_session_end(fnet_bench_srv_desc_t desc, const struct fnet_bench_srv_result *bench_srv_result, void *cookie) {
                                                                        ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:363:126: error: expected primary-expression before 'void'
 static void bench_srv_callback_session_end(fnet_bench_srv_desc_t desc, const struct fnet_bench_srv_result *bench_srv_result, void *cookie) {
                                                                                                                              ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:508:44: error: variable or field 'bench_cln_callback_session_end' declared void
 static void bench_cln_callback_session_end(fnet_bench_cln_desc_t bench_cln_desc, const fnet_bench_cln_result_t *bench_cln_result, void *cookie){
                                            ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:508:44: error: 'fnet_bench_cln_desc_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:508:82: error: expected primary-expression before 'const'
 static void bench_cln_callback_session_end(fnet_bench_cln_desc_t bench_cln_desc, const fnet_bench_cln_result_t *bench_cln_result, void *cookie){
                                                                                  ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:508:131: error: expected primary-expression before 'void'
 static void bench_cln_callback_session_end(fnet_bench_cln_desc_t bench_cln_desc, const fnet_bench_cln_result_t *bench_cln_result, void *cookie){
                                                                                                                                   ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:31:1: error: 'fnet_return_t' does not name a type
 fnet_return_t teensy_mutex_init(fnet_mutex_t *mutex) {
 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:45:27: error: variable or field 'teensy_mutex_release' declared void
 void teensy_mutex_release(fnet_mutex_t *mutex) {
                           ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:45:27: error: 'fnet_mutex_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:45:41: error: 'mutex' was not declared in this scope
 void teensy_mutex_release(fnet_mutex_t *mutex) {
                                         ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:51:24: error: variable or field 'teensy_mutex_lock' declared void
 void teensy_mutex_lock(fnet_mutex_t *mutex) {
                        ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:51:24: error: 'fnet_mutex_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:51:38: error: 'mutex' was not declared in this scope
 void teensy_mutex_lock(fnet_mutex_t *mutex) {
                                      ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:69:26: error: variable or field 'teensy_mutex_unlock' declared void
 void teensy_mutex_unlock(fnet_mutex_t *mutex) {
                          ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:69:26: error: 'fnet_mutex_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:69:40: error: 'mutex' was not declared in this scope
 void teensy_mutex_unlock(fnet_mutex_t *mutex) {
                                        ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:94:1: error: 'fnet_time_t' does not name a type
 fnet_time_t timer_get_ms(void){ //Used for multi-thread version
 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino: In function 'void usbthread()':
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:6:5: error: 'myusb' was not declared in this scope
     myusb.Task();
     ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:7:5: error: 'asix1' was not declared in this scope
     asix1.read();
     ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:9:34: error: 'current_netif' was not declared in this scope
     if(fnet_netif_is_initialized(current_netif)){
                                  ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:9:47: error: 'fnet_netif_is_initialized' was not declared in this scope
     if(fnet_netif_is_initialized(current_netif)){
                                               ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:10:17: error: 'fnet_poll' was not declared in this scope
       fnet_poll();
                 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:11:25: error: 'fnet_service_poll' was not declared in this scope
       fnet_service_poll();
                         ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:20:7: error: 'threads' was not declared in this scope
       threads.yield();
       ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino: At global scope:
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:26:32: error: variable or field 'dhcp_cln_callback_updated' declared void
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:26:32: error: 'fnet_dhcp_cln_desc_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:26:65: error: 'fnet_netif_desc_t' was not declared in this scope
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                                                 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:26:90: error: expected primary-expression before 'void'
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                                                                          ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino: In function 'void checkLink()':
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:83:6: error: 'asix1' was not declared in this scope
   if(asix1.connected && fnet_dhcp_cln_is_enabled(dhcp_desc)){
      ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:83:50: error: 'dhcp_desc' was not declared in this scope
   if(asix1.connected && fnet_dhcp_cln_is_enabled(dhcp_desc)){
                                                  ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:83:59: error: 'fnet_dhcp_cln_is_enabled' was not declared in this scope
   if(asix1.connected && fnet_dhcp_cln_is_enabled(dhcp_desc)){
                                                           ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:87:33: error: aggregate 'checkLink()::fnet_init_params init_params' has incomplete type and cannot be defined
     struct fnet_init_params     init_params;
                                 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:89:18: error: 'fnet_timer_api_t' does not name a type
     static const fnet_timer_api_t timer_api = { //Setup multi-thread timer
                  ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:94:31: error: 'stack_heap' was not declared in this scope
     init_params.netheap_ptr = stack_heap;
                               ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:96:30: error: 'teensy_mutex_api' was not declared in this scope
     init_params.mutex_api = &teensy_mutex_api;
                              ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:97:30: error: 'timer_api' was not declared in this scope
     init_params.timer_api = &timer_api;
                              ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:99:31: error: 'fnet_init' was not declared in this scope
     if (fnet_init(&init_params) != FNET_ERR) {
                               ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:99:36: error: 'FNET_ERR' was not declared in this scope
     if (fnet_init(&init_params) != FNET_ERR) {
                                    ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:104:26: error: 'FNET_CPU_USB0_IF' was not declared in this scope
       if(fnet_netif_init(FNET_CPU_USB0_IF, MacAddress, 6) != FNET_ERR){
                          ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:104:44: error: 'MacAddress' was not declared in this scope
       if(fnet_netif_init(FNET_CPU_USB0_IF, MacAddress, 6) != FNET_ERR){
                                            ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:104:57: error: 'fnet_netif_init' was not declared in this scope
       if(fnet_netif_init(FNET_CPU_USB0_IF, MacAddress, 6) != FNET_ERR){
                                                         ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:106:13: error: 'current_netif' was not declared in this scope
         if((current_netif = fnet_netif_get_default()) == 0){
             ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:106:52: error: 'fnet_netif_get_default' was not declared in this scope
         if((current_netif = fnet_netif_get_default()) == 0){
                                                    ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:111:57: error: 'fnet_memset_zero' was not declared in this scope
           fnet_memset_zero(&dhcp_desc, sizeof(dhcp_desc));
                                                         ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:112:29: error: 'dhcp_params' was not declared in this scope
           fnet_memset_zero(&dhcp_params, sizeof(dhcp_params));
                             ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:115:58: error: 'fnet_dhcp_cln_init' was not declared in this scope
           if((dhcp_desc = fnet_dhcp_cln_init(&dhcp_params))){
                                                          ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:117:60: error: 'dhcp_cln_callback_updated' was not declared in this scope
              fnet_dhcp_cln_set_callback_updated(dhcp_desc, dhcp_cln_callback_updated, (void*)dhcp_desc);
                                                            ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:117:103: error: 'fnet_dhcp_cln_set_callback_updated' was not declared in this scope
              fnet_dhcp_cln_set_callback_updated(dhcp_desc, dhcp_cln_callback_updated, (void*)dhcp_desc);
                                                                                                       ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:118:104: error: 'fnet_dhcp_cln_set_callback_discover' was not declared in this scope
              fnet_dhcp_cln_set_callback_discover(dhcp_desc, dhcp_cln_callback_updated, (void*)dhcp_desc);
                                                                                                        ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:137:36: error: 'fnet_dhcp_cln_release' was not declared in this scope
     fnet_dhcp_cln_release(dhcp_desc);
                                    ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:138:50: error: 'fnet_memset_zero' was not declared in this scope
     fnet_memset_zero(dhcp_desc, sizeof(dhcp_desc));
                                                  ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:140:18: error: 'fnet_release' was not declared in this scope
     fnet_release();
                  ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino: At global scope:
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:19: error: variable or field 'handleOutput' declared void
 void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
                   ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:19: error: 'fnet_netif_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:33: error: 'netif' was not declared in this scope
 void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
                                 ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:40: error: 'fnet_netbuf_t' was not declared in this scope
 void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
                                        ^
T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\Functions.ino:147:55: error: 'nb' was not declared in this scope
 void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
                                                       ^
In file included from T:\tCode\libraries\FNET\src/stack/fnet_socket.h:30:0,
                 from T:\tCode\libraries\FNET\src/stack/fnet_stack.h:32,
                 from T:\tCode\libraries\FNET\src/fnet.h:36,
                 from T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:7:
T:\tCode\libraries\FNET\src/stack/fnet_ip6.h:35:8: error: expected declaration before end of line
 FNET_COMP_PACKED_BEGIN
        ^
Using library USBHost_t36 at version 0.1 in folder: T:\arduino-1.8.12\hardware\teensy\avr\libraries\USBHost_t36 
Using library TeensyASIXEthernet in folder: T:\tCode\libraries\TeensyASIXEthernet (legacy)
Using library TeensyThreads at version 1.0.1 in folder: T:\arduino-1.8.12\hardware\teensy\avr\libraries\TeensyThreads 
Using library FNET at version 0.1.3 in folder: T:\tCode\libraries\FNET 
exit status 1

Similar for :: T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino
Code:
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:22:32: error: variable or field 'dhcp_cln_callback_updated' declared void
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:22:32: error: 'fnet_dhcp_cln_desc_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:22:65: error: 'fnet_netif_desc_t' was not declared in this scope
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                                                 ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:22:90: error: expected primary-expression before 'void'
 void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
                                                                                          ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:117:1: error: 'fnet_bool_t' does not name a type
 fnet_bool_t handleIsConnected() {
 ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:145:44: error: variable or field 'bench_srv_callback_session_end' declared void
 static void bench_srv_callback_session_end(fnet_bench_srv_desc_t desc, const struct fnet_bench_srv_result *bench_srv_result, void *cookie) {
                                            ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:145:44: error: 'fnet_bench_srv_desc_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:145:72: error: expected primary-expression before 'const'
 static void bench_srv_callback_session_end(fnet_bench_srv_desc_t desc, const struct fnet_bench_srv_result *bench_srv_result, void *cookie) {
                                                                        ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:145:126: error: expected primary-expression before 'void'
 static void bench_srv_callback_session_end(fnet_bench_srv_desc_t desc, const struct fnet_bench_srv_result *bench_srv_result, void *cookie) {
                                                                                                                              ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:290:44: error: variable or field 'bench_cln_callback_session_end' declared void
 static void bench_cln_callback_session_end(fnet_bench_cln_desc_t bench_cln_desc, const fnet_bench_cln_result_t *bench_cln_result, void *cookie){
                                            ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:290:44: error: 'fnet_bench_cln_desc_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:290:82: error: expected primary-expression before 'const'
 static void bench_cln_callback_session_end(fnet_bench_cln_desc_t bench_cln_desc, const fnet_bench_cln_result_t *bench_cln_result, void *cookie){
                                                                                  ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\Functions.ino:290:131: error: expected primary-expression before 'void'
 static void bench_cln_callback_session_end(fnet_bench_cln_desc_t bench_cln_desc, const fnet_bench_cln_result_t *bench_cln_result, void *cookie){
                                                                                                                                   ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino:25:1: error: 'fnet_return_t' does not name a type
 fnet_return_t teensy_mutex_init(fnet_mutex_t *mutex) {
 ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino:39:27: error: variable or field 'teensy_mutex_release' declared void
 void teensy_mutex_release(fnet_mutex_t *mutex) {
                           ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino:39:27: error: 'fnet_mutex_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino:39:41: error: 'mutex' was not declared in this scope
 void teensy_mutex_release(fnet_mutex_t *mutex) {
                                         ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino:45:24: error: variable or field 'teensy_mutex_lock' declared void
 void teensy_mutex_lock(fnet_mutex_t *mutex) {
                        ^
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino:45:24: error: 'fnet_mutex_t' was not declared in this scope
T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino:45:38: error: 'mutex' was not declared in this scope
 void teensy_mutex_lock(fnet_mutex_t *mutex) {
          
 ...
 
I don't know where those errors are coming from, I can't seem to reproduce it on my normal installation or my portable installation of Teensyduino 1.52 B4.
 
I don't know where those errors are coming from, I can't seem to reproduce it on my normal installation or my portable installation of Teensyduino 1.52 B4.

Well that is a puzzle then :( This is what I noted after your last update too so I couldn't test again - and wanted to try to see the NATIVE and USBHost working from the same code.
 
@ vjmuzik:: I just got both updates to sketchbook libraries. Using IDE 1.8.12 and TD 1.52 B4

Same issues seen before? What's missing here?

Compiling this "T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino" gives::
…..

Similar for :: T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino
...

@defragster - @vjmuzik

Just downloaded latest version of FNET and NativeEthernet libs.

Compiled FNET_Native_Ethernet.ino without errors. However ASIXEthernet_Test.ino is giving me errors but different ones that @defragster noted:
Code:
Arduino: 1.8.12 (Windows 10), TD: 1.52-beta4, Board: "Teensy 4.1, MTP Disk (Experimental), 600 MHz, Faster, US English"

ASIXEthernet_Test: In function 'void setup()':
D:\Users\Merli\Documents\Arduino\libraries\FNET-master\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:113:39: warning: invalid conversion from 'void (*)(const uint8_t*, uint32_t) {aka void (*)(const unsigned char*, long unsigned int)}' to 'void (*)(const uint8_t*, uint16_t) {aka void (*)(const unsigned char*, short unsigned int)}' [-fpermissive]

   asix1.setHandleRecieve(handleRecieve);
                                      
In file included from D:\Users\Merli\Documents\Arduino\libraries\FNET-master\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino:4:0:

D:\Users\Merli\Documents\Arduino\libraries\TeensyASIXEthernet-master/ASIXEthernet.h:38:10: note:   initializing argument 1 of 'void ASIXEthernet::setHandleRecieve(void (*)(const uint8_t*, uint16_t))'

     void setHandleRecieve(void (*fptr)(const uint8_t* data, uint16_t length)) {

          ^
ASIXEthernet_Test:114: error: 'class ASIXEthernet' has no member named 'setHandleWait'
   asix1.setHandleWait(handleWait);

         ^
Functions: In function 'void checkLink()':
Functions:83: error: 'class ASIXEthernet' has no member named 'connected'
   if(asix1.connected && fnet_dhcp_cln_is_enabled(dhcp_desc)){

            ^
Functions:86: error: 'class ASIXEthernet' has no member named 'connected'
   else if(asix1.connected){

                 ^
Functions:135: error: 'class ASIXEthernet' has no member named 'connected'
   else if(!asix1.connected && fnet_dhcp_cln_is_enabled(dhcp_desc)){

                  ^
Functions:142: error: 'class ASIXEthernet' has no member named 'connected'
   else if(!asix1.connected){

                  ^
Functions: In function 'void handleMulticastJoin(fnet_netif_t*, fnet_uint8_t*)':
Functions:303: error: 'class ASIXEthernet' has no member named 'setMulticast'
   asix1.setMulticast((uint8_t*)&mcHashTable);

         ^
Functions: In function 'void handleMulticastLeave(fnet_netif_t*, fnet_uint8_t*)':
Functions:321: error: 'class ASIXEthernet' has no member named 'setMulticast'
   asix1.setMulticast((uint8_t*)&mcHashTable);

         ^
Functions: In function 'fnet_bool_t handleIsConnected()':
Functions:336: error: 'class ASIXEthernet' has no member named 'connected'
   return asix1.connected ? FNET_TRUE : FNET_FALSE;

                ^
'class ASIXEthernet' has no member named 'setHandleWait'
Note this is using a T4.1 with both a Flash and PSRAM chip.

Also did a compile on the BarometricPressureWebServer.ino sketch with no errors, a few warnings though.
 
I threw together a wrapper library to bridge the gap between FNET and Ethernet.h.
https://github.com/vjmuzik/NativeEthernet
And a small update to my FNET fork to remove conflicts
https://github.com/vjmuzik/FNET

I've done as much testing as I could using the normal examples and some of my own sketches, so far they all appear to work as intended with no changes except for sketches that make direct calls to w5100.h. This instance of FNET is not multithreaded like my other examples have been, so this uses one IntervalTimer to poll the stack every 1ms in the background. Also in an effort to make sure this compiles from a fresh install I made a portable Teensyduino instance, installed libraries straight from GitHub, and tested it so I can confirm that it should compile without issues.

Because I tried to maintain compatibility with the standard Ethernet library some impact to the performance may have taken place.

Wow! This wrapper looks good. :D i'm running my UDP/TCP tests....

ntp drift test (UDP)
Code:
     ntp 3797960422.015705  rtt 189 us   -7 ppm over 10 s
     ntp 3797960432.015986  rtt 193 us   -7 ppm over 20 s
     ntp 3797960442.016269  rtt 193 us   -7 ppm over 30 s

Ok,I again updated post #108 with FNET numbers using arduino wrapper. All looks good except when T4.1 is sending TCP. Sketch sends 100 1000-byte records but TCP receive on linux only reports receiving 68584 bytes ??
 
Last edited:
I was able to use flying leads for T3.6 and T4.0. I don't know why it wouldn't work with T4.1. User error is the best explanation, but unsatisfying.

Yes, maybe we can try to modify the PAD settings, and set them to a lower speed ("SPEED" and "DSE" Bitfields)
But this requires more intensive testing and we need to make sure it has no negative impact for other users.
 
Wow! This wrapper looks good. :D i'm running my UDP/TCP tests....

ntp drift test (UDP)
Code:
     ntp 3797960422.015705  rtt 189 us   -7 ppm over 10 s
     ntp 3797960432.015986  rtt 193 us   -7 ppm over 20 s
     ntp 3797960442.016269  rtt 193 us   -7 ppm over 30 s

Ok,I again updated post #108 with FNET numbers using arduino wrapper. All looks good except when T4.1 is sending TCP. Sketch sends 10 1000-byte records but TCP receive on linux only reports receiving 68584 bytes ??

Can I get a link to the test sketch so I can see what’s going on? Receiving more than it’s sending sounds like a problem.
 
Can I get a link to the test sketch so I can see what’s going on? Receiving more than it’s sending sounds like a problem.

well, sketch says its sending 100,000 bytes (100 x 1000), but tcpdump shows it just stops sending at some point. I'm still looking at the packet trace. here is test sketch
https://github.com/manitou48/teensy4/blob/master/fnet_perf.ino
sketch contains various tests, just uncomment the one you want to use. I tried adding client.flush() before client.stop() no change. TCP tests on your earlier FNET libs worked just fine.
test program is based on my earlier wiznet tests (e.g. W5500)

tcp_send() is the test you want to run. i just tried using fbench.exe on win10 as the receiver. same problem, only 68584 bytes arrive

packet trace show strange MSS from FNET (should be 1460?)
192.168.1.113.8888 > 192.168.1.4.5001: Flags , seq 192001, win 2048, options [mss 2048,wscale 0,eol], length 0
Commentiing out MSS setopt in Nativesocket.cpp fixes MSS problem (1460), but the tcp send is still only sending 68584 bytes ????
 

Attachments

  • pkt.zip
    2.5 KB · Views: 65
Last edited:
Or the more general defs.h solution which allows even more ;)
....
Me and a few others are suggesting these things since years - without any reaction from Paul.

I commented on this just a couple days ago on another thread, and I have done so many times over the past years. The notion that I have said nothing is absolutely false. Perhaps the situation is that I have not given the desired answer, so the words I have written were forgotten?

Arduino has consistently rejected this proposal. I personally have mixed feelings about it, though I do generally agree with their concerns about the long-term API consequences. So far, and certainly for the short term (definitely version 1.52) I'm continuing to follow their lead on this.

So at least for now, the answer is no. Please, remember that I say no. Do not say I didn't answer.
 
Yup, that comment and others were about Arduino - not Teensyduino - if I remember correctly.
Teensyduino is full of (wanted) changes to Arduino.

Edit: I don't see how storing per project settings in TD would affect the Ardunio APIs.

Edit: ok, I read your edit with your "NO" :)
 
I don't know where those errors are coming from, I can't seem to reproduce it on my normal installation or my portable installation of Teensyduino 1.52 B4.

This is with the never before failed TSET CmdLine build. I emptied sketchbook\libraries except for FNET and NativeEthernet. I get the same errors from fresh github p#310.

NOTE: IDE Portable does not affect the TSET CmdLine build to use the 'Portable' folder.

Opened IDE 1.8.12 and built "T:\tCode\libraries\FNET\examples\FNET_Native_Ethernet\FNET_Native_Ethernet.ino" to work.

Had to get a refresh of ::

Then I can build USB_HOST to work :: "T:\tCode\libraries\FNET\examples\ASIXEthernet_Test\ASIXEthernet_Test.ino"

<EDIT> @vjmuzik - those folders both have a second INO >> " Functions.ino "
- wondering if that is the problem as most sketch folders have a s single INO and then CPP file for other sources?
 
Last edited:
well, sketch says its sending 100,000 bytes (100 x 1000), but tcpdump shows it just stops sending at some point. I'm still looking at the packet trace. here is test sketch
https://github.com/manitou48/teensy4/blob/master/fnet_perf.ino
sketch contains various tests, just uncomment the one you want to use. I tried adding client.flush() before client.stop() no change. TCP tests on your earlier FNET libs worked just fine.
test program is based on my earlier wiznet tests (e.g. W5500)

tcp_test is the test you want to run. i just tried using fbench.exe on win10 as the receiver. same problem, only 68584 bytes arrive

packet trace show strange MSS from FNET (should be 1460?)
192.168.1.113.8888 > 192.168.1.4.5001: Flags , seq 192001, win 2048, options [mss 2048,wscale 0,eol], length 0
Commentiing out MSS setopt in Nativesocket.cpp fixes MSS problem (1460), but the tcp send is still only sending 68584 bytes ????


I found the problem, I was incorrectly reporting the number of bytes being written to the wrapper, so the wrapper was thinking it was sending the whole 100,000 bytes when it actually wasn't. Also the MSS is normal now, I forgot to reset it after I was done doing some other testing.
 
@defragster - any chance you can update your code in post #287 with your Sparse option.

@mjs513 (@all with PSRAM on T_4.1: added a variant of the posted SparsePrint() here in the write function to replace - with NO writes to SD card.
Code:
void WriteBinary(volatile struct datrec *drp, size_t numstructs) {

//	dataFile.write((uint8_t *)drp, numstructs * sizeof(datrec));

	Serial.printf(" \t BUFF at %lX\n", drp );
uint32_t lastM = 0;
	uint32_t kk,lastB = 5;
	uint32_t ii = 0, iiL = 0;
	lastB = drp[0].byteswritten;
	for ( kk=0; kk<numstructs; kk++) {
		if ( lastM != drp[kk].millitime || lastB != drp[kk].byteswritten ) {
			if ( lastM != drp[kk].millitime )
				lastM = drp[kk].millitime;
				
			if ( ii != iiL ) {
			Serial.printf("skipped %lu\t", ii);
			Serial.printf("%lu, %lu, %lu, %lu\t", drp[kk].millitime, drp[kk].microtime, drp[kk].DWTCount, drp[kk].byteswritten);
				Serial.printf(" \t kk==%lu  ????\n", kk );
			}
			iiL = ii;
			ii = 0;
		}
		else
			ii++;
	}

	//dataFile.write((uint8_t *)drp, numstructs * sizeof(datrec));

#ifdef USE_EXFAT
// sync() updates directory and puts SD card in low-power idle mode
// it increases the block write time to 6-10mSec, since the file system
// must wait for the long block write to finish before it can update the
// directory and put the SD card into idle mode
// Without the sync, the block write returns in 0.88mSec on T3.6 at 168MHz
// because all the multi-block write stuff happens in interrupt routines in
// the SDFat driver.
// Sync() will reduce power consumption by about 20 to 40mA in the ~1 second
// between block writes. That can be significant for low-power loggers.

//    dataFile.sync(); // uncomment for slower writes, but reduced SD power
#endif
}

it shows the ???? anomalies if tested before or after the dataFile.write() - or with NO datafile.write() !!!!

So the corruption is not from write occurring during logging - or from SD write/read fail - but just misplaced data into PSRAM????
Showing this with above WriteBinary() code replaced in posted code:
Code:
Starting logging
skipped 3	1, 3355024, 2012757749, 0	 	 kk==3  ????  ????
skipped 19	2, 3356024, 2013357744, 0	 	 kk==23  ????  ????
skipped 0	3276, 6630874, 3978267754, 1	 	 kk==16384  ????  ????
skipped 5	827, 4181024, 2508357744, 0	 	 kk==16523  ????  ????
skipped 19	828, 4182024, 2508957744, 0	 	 kk==16543  ????  ????
0] 3321.06 mSec fill [lp#4674330] 	Writing dbuff0 to data file.  tmilli =  0  took  25.82 mSec
skipped 2	3277, 6631024, 3978357737, 1	 	 kk==3  ????  ????
skipped 19	3278, 6632024, 3978957748, 1	 	 kk==23  ????  ????
1] 3276.43 mSec fill [lp#4673001] 	Writing dbuff1 to data file.  tmilli =  3276  took  26.27 mSec
skipped 2	6553, 9907024, 1648990442, 0	 	 kk==3  ????  ????
skipped 19	6554, 9908024, 1649590447, 0	 	 kk==23  ????  ????
[B]skipped 0	9828, 13182874, 3614500458, 1	 	 kk==16384  ????  ????[/B]
skipped 2	7379, 10733024, 2144590448, 0	 	 kk==16523  ????  ????
skipped 19	7380, 10734024, 2145190448, 0	 	 kk==16543  ????  ????
0] 3275.67 mSec fill [lp#4674340] 	Writing dbuff0 to data file.  tmilli =  6552  took  25.96 mSec
skipped 2	9829, 13183024, 3614590441, 1	 	 kk==3  ????  ????
skipped 19	9830, 13184024, 3615190452, 1	 	 kk==23  ????  ????
1] 3276.30 mSec fill [lp#4672906] 	Writing dbuff1 to data file.  tmilli =  9828  took  26.27 mSec
skipped 2	13105, 16459024, 1285223146, 0	 	 kk==3  ????  ????
skipped 19	13106, 16460024, 1285823151, 0	 	 kk==23  ????  ????
[B]skipped 0	16380, 19734874, 3250733162, 1	 	 kk==16384  ????  ????
[/B]skipped 2	13931, 17285024, 1780823152, 0	 	 kk==16523  ????  ????
skipped 19	13932, 17286024, 1781423152, 0	 	 kk==16543  ????  ????
0] 3275.67 mSec fill [lp#4674313] 	Writing dbuff0 to data file.  tmilli =  13104  took  25.95 mSec
skipped 2	16381, 19735024, 3250823145, 1	 	 kk==3  ????  ????
skipped 19	16382, 19736024, 3251423156, 1	 	 kk==23  ????  ????
1] 3276.31 mSec fill [lp#4672900] 	Writing dbuff1 to data file.  tmilli =  16380  took  26.28 mSec
skipped 2	19657, 23011024, 921455850, 0	 	 kk==3  ????  ????
skipped 19	19658, 23012024, 922055855, 0	 	 kk==23  ????  ????
[B]skipped 0	22932, 26286874, 2886965866, 1	 	 kk==16384  ????  ????
[/B]skipped 2	20483, 23837024, 1417055856, 0	 	 kk==16523  ????  ????
skipped 19	20484, 23838024, 1417655856, 0	 	 kk==16543  ????  ????
0] 3275.68 mSec fill [lp#4674336] 	Writing dbuff0 to data file.  tmilli =  19656  took  25.97 mSec
skipped 2	22933, 26287024, 2887055849, 1	 	 kk==3  ????  ????
skipped 19	22934, 26288024, 2887655860, 1	 	 kk==23  ????  ????
1] 3276.30 mSec fill [lp#4672905] 	Writing dbuff1 to data file.  tmilli =  22932  took  26.28 mSec
skipped 2	26209, 29563024, 557688554, 0	 	 kk==3  ????  ????
skipped 19	26210, 29564024, 558288559, 0	 	 kk==23  ????  ????
[B]skipped 0	29484, 32838874, 2523198570, 1	 	 kk==16384  ????  ????
[/B]skipped 9	27035, 30389024, 1053288560, 0	 	 kk==16523  ????  ????
skipped 19	27036, 30390024, 1053888560, 0	 	 kk==16543  ????  ????
0] 3275.32 mSec fill [lp#4674342] 	Writing dbuff0 to data file.  tmilli =  26208  took  25.61 mSec
skipped 2	29485, 32839024, 2523288553, 1	 	 kk==3  ????  ????
skipped 19	29486, 32840024, 2523888564, 1	 	 kk==23  ????  ????
1] 3276.65 mSec fill [lp#4672999] 	Writing dbuff1 to data file.  tmilli =  29484  took  26.27 mSec
skipped 2	32761, 36115024, 193921258, 0	 	 kk==3  ????  ????
skipped 19	32762, 36116024, 194521263, 0	 	 kk==23  ????  ????
[B]skipped 0	36036, 39390874, 2159431274, 1	 	 kk==16384  ????  ????
[/B]skipped 2	33587, 36941024, 689521264, 0	 	 kk==16523  ????  ????
skipped 19	33588, 36942024, 690121264, 0	 	 kk==16543  ????  ????
0] 3275.67 mSec fill [lp#4674350] 	Writing dbuff0 to data file.  tmilli =  32760  took  25.96 mSec
skipped 2	36037, 39391024, 2159521257, 1	 	 kk==3  ????  ????
skipped 19	36038, 39392024, 2160121268, 1	 	 kk==23  ????  ????
1] 3276.30 mSec fill [lp#4672905] 	Writing dbuff1 to data file.  tmilli =  36036  took  26.27 mSec
skipped 2	39313, 42667024, 4125121258, 0	 	 kk==3  ????  ????
skipped 19	39314, 42668024, 4125721263, 0	 	 kk==23  ????  ????
[B]skipped 0	42588, 45942874, 1795663978, 1	 	 kk==16384  ????  ????
[/B]skipped 2	40139, 43493024, 325753968, 0	 	 kk==16523  ????  ????
skipped 19	40140, 43494024, 326353968, 0	 	 kk==16543  ????  ????
0] 3275.68 mSec fill [lp#4674323] 	Writing dbuff0 to data file.  tmilli =  39312  took  25.96 mSec
skipped 2	42589, 45943024, 1795753961, 1	 	 kk==3  ????  ????
skipped 19	42590, 45944024, 1796353972, 1	 	 kk==23  ????  ????
1] 3276.30 mSec fill [lp#4672907] 	Writing dbuff1 to data file.  tmilli =  42588  took  26.27 mSec
skipped 2	45865, 49219024, 3761353962, 0	 	 kk==3  ????  ????
skipped 19	45866, 49220024, 3761953967, 0	 	 kk==23  ????  ????
[B]skipped 0	49140, 52494874, 1431896682, 1	 	 kk==16384  ????  ????
[/B]skipped 5	46691, 50045024, 4256953968, 0	 	 kk==16523  ????  ????
skipped 19	46692, 50046024, 4257553968, 0	 	 kk==16543  ????  ????
0] 3275.53 mSec fill [lp#4674312] 	Writing dbuff0 to data file.  tmilli =  45864  took  25.82 mSec
skipped 2	49141, 52495024, 1431986665, 1	 	 kk==3  ????  ????
skipped 19	49142, 52496024, 1432586676, 1	 	 kk==23  ????  ????
1] 3276.44 mSec fill [lp#4672999] 	Writing dbuff1 to data file.  tmilli =  49140  took  26.27 mSec
skipped 2	52417, 55771024, 3397586666, 0	 	 kk==3  ????  ????
skipped 19	52418, 55772024, 3398186671, 0	 	 kk==23  ????  ????
[B]skipped 0	55692, 59046874, 1068129386, 1	 	 kk==16384  ????  ????
[/B]skipped 2	53243, 56597024, 3893186672, 0	 	 kk==16523  ????  ????
skipped 19	53244, 56598024, 3893786672, 0	 	 kk==16543  ????  ????
0] 3275.67 mSec fill [lp#4674341] 	Writing dbuff0 to data file.  tmilli =  52416  took  25.96 mSec
skipped 2	55693, 59047024, 1068219369, 1	 	 kk==3  ????  ????
skipped 19	55694, 59048024, 1068819380, 1	 	 kk==23  ????  ????
1] 3276.31 mSec fill [lp#4672900] 	Writing dbuff1 to data file.  tmilli =  55692  took  26.28 mSec
skipped 2	58969, 62323024, 3033819370, 0	 	 kk==3  ????  ????
skipped 19	58970, 62324024, 3034419375, 0	 	 kk==23  ????  ????
[B]skipped 0	62244, 65598874, 704362090, 1	 	 kk==16384  ????  ????
[/B]skipped 2	59795, 63149024, 3529419376, 0	 	 kk==16523  ????  ????
skipped 19	59796, 63150024, 3530019376, 0	 	 kk==16543  ????  ????
0] 3275.66 mSec fill [lp#4674341] 	Writing dbuff0 to data file.  tmilli =  58968  took  25.95 mSec
skipped 2	62245, 65599024, 704452073, 1	 	 kk==3  ????  ????
skipped 19	62246, 65600024, 705052084, 1	 	 kk==23  ????  ????
1] 3276.31 mSec fill [lp#4672906] 	Writing dbuff1 to data file.  tmilli =  62244  took  26.27 mSec
skipped 2	65521, 68875024, 2670052074, 0	 	 kk==3  ????  ????
skipped 19	65522, 68876024, 2670652079, 0	 	 kk==23  ????  ????
[B]skipped 0	68796, 72150874, 340594794, 1	 	 kk==16384  ????  ????
[/B]skipped 2	66347, 69701024, 3165652080, 0	 	 kk==16523  ????  ????
skipped 19	66348, 69702024, 3166252080, 0	 	 kk==16543  ????  ????
0] 3275.67 mSec fill [lp#4674301] 	Writing dbuff0 to data file.  tmilli =  65520  took  25.96 mSec
skipped 2	68797, 72151024, 340684777, 1	 	 kk==3  ????  ????
skipped 19	68798, 72152024, 341284788, 1	 	 kk==23  ????  ????
1] 3276.30 mSec fill [lp#4672900] 	Writing dbuff1 to data file.  tmilli =  68796  took  26.27 mSec
skipped 2	72073, 75427024, 2306284778, 0	 	 kk==3  ????  ????
skipped 19	72074, 75428024, 2306884783, 0	 	 kk==23  ????  ????
[B]skipped 0	75348, 78702874, 4271794794, 1	 	 kk==16384  ????  ????[/B]
skipped 10	72899, 76253024, 2801884784, 0	 	 kk==16523  ????  ????
skipped 19	72900, 76254024, 2802484784, 0	 	 kk==16543  ????  ????
0] 3275.18 mSec fill [lp#4674341] 	Writing dbuff0 to data file.  tmilli =  72072  took  25.47 mSec
skipped 2	75349, 78703024, 4271884777, 1	 	 kk==3  ????  ????
skipped 19	75350, 78704024, 4272484788, 1	 	 kk==23  ????  ????
1] 3276.79 mSec fill [lp#4672906] 	Writing dbuff1 to data file.  tmilli =  75348  took  26.27 mSec
skipped 2	78625, 81979024, 1942517482, 0	 	 kk==3  ????  ????
skipped 19	78626, 81980024, 1943117487, 0	 	 kk==23  ????  ????
[B]skipped 0	81900, 85254874, 3908027498, 1	 	 kk==16384  ????  ????[/B]
skipped 2	79451, 82805024, 2438117488, 0	 	 kk==16523  ????  ????
skipped 19	79452, 82806024, 2438717488, 0	 	 kk==16543  ????  ????
0] 3275.67 mSec fill [lp#4674311] 	Writing dbuff0 to data file.  tmilli =  78624  took  25.96 mSec
skipped 2	81901, 85255024, 3908117481, 1	 	 kk==3  ????  ????
skipped 19	81902, 85256024, 3908717492, 1	 	 kk==23  ????  ????
1] 3276.31 mSec fill [lp#4672906] 	Writing dbuff1 to data file.  tmilli =  81900  took  26.28 mSec
skipped 2	85177, 88531024, 1578750186, 0	 	 kk==3  ????  ????
skipped 19	85178, 88532024, 1579350191, 0	 	 kk==23  ????  ????
[B]skipped 0	88452, 91806874, 3544260202, 1	 	 kk==16384  ????  ????[/B]
skipped 9	86003, 89357024, 2074350192, 0	 	 kk==16523  ????  ????
skipped 19	86004, 89358024, 2074950192, 0	 	 kk==16543  ????  ????
0] 3275.33 mSec fill [lp#4674311] 	Writing dbuff0 to data file.  tmilli =  85176  took  25.62 mSec
skipped 2	88453, 91807024, 3544350185, 1	 	 kk==3  ????  ????
skipped 19	88454, 91808024, 3544950196, 1	 	 kk==23  ????  ????
1] 3276.65 mSec fill [lp#4672996] 	Writing dbuff1 to data file.  tmilli =  88452  took  26.28 mSec
skipped 2	91729, 95083024, 1214982890, 0	 	 kk==3  ????  ????
skipped 19	91730, 95084024, 1215582895, 0	 	 kk==23  ????  ????
[B]skipped 0	95004, 98358874, 3180492906, 1	 	 kk==16384  ????  ????[/B]
skipped 2	92555, 95909024, 1710582896, 0	 	 kk==16523  ????  ????
skipped 19	92556, 95910024, 1711182896, 0	 	 kk==16543  ????  ????
0] 3275.67 mSec fill [lp#4674000] 	Writing dbuff0 to data file.  tmilli =  91728  took  25.96 mSec
Stopping logging


Quick read of that:
- skipped ## means the first value after that (millis) changed after ## repetitions, it should show groups of 19, with 20 data logs per millisecond - and then 19 repeats after the change.
- the end digit ,0 or ,1 should coincide with what buffer the data was written into by the _isr():: ADCChore(void)

A given 'Writing dbuff#' should only be looking at one buffer or another so whatever is written should have the SAME # - those are bold, the ones not bold are same buffer - where the millis tick crossed a buffer so the group skip size is not 19.

Above example output shows same sized disturbance of Skip 0 then skip 9, a longer run now is always skip 7 then skip 0 - so that changes.
>> What is repeating on restarts here is that it is always 1's in the zero buffer????

You can check my pointer allocation - but dbuff0 precedes dbuff1 - and both should be safely long enough and not near the start or end of PSRAM, and should be safely on a 32 bit boundary ( though prior check##() that didn't matter for read/write )

Kraaaap - just thought of something and have to repost both blocks the above
The error is always at the same offset in the buffer ???? >> kk==16384 ???? ???? which is HEX 0x4000
>> another run the error was at 16385, next run back to 16384

Also just added this to CODE above showing buffer address to be certain where that offset relates to:
Code:
 	 [B]BUFF at 70090000[/B]  skipped 18	108109, 119721015, 3112858643, 1	 	 kk==19  ????  ????
skipped 19	108110, 119722015, 3113458643, 1	 	 kk==39  ????  ????
1] 3276.29 mSec fill [lp#4672773] 	Writing dbuff1 to data file.  tmilli =  108108  took  26.28 mSec
 	 [B]BUFF at 70050000[/B]  skipped 18	111385, 122997015, 783491348, 0	 	 kk==19  ????  ????
skipped 19	111386, 122998015, 784091348, 0	 	 kk==39  ????  ????
skipped 4	114660, 126272065, 2748521364, 1	 	 kk==16384  ????  ????
skipped 0	114660, 126272115, 2748551365, 1	 	 kk==16385  ????  ????
skipped 18	112211, 123823015, 1279091354, 0	 	 kk==16539  ????  ????
skipped 19	112212, 123824015, 1279691354, 0	 	 kk==16559  ????  ????

<EDIT>
Made the buffer smaller so once could fit in RAM1 and the other in RAM2 and this works, then changing back to PSRAM fails at the same point:
Code:
#define SAMPLERATE 20000
[B][COLOR="#FF0000"]//#define USE_PSRAM 1[/COLOR][/B]
#ifdef USE_PSRAM // 128KB apart
#define BUFFSIZE  9190*2
const char *logfilename = "TIMELG_R1.DAT";
#include <extRAM_t4.h>
extRAM_t4 eRAM;
//uint8_t config = 2; //0 - init eram only, 1-init flash only, 2-init both
//These have been replaced with defines for:
//INIT_PSRAM_ONLY
//INIT_FLASH_ONLY
//INIT_PSRM_FLASH
uint8_t config = INIT_PSRAM_ONLY;
struct datrec *dbuff0 = (datrec *)0x70050000;
struct datrec *dbuff1 = (datrec *)0x70090000;
#else
//#define BUFFSIZE  1024
#define BUFFSIZE  9190*2
const char *logfilename = "TIMELOG1.DAT";
[B]struct datrec dbuff1[BUFFSIZE];
//struct datrec dbuff1[BUFFSIZE];
struct datrec *dbuff0 = (datrec *)malloc(BUFFSIZE*sizeof(datrec));[/B]

#endif
Tried with either in RAM1 or RAM2 and neither show the failure - so it doesn't seem to be a problem in the _isr() logic writing to the wrong buffer, but something on the PSRAM boundary ?
 
Last edited:
Just tested the T4.1 (and T3.6) for recording uBlox F9P GPS data (NMEA RMC messages) at 20 Hz to SD. Works like a champ, with Pete's help on some code mods. See this thread "Stream Data from Serial1 to SD Card, Teensy 3.6" under the Technical Support forum area for details.
 
@defragster
Just ran the sketch with the added mods and am seeing the same thing:
Code:
1, 5170005, 3101752914, 0	 	 kk==3  ????
skipped 19	2, 5171005, 3102352914, 0	 	 kk==23  ????
skipped 0	3276, 8445855, 772295628, 1	 	 kk==16384  ????
skipped 10	827, 5996005, 3597352914, 0	 	 kk==16523  ????
skipped 19	828, 5997005, 3597952914, 0	 	 kk==16543  ????
0] 3329.41 mSec fill [lp#4674286] 	Writing dbuff0 to data file.  tmilli =  0  took  25.46 mSec
 	 BUFF at 70090000
skipped 2	3277, 8446005, 772385611, 1	 	 kk==3  ????
skipped 19	3278, 8447005, 772985617, 1	 	 kk==23  ????
1] 3276.80 mSec fill [lp#4672998] 	Writing dbuff1 to data file.  tmilli =  3276  took  26.28 mSec
 	 BUFF at 70050000
skipped 2	6553, 11722005, 2737985612, 0	 	 kk==3  ????
skipped 19	6554, 11723005, 2738585618, 0	 	 kk==23  ????
skipped 0	9828, 14997855, 408528332, 1	 	 kk==16384  ????
skipped 2	7379, 12548005, 3233585618, 0	 	 kk==16523  ????
skipped 19	7380, 12549005, 3234185618, 0	 	 kk==16543  ????
Whats interesting is that the kks' show that the problems are occurring at the same index number. Also assuming that that the 0 or 1 indicate the buffer?
 
Back
Top