14

I'm working on a V-USB project that shows up as a Keyboard using an ATmega328p. The USB part is working great (it's not my first V-USB project), but after I start the V-USB stack with usbInit(), all calls to the SD card library fail. If I call the same functions before usbInit(), everything works perfectly.

I use an Arduino clone called Diavolino, but without the Arduino/wiring framework. I have the USB connected to digital I/O 2 and 3, and the SD card to 10-13 (built-in SPI lines).

I looked through the SD card library and found no sign of it using any interrupts or registers other than SPxx. I also grep'd though the V-USB code, but it doesn't even touch the SPxx registers.

The first sign of the problem was when the device disconnected when it was supposed to access the SD card. Then I put usbPoll() and wdt_reset() calls into all SD card handling loops, and found that in case of writing, the card waits forever for acknowledgement from the card after having sent the last two bytes (CRC-16).

The SD card library I use is sd_raw by Roland Riegel.

dnet
  • 241
  • 1
  • 4
  • 2
    It is my understanding that V-USB is very CPU-intensive, and it's probably introducing unacceptable delays into the SPI routines. Normally, SPI operations are not timing-sensitive, but write and erase operations on SPI FLASH definitely are. – Dave Tweed Oct 11 '12 at 13:01
  • The problem is that even read operations didn't work most of the time, and as I've read, SPI comms are done independently as soon as the data and control registers are set by the running code. – dnet Oct 11 '12 at 13:08
  • @DaveTweed - time sensitive in terms of having to wait for the card yes, but in terms of not being able to keep the card waiting for your program?? – Chris Stratton Oct 11 '12 at 13:38
  • 2
    Likely you are waiting on something that either cannot happen or cannot be detected; for example, the I/O pin might have been reconfigured and no longer be an input, or spurious data/clocks could have been sent to the card, getting it into an undesired state. Also make sure that the mechanism by which the SD library accomplishes required delays hasn't been broken or accelerated. – Chris Stratton Oct 11 '12 at 13:40
  • @ChrisStratton I use pins B2-5, so I did `egrep -r '(PIN|DDR|PORT)B' . | grep -v sd_raw` with no sensible results. The required delays are done using the SPI port (dummy reads). I'll try to replace the library with something else, although its implementation seemed pretty close to anything else I've found. – dnet Oct 11 '12 at 14:03
  • @dnet, if you are going to grep, try generating a list file with the objdump that comes with avr gcc, and look there, so that you are sure you are getting everything which has been included. – Chris Stratton Oct 11 '12 at 14:05
  • 3
    You may be having noise or power supply problems, too. Check your rails with a scope and check the SD lines with a logic analyzer to see what's going on. – Jim Paris Oct 11 '12 at 21:46
  • The V-USB implementation depends on getting USB working in a few cycles of the processor(I believe 8 is the key), so I am not surprised that at some points it will hog all the processing. – Gustavo Litovsky Dec 31 '12 at 16:33
  • You could also check if there's a stack overflow happening at some point. Both the USB stack and an SD card library (especially if its also using a filesytem, which you've been spared atleast) can make pretty heavy use of buffers, be CPU intensive generally (mostly for shunting around data, not number crunching), and also tend to have deep call stacks. None of those really bodes well for something as small as an ATMega. Even if there are a functions which use buffers as locals (as opposed to in the heap as 'globals'), you'd be asking for trouble. – Chintalagiri Shashank Jan 28 '13 at 13:13

1 Answers1

1

I had a problem like that with USART and resolved it by changing the watch dog settings. As you know V-USB uses a watch dog and if you put extra time in one operation, the watch dog gets activated. Try deactivating the watch dog and if you see everything goes well, you can change the watch dog time or you can split the interfering code (the SD card codes in your case) into smaller parts and "Resetting" the watch dog between them. But don't forget to re-activate your watch dog after debugging as it is not recommended to use V-USB without that.

Aug
  • 1,561
  • 6
  • 28
  • 63
  • Note that the question mentions having wdt_reset() calls inserted into the SD code; though of course it's possible that this was not done everywhere. – Chris Stratton Sep 10 '13 at 22:00
  • 1
    Yes but it is really worth to try the code with disabling the watch dog. Sometimes especially when the returning data is processed in an interrupt routine, the code gets stuck there and the watch dog gets activated before being reset – Aug Sep 10 '13 at 22:07