Teensy 4.0 First Beta Test

Status
Not open for further replies.
@Paul - Sorry to hear about the employee problems. Luckily before I retired, I only had to fire a few people. It was never easy, and I worked for a much larger company. I cann't imagine having to do it in a 4 person company.

Hang in there and let us know if there is anything we can help with!
 
Kurt - I'll have a look at the mod you made from my T_3.6 testing { and remember what cool thing I did :) } ... I think that looped THROUGH port to port (?) rather than loop BACK to same port? I misread Frank's and though that is what that sample was.

But was much easier to use 8 jumpers and test across all 8 where each just Tx'd to its own Rx. Will find M to M wires and do a full loop over and back.

I was seeing something funny in trying to print Strings to USB I thought too - but then again I had quite a few gotchas in the posted code before I got it clean :( - debug OFF was one and the flakey Serial7 connect did not help :) :(

Doing a loop THROUGH all the ports will make sure that the same setting works for ALL. Though current test might be fun to have unique settings on alternate ports.

Question - do you have a list of the .begin() format strings that are usable to test?

Won't this overfill the default Tx buffer?
Code:
  Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
  Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
  Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");

I suppose I should test the dynamic buffer allocation addition?

Given that used Serial ports are Virtual (?) and only allocate when used - it might be good to start with larger 128 byte Rx and Tx buffers? Something more typical of GPS or other message strings?
 
@KurtE
Just tried the SPI mods with a BME280 sensor and getting some very strange results - using pins 10, 11, 12, 13. Tell me that I am at 6000meters.

Going to put a scope on it and see if I can sort it out - is there a best speed to test at for now :)
 
First, basic T4 support for SD.h - without optimizations.

To make it work with the Audioshield + adapter, just set chipselect to Pin 10 - other settings not needed.

Please test. I've tried some of the eamples- they work - but havn't tested more than that. Speed will be...not existend :)

https://github.com/PaulStoffregen/SD/pull/13
 
Last edited:
I did a quick and dirty update of the avr_emulation.h file to add in the SPI registers. Note: So far I only have done a real minor part of it.
In particular:
SPCR - nothing done, all code simply commented out
SPSR - Only the SPIF flag is returned.
SPDR - I do write to it (LPSPI4_TDR) and read from it (LPSPI4_RDR)

With this at least on my machine the Adafruit_ili9341 library graphic test compiles and runs. I don't think so but may rely on my SPI library changes as well...

Anyway checked this in on my other cores SPI PR (https://github.com/PaulStoffregen/cores/pull/320) that defined SPI structure

And my SPI changes are in the SPI PR (https://github.com/PaulStoffregen/SPI/pull/38)
Thanks, I used your avr_emulation.h file to get my SPI OLED (adafruit SSD1306) to run the 128x32 example on T4. SPI clock request is 8mhz, scope shows 7.57 mhz as expected.
Hacked CCR to increase SPI speed. Display worked fine all the way to 37.5 MHz, despite the reduced Vpp at 37.5 mhz.
Code:
           LPSPI4_CCR = 3   15 mhz scope 15.1 display ok
                        1   25 mhz  scope 25.2 Vpp 2.6v  display ok
                        0   37.5    scope 37.3  Vpp 1.8 v  display ok
 
Last edited:
That was the intention - to check if it blocks correctly until there is space in the buffers.
Or..is my assumtion wrong - have not looked at the source codes - shouldn't it block?

Couple of interesting things. If you do something like:
Code:
Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
  Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
  Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
The Serial1 write code will wait until it can put all of the data into the output buffer. If the output buffer fills, it spins until there is room to put stuff in...

However the more interesting this is what happens on the Receive buffer side.

That is:

if your code looks something like:

Code:
Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
  Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
  Serial1.print("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
  // Lets say Serial1 TX pin is connected to Serial2 RX pin.

  for (;;) {
    int ch = Serial2.read();
    if (ch != -1) Serial.write(ch);
  }
...
The problem is that Serial1 just wrote out the 193 characters, by the time the Serial2 queue is looked at. Actually somewhere near 193-<tx buffer size>

So that implies that the Serial2 receive buffer is going to try to save away that number of characters... But the RX buffer is not that big so it tosses data...

Where as the SerialEvent2 function can work, because while Serial1.print is waiting for space to be available, it is (hopefully) calling yield, which will then call through the SerialEvent2 code to pull the data out of the input queue...
 
That was the intention - to check if it blocks correctly until there is space in the buffers.
Or..is my assumtion wrong - have not looked at the sourcecodes - shouldn't it block?

+1

Yes it should and will block { yes it needs to be tested } - problem is the artificial nature of the test - buffer S1 will just push Tx buffer into Rx buffer on the same port and one or the other will get lost given the single thread is blocked - so that will make the rest of the test invalid as the data will be compromised in the dfirst step?
 
Ideally the output will be like the input. If it's not, something is wrong.
buffer S1 will just push Tx buffer into Rx buffer on the same port
Nope, to the next port RX. - at least with my version. If something gets lost, we have a problem.

Hav'nt looked at this eventResponder stuff - I think it's known that I don't like it. :rolleyes: No more comments from my side .. I'm done with that.:) If I ever need UARTs I'll use available, If I need speed i'll disable this stuff. Easy.
 
Hi Frank,

Actually at this point, not using the Event Responder, just the Arduino SerialEvent code (and our yield).

Obviously one way to resolve this is to make the buffers bigger. Note: this implementation, actually has code in it to allow a sketch to add RX and/or TX buffer space to a Serial object.

Right not pretty primitive. Just pointer and size. Not sure if it will stay. In the previous round of discussions on this (maybe a year ago), it was unclear what the best approach for adding objects like this.

If I remember correctly there were several opinions on how best to do this.
a) Simple API that says make my buffer size X - which uses malloc or the like.
b) Simple pass in method, which you pass in buffer/length
c) some form of object...
Lots of pros and cons... - So currently did simple approach (pass in buffer and size). I probably would have used malloc, but...

As for current test case. If RX full somehow blocked TX and Code won't continue until TX completes, we would hang... So not sure of best approach for single thread of operation.
 
I see what you say - the loop runs after the print. Maybe we can make a better testcase with the print inside the loop.
It would be good if there was a way to increase the buffers at runtime, since Arduino has no official way to use project settings where this stuff belongs to.. :)
So that means using malloc? But that would break compability, I fear..
 
@Paul - No Hurry or the like, I can probably figure out most of this. But with the new shiny breakout board, was wondering a few things, like:
Serial port area: You have 6 pins per Serial port, With RX/TX/GND - Wondering what the other three pin are...

My first guess is that, it is setup to be compatible with FTDI like cables, like:
09716-02.jpg

So something like: DTR RX TX V? CTS GND

The area that is setup for Audio board, how many of the pins connect up to the processor pins? Most/All or just what is needed for Audio?
I believe probably just Audio, as For example GND appears to ring out with my Multimeter, but D0 and D1 don't... Darn, when I am not getting ready to try Audio stuff, would be nice to be able to use the socket to hook up debug pins to things like Logic Analyzer.

USB Host connector: Again will probably ring out. But first look is that it connects to the pads under the USB where the pogo pins connect... Wondering how different the USB Host stuff is for this versus the T3.6... That is my guess, my mag lite died (replacement at Mailbox in town...) so harder to look at details of board

Well now back to playing.
 
I thought serialEvent under the IDE would be cool - then I saw it was just overhead outside loop not some magical interrupt. The EventResponder is like that - no magic - sketch doesn't poll for events - but the core does on any yield() or leaving loop() - it may be more efficient with checks - but not magic or threaded or interrupt driven - of course that could be rude too. So it is just another way to do polling - and pretend it is threading or at least isolate code to service 'tasks'. The cool thing is if all the 'Serial' is handled in an EVENT() a call to Yield or Delay at any time will process any data without having to POLL any individual source - so that can cleanly isolate chores to functions.

I thought your example from the English comment was going port to port ? but I got it working just putting jumpers on each port Rx<>Tx pair without changing the code ... then again I had that confusion doing the sample for T_3.6 Serial too. With Paul's new Breakout board - jumpers Rx<>Tx was a natural fit - and I had a 10 pack here at my desk :)

Even so while blocked filling on 'some' Tx - it will just transfer to 'another' Rx buffer - when that fills data will be lost if the Rx buffer isn't emptied before it fills because there isn't flow control to stop the Tx - right?

The way I edited your test assures that no buffer overflows - but just puts out enough data to be interesting and then waits for it to cycle through each port 1-2-3-4-5-6-7-8 and then back into 1 from 8 where it starts over.

It has done another 17 million iterations of that without error since I restarted after Kurt's other test.
 
The cool thing is if all the 'Serial' is handled in an EVENT() a call to Yield or Delay at any time
The uncool things are that it is in programs that don't use UARTs at all and that all interrupts get disabled for a short time. That's not near "bare metal" anymore, no way. It's going towards an OS - but then, one could use a raspberry? Or RTOS? But it's not the right thread to talk about this, and I'm tired.. :)

I'll do more fun things now and look what I can do with audio - and I have my ILI-lib waiting..!
 
Could someone test SD.h, please? A confirmation would be great because then we have a known to work basis and can begin to optmize T4-part of the library.
It's incredible slow, at the moment.


Sorry, did some copy&paste errors. I'll create a new pull-request.. :)

Edit: https://github.com/PaulStoffregen/SD/pull/14
 
Last edited:
Kurt - my eye suggested only the Rx/Tx were pulled over to that pin array - with resistors there just for touch safety keeping the T4 from getting zapped - the rest NOP's? Few top traces where bottom pair missing and only others on bottom.
And some clues from posts suggested T_3.x sockets were just to support Audio board testing. I did test/find p#15/A1 is there for the POT - was going to do a quick test to see how many of my prior devices could hang off of that to torment Serial testing until that is called good and onto something else.
 
Kurt - just got my board, wow, as I was playing with SPI. I checked RX/TX/GND and they look like they ring out not sure about the other.

EDIT:
BME280 on SPI not working. Did a couple of sanity checks, yes it works on I2C, and tested it on a T3.5 using SPI and it works with no issue. I put a scope on the lines 1 at a time with about 1ms delay between reading different data elements. The yellow lines are the SPI Clock and the Blue lines are the signal lines (CS, MISO, MOSI):
CS:
cs.jpg

SDI
sdi.jpg

SDO
sdo.jpg

The library has the SPI bus speed at 500Khz. The sketch is basically a bunch of reads with delays:
Code:
void loop() { 
    //printValues();
    bme.readTemperature();
    delay(5);
    bme.readPressure();
    delay(5);
    bme.readAltitude(SEALEVELPRESSURE_HPA);
    delay(5);
    bme.readHumidity();
    delay(10);
}
 
Last edited:
Frank - looked at Pull request #14:
> Exchanged the one line in :: Update Sd2PinMap.h
> Exchanged the file contents for Update Sd2Card.cpp
Both in Utility - compiled for T4 and ran against a card with no errors.

One 32 GB card had files on and all were found and displayed.

Other 8GB card has files that were not shown - but it powered up and connected with this output. Just swapped to PC and files show and I put on a .txt file that worked on the working card and does not show on this card.
This card is the one I had in my PJRC Audio Tutorial T_3.2 with factory installed Audio Board - I assume it worked when last used and the PC can see the files - FOUR .WAV files and the PDF of the Audio Tutorial - then the added empty Somefile.txt. The WAV files are UPPER CASE names, put it back in PC and did disk scan and no errors.

Initializing SD card...Wiring is correct and a card is present.

Card type: SDHC

Volume type is FAT32

Volume size (Kbytes): 7622656
Volume size (Mbytes): 7444

Files found on the card (name, date and size in bytes):

<edit> Put that card back in T_3.2 Audio Tutorial Board and it shows that same as below - where I assume CS should be the same pin 10 ? So the card may be acting up?

Powered up with no card and got the expected:
Initializing SD card...initialization failed. Things to check:
* is a card inserted?
* is your wiring correct?
* did you change the chipSelect pin to match your shield or module?

<EDIT>: Overwrite Reformatting the 8GB card in my PC - it acted odd on inserting it - maybe the carrier to put into larger slot on PC - put into another direct USB 3 device and it came up for formatting.

Found my copy of 'SD Memory Card Formatter 5.0.1 for SD/SDHC/SDXC' was old and there is an update so I'm using that and doing a long format ... and waiting ...
 
Last edited:
@Frank B
Could someone test SD.h, please? A confirmation would be great because then we have a known to work basis and can begin to optmize T4-part of the library.
It's incredible slow, at the moment.


Sorry, did some copy&paste errors. I'll create a new pull-request..

Edit: https://github.com/PaulStoffregen/SD/pull/14
You wish is my command. Hooked up a sainsmart sd card adapter and ran through all the examples. Everyone of them worked like a charm. No issues what so ever. Not sure why you said it was slow originally. Worked really well and fast. Tim will probably confirm.

Mike

EDIT: Guess Tim and I crossed post. My card is about the same as his except mine had some files on it:
Code:
Initializing SD card...Wiring is correct and a card is present.

Card type: SDHC

Volume type is FAT32

Volume size (Kbytes): 31154688
Volume size (Mbytes): 30424

Files found on the card (name, date and size in bytes): 
SYSTEM~1/     2017-09-10 13:13:12
  WPSETT~1.DAT  2017-09-10 13:13:12 12
  INDEXE~1      2017-09-10 13:21:18 76
DATA00.CSV    2000-01-01 01:00:00 2794
DATA01.CSV    2000-01-01 01:00:00 26132
DATALOG.TXT   2000-01-01 01:00:00 45846
TEST.TXT      2000-01-01 01:00:00 18
 
BME280 on SPI not working.

Try setting the SPI clock to 4 mhz or 8mhz in the BME280 lib. The T4 SPI lib at this time does not set any of the timing delays for the various SPI pins (CCR reg). That may be more critical at slow speeds. The EVK SDK SPI code would set the delay settings based on the SPI clock frequency. Also could try a short delay before pulling CS high at end of transfer. I haven't done any low-speed SPI tests. But just did successful OLED test up to 37.5 mhz.
 
Try setting the SPI clock to 4 mhz or 8mhz in the BME280 lib. The T4 SPI lib at this time does not set any of the timing delays for the various SPI pins. That may be more critical at slow speeds. The EVK SDK SPI code would set the delay settings based on the SPI clock frequency. Also could try a short delay before pulling CS high at end of transfer. I haven't done any low-speed SPI tests. But just did successful OLED test up to 37.5 mhz.

I tried 12.5mhz but that didn't work. Will try 4 and 8Mhz as a test then play with delay. May have to dig deeper into what they are doing with SPI in their library. Now to rehook up the BME280 chip.

EDIT: Kind of work - one of the data elements would print periodically correct. I looked at a couple other libraries but they had issues with I believe are deprecated functions:
Code:
undefined reference to `SPIClass::setBitOrder(unsigned char)'
undefined reference to `SPIClass::setDataMode(unsigned char)

Theres a setFrequency as well that didn't get an undefined

The EVK SDK SPI code would set the delay settings based on the SPI clock frequency
Now that you mention that I remember I was looking at that to see how calculated it. It was rather simple:
Code:
    pcsToSckDelayInNanoSec = 1000000000 / masterConfig.baudRate;
    lastSckToPcsDelayInNanoSec = 1000000000 / masterConfig.baudRate;
    betweenTransferDelayInNanoSec = 1000000000 / masterConfig.baudRate;
 
Last edited:
@Frank and @defragster - Here is another daisy chain Serial test that does not use SerialEvent...

It does non-blocking outputs the same way that apps would normally do it, by only outputting as much at a time as will fit in output queue... This one initializes a buffer at start of loop, and outputs as much per chunk as it can. Then for most Serial objects, it simply grabs as much at a time as it can and sends it back to itself... Then anything received back on Serial1 goes to the another buffer.

I bail the loop when I have sent everything and received everything or a timeout... I then compare buffers and report up to 5 errors...

Code:
//connect  Serial1 TX -> Serial2 RX, Serial2 TX -> Serial3 RX, Serial3 TX -> Serial4 RX....


#define SPD 1000000
int loop_count = 0;
#define BUFFER_SIZE  320
#define TIMEOUT_MILLIS 250
char buffer_out[BUFFER_SIZE];
char buffer_in[BUFFER_SIZE];
char buffer[80];

void setup() {
  pinMode(13, OUTPUT);
  //  while (!Serial && millis() < 4000) ;
  //  Serial.begin(115200);
  delay(800);
  Serial4.println("Test all Serials");
  Serial4.printf("Baud rate: %d\n", SPD);
  Serial1.begin(SPD);
  Serial2.begin(SPD);
  Serial3.begin(SPD);
  Serial4.begin(SPD);
  Serial5.begin(SPD);
  Serial6.begin(SPD);
  Serial7.begin(SPD);
  Serial8.begin(SPD);
}


void echoSerial(HardwareSerial *pserial)
{
  int cb = pserial->available();
  if (cb) {
    if (cb > sizeof(buffer)) cb = sizeof(buffer);
    if (cb >  pserial->availableForWrite()) cb = pserial->availableForWrite();
    pserial->readBytes(buffer, cb);
    pserial->write(buffer, cb);
  }
}


void loop() {

  Serial4.printf("Loop: %d\n", ++loop_count);
  for (int i = 0; i < BUFFER_SIZE; i++) {
    buffer_out[i] = (i + loop_count) & 0xff;
  }

  char *pb_out = buffer_out;
  int cb_out_left = BUFFER_SIZE;
  char *pb_in = buffer_in;
  int cb_in_left = BUFFER_SIZE;
  int cb;
  uint32_t start_time = millis();
  while ((cb_out_left || cb_in_left) && ((millis() - start_time) < TIMEOUT_MILLIS)) {
    // See if we have more to output
    if (cb_out_left) {
      cb = Serial1.availableForWrite();
      if (cb > cb_out_left) cb = cb_out_left;
      Serial1.write(pb_out, cb);
      pb_out += cb;
      cb_out_left -= cb;
    }
    echoSerial(&Serial2);
    echoSerial(&Serial3);
    // We are using Serial4 for other stuff
    echoSerial(&Serial5);
    echoSerial(&Serial6);
    echoSerial(&Serial7);
    echoSerial(&Serial8);

    // Serial1 is special so handle that one here.
    cb = Serial1.available();
    if (cb) {
      // should verify that we fit, but...
      Serial1.readBytes(pb_in, cb);
      pb_in += cb;
      cb_in_left -= cb;
    }
  }
  // Exited loop see if we received everything.
  uint32_t dt = millis() - start_time;
  Serial4.printf("Delta time: %d, CB Out: %d, CB In: %d\n", dt, BUFFER_SIZE - cb_out_left, BUFFER_SIZE - cb_in_left);
  int error_count = 0;
  for (int i = 0; i < BUFFER_SIZE; i++) {
    if (buffer_out[i] != buffer_in[i]) {
      error_count++;
      if (error_count < 5)Serial4.printf("   %d %x != %x\n", i, buffer_out[i], buffer_in[i]);
    }
  }
  Serial4.printf("     Error Count %d\n", error_count);
  delay(500);
}
 
Kurt - that example shows answers to some questions I had - passing the &Serial# nicely. Will give it a look.

Question - what is the Rx and Tx connect scheme for the ports?

I was here with speakers on and my computer said T4 left USB ??? It was running my last Serial sample - started it up again and going fine - maybe the pogo pin push-up interrupted something ... just gave it a push down.

Frank - after reformat the T_3.2 audio tut board failed to see anything - and the T4 sample showed the same startup as before - but no files - seems like that card isn't Teensy good just now. I see Mike gave it a GOOD, and it seemed to generally work on one card and did connect on the second better than T_3.2 audio board did - so I'll wait until next beta releases with it in and get a fresh card.
 
Status
Not open for further replies.
Back
Top