Teensy 4.0 - Serial.readBytes Corruption

Status
Not open for further replies.

thagh05t

Active member
Hello All,

I have an xmodem 1k implementation that I have written for Teensy 3.2 that works great. When porting over to Teensy 4.0 I saw a huge error rate when receiving bytes. Particularly on the count of bytes received that is returned by:

Code:
int read_bytes = Serial.readBytes((char *) &xmodem_block, sizeof(xmodem_block));

I later do a check to be sure all the bytes were read in by:

Code:
else if (read_bytes == sizeof(xmodem_block))

...and catch the incorrect read_bytes with the else statement and return a NAK to the sender, which forces them to resend the data.

So, everything is working as expected with the protocol, but my finding is that the count (maybe even the data) is corrupt when running at any clock speed (600, 450, 24MHz). I thought maybe it could have been the instantiation and assignment happening inside the for loop reading from serial, so I moved the instantiation outside of the loop. Then I started adding in delays in different places. I found that adding a delay at the top of the for loop (which would happen right after responding to the sender) the errors stopped. It has be a bit stumped as to why the problem would arise in the first place. Can anyone shed some light on this by chance, and possibly lead me to a solution that would not require adding this delay? As of now it works, but not at the speed it really could be. And I am sure one small change could also render similar effects.

My real question is, why would the delay fix the problem unless it is reading bytes faster than the sender is sending them? Could adding a condition to wait for the sender to finish before reading?

The delay works for now, but I am going to force the bytes read in order to try to achieve this instead. If that works I will post back, but I feel like serial USB should be handling this honestly.
 
Interestingly enough, I got my answer with inspiration from writing this post. I looked into the age old method we always use in the setup:

Code:
while (!Serial.available()) {}

Using this in place of the delay offered a quicker way to traverse the for loop as well as being less error prone if there were real hardware issues (bad cable, noise, etc). I have never had to use this within my code before when having conversations over serial, so I would still like to know why now?

Is this something to do with the overall processor speed on the Teensy 4.0? Does it have to do with some other difference in the chips USB implementation? I already have a solution, I am just curious at this point. It is possible that maybe all of you HAVE been doing things like this in the past and I have just been a lazy. If thats the case please also let me know.

Thanks in advance!
 
The Teensy 4.0 USB stack Under Development - and not yet complete or fully functional. Not sure to what extent there are bugs and where code it not yet implemented. In the end it should work like Prior T_3.x's - just at 480 Mbps instead of 12 Mbps - using wholly different onboard USB hardware on the T4 processor.

It has been observed that the bytes available is in an odd state - just saw post near this one in the new posts. So readBytes() likely affected to the extent it is implemented.

If you can post a simple sample and steps for repro it would help confirm the issue and the fix when working.

Related seeming post? :: Teensy-4-0-USB-serial-lockup
 
It may be a bit difficult to produce a simple example. The method that is effected is using the xmodem library I have written and is pretty specific to SPI. I may be able to reproduce it just by blasting a known length of characters to the Teensy over serial and just printing the readBytes return value (count of read bytes), and returning if the count is <> than expected. In theory that should reproduce the issue I am seeing.

Reading over the related post provided, I do think that they are related. I think the problem is that when attempting to read from the serial port while it is being written to (using Serial.readBytes(buffer, length_to_read)), Teensy will attempt to read the number oof bytes requested, but if that number of bytes exceeds the data available at the time of read, it returns only count of bytes available. I may be able to confirm this as well as the struct I am reading into contains a CRC.

I have some work to get done at the moment since I am making some headway, but I will revisit this to produce some examples if it will help to identify and solve possible issues.
 
Good you can see the relation - wasn't sure I read post for proper inference. Xmodem was shown - but nothing about SPI or what the real code does.

USB Stack will be changed with next Beta of TD - that is pending on PJRC timeline - and will need notice of such issues to address them if they don't fall out naturally in the code upgrade.

If related then follow that post and look after it to test your code when it evolves.
 
Status
Not open for further replies.
Back
Top