ArduinoCore-samd icon indicating copy to clipboard operation
ArduinoCore-samd copied to clipboard

Cannot receive the data when data length exactly 64 or 128 bytes

Open converse2006 opened this issue 6 years ago • 4 comments

I tried to write the data to Arduino MKR Zero but always read 0 (Serial1.println(SerialUSB.available());) when data size exactly same as 64 bytes or 128 bytes. send 256bytes are fine.

If I work around this by issue another transaction to send the last bytes of 64/128byte data.

#Host side
if len(msg)%64 == 0 and len(msg) != 256:
    self.comm.write(msg[0:len(msg)-1])
    self.comm.write(msg[len(msg)-1:])

Does anyone meet this issue? Thanks

converse2006 avatar Mar 11 '19 03:03 converse2006

Hmm so you see an error at 128 bytes? I am seeing the problem at length%256==64. For instance the MKRZERO will receive the first 256 bytes when sent 320 bytes but the last 64 bytes never get received. I haven't tried 128 yet. I'll try tomorrow and report back.

BTW I have a similar issue report entered in the Arduino forums https://forum.arduino.cc/index.php?topic=602425.0

tozz88 avatar Mar 11 '19 06:03 tozz88

I have run some tests and found the following results. This is all attempting to send a certain size packet of data to the MKRZERO from a PC host.

size results 64 fails 128 fails 192 fails 256 success 320 fails (first 256 bytes delivered) 384 fails (first 256 bytes delivered) 448 fails (first 256 bytes delivered) 512 success 576 fails (first 512 bytes delivered)

As you can see the failure occurs if size%64==0 and size%256!=0 Also all size - size%256 bytes are delivered. its just the residual size%256 bytes that are not.

tozz88 avatar Mar 11 '19 21:03 tozz88

I encountered the same issue and it cost me hours to find out why my controller failed only under certain circumstances. This issue is a major bug that affects obviously different boards. Could this therefore please be put on the milestone list for the next bugfix release of the SAMD21 firmware?

donovaly avatar Oct 10 '19 10:10 donovaly

I'm pretty sure this issue has already been fixed by 3316756b0ce32d334b8798206c5bb88984b396b1 USBDevice: do not use automatic multi-packet USB transactions

I had this issue when using a the Adafruit version of the samd Arduino core, which is missing this commit.

You can read the commit for more details, but I think it's because multi-packet USB transactions were enabled. This defers the USB interrupt until the 256 byte limit is reached, or if receiving a packet which doesn't neatly fit in the 256 byte buffer (see notes below for details on why).

It looks like this commit was first released in version https://github.com/arduino/ArduinoCore-samd/releases/tag/1.8.1, which is after this issue was raised.


Extra notes:

The datasheet has a diagram/more info on the "multi-packet USB transactions" feature, if you want more info on this feature.

The datasheet states "The total number of bytes to be received must be written to PCKSIZE.MULTI_PACKET_SIZE. This value must be a multiple of PCKSIZE.SIZE, otherwise excess data may be written to SRAM locations used by other parts of the application.". This explains why non-multiple of 64 byte packets are not affected by this problem (somewhere along the line, it avoids storing non-multiple of 64 byte packets to avoid the above problem).

drojf avatar Jan 10 '22 11:01 drojf