3
\$\begingroup\$

I'm working with an STM32F303 microcontroller configured in slave mode running at 72 MHz, and I've come across some strange behavior that I'm trying to track the origin of. The master first sends across ~40 bytes and clocks them at ~300 KHz. After a 6 ms pause, the master then starts to transmit ~20 bytes at 5 MHz and repeats this behavior indefinitely. Since I have a logic analyzer, I've been using it in conjunction with some debug GPIO pins to find out approximately when the SPI ISR is firing.

During the first set of bytes, the Receive Buffer Not Empty (RXNE) interrupt takes ~0.52 us to trigger after the last bit of the first byte has been clocked in. I would expect that I would see similar behavior for the other set of bytes, but instead, it takes 1.3 us to trigger for the faster clocked bytes.

This is a problem for me, because by the time the 1.3 us has passed, the second byte has already been clocked in when I should have had data ready for it to clock out with it. I've checked my code and it doesn't seem like any other interrupt is firing, and I've also given my SPI handler the highest priority, so it shouldn't be preempted by any other ISR to begin with. I'm positive that speed isn't an issue, because even though the SPI peripheral I'm using is actually clocked at 36 MHz, it should be plenty fast to address a master clocking in bytes at 5 MHz.

My only guess is that it's something hardware related with the STM32? Has anyone seen behavior like this, and or do they know the origin of this? Also any possible workarounds?

\$\endgroup\$
  • \$\begingroup\$ I think we need to see the code, or the smallest case you have. STM32F303 SPI has 32bit FIFOs. Where the interrupt happens could cause differences in interrupt response time. I notice in RM0316 that the FRXTH bit controls when the RXNE is triggered. \$\endgroup\$ – gbulmer Sep 16 '14 at 21:44
1
\$\begingroup\$

I have nothing on the timing difference, but I do have a possible workaround: if you are able to prepare your response frame in advance, use DMA to both send your frame and catch the transmitted frame. I've found the DMA in the STM32F4 to be a bit fiddly to get going, but once you understand the sequence that you have to configure things in it works very well indeed.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your input. I've used DMA many times in the past and I've also had great success like you. For this particular project though, the number of bytes being sent/received isn't necessarily known beforehand, so I was trying to avoid using DMA. \$\endgroup\$ – HD_Mouse Sep 17 '14 at 17:14
  • \$\begingroup\$ @HD_Mouse You could set the DMA transfer sizes to the maximum you expect to see and use an EXTI interrupt on the nSS pin to detect the end of frame and terminate the DMA transfers. \$\endgroup\$ – markt Sep 17 '14 at 22:26
  • \$\begingroup\$ Use a circular DMA buffer + tx interrupt which starts a timer to detect if end of transmission has happened + a half-buffer interrupt to gather information before circulation happens. @HD_Mouse \$\endgroup\$ – Ayhan Apr 17 '15 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.