AT90USB1287 - pieces of eight

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm having a really strange problem with the 90USB1287.

I'm messing around with the 90USBKey and Dean's LUFA package. I've built a CDC application that puts data in and out of the SPI rather than the UART. It all works very nicely, except... If I feed the PC end any multiple of 8 bytes at a time, it locks up. Any other number - 7, 9, 127 etc - works perfectly.

Specifically, the lockup happens on the RX endpoint, which in this application has a 16 byte FIFO. I've debugged it down to register level and it seems that register UEINTX, bit RWAL (read write allowed) never sets if it receives a multiple of 8 bytes - although I should qualify that. If I send (say) 21 bytes all at once, it correctly receives one buffer load of 16 (a multiple of 8 ), allows me to unload it, then receives the other 5, and there's no problem. But if the last buffer load it gets from the PC is 8 or 16 bytes, I can unload the 8 or 16 bytes and clear the endpoint, but RWAL doesn't set on the next packet and it's unrecoverable.

So I ask myself, how does it know the PC has finished sending data, so it doesn't lock up if there's more to come? Well being as it's SPI, for every byte received it generates one to send back. Being as these things are asynchronous and happen in microseconds, I can't be sure what order they happen in, but I presume that if there's a large packet coming in from the PC (more than 16 bytes) there isn't time to generate an IN packet before the next OUT packet arrives, so the lockup may be associated with the OUT packet. But that's on a different endpoint, and it doesn't lock up.

Has anyone else here ever come across this effect? I can't find anything written about it, so I have to conclude I'm overlooking something really simple that everyone else knows.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Peret,

Just to say that I think Dean said he'd set up a specific LUFA support forum somewhere - you may catch up with him quicker there.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Holy cr*p! This was report independently to me only yesterday, after at least a year of being in the wild. The problem is with the way I'm currently handling Endpoint bank checks. I thought I'd be clever back at the start of development and use the RWAL bit to check for packet reception OR write ready state, and FIFOCON only to clear the bank for both IN and OUT endpoints.

That's backfired, as RWAL is not set when an empty packet from the host appears. That's logical - since there are no bytes which can be read, the bank isn't ready for reading!

The solution is to jigger around quite a bit of the internal library code, and make some minor changes to the user code. Now I use the proper RXINI and TXOUTI flags for the checking of banks, which means different macros for IN and OUT endpoints but it's the only way to fix the problem.

The reason behind all this is that the CDC class requires the sender to transmit an empty packet at the end of each transmission, where the last sent packet completely filled the endpoint bank. That's so the receiver can buffer data until it gets a non-full packet, whereupon it can release the buffer to the application.

Please download the latest SVN revision which I've only just finished two or so hours ago, which corrects the problem.

SVN Access: http://code.google.com/p/lufa-lib/
Help Forum: http://groups.google.com/group/m...

If you can't download a working copy of the latest SVN revision yourself, just email/PM me for a copy.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
This was report independently to me only yesterday, after at least a year of being in the wild.

What a strange coincidence! But fortunate for me, since you were already on the case. I noticed the lockups two or three weeks ago and found the no-multiples-of-8 workaround at the weekend, but I didn't track it down to the register level until yesterday. I knew about the empty packet too, but didn't connect it, since 8 bytes doesn't fill the buffer my end. But of course the sender doesn't know how big the receiver buffer is.

Thanks so much, Dean.