Hi,
I wrote a small script to drive 10 WS2812 LEDs. From time to time an error in the transferred color codes appears, and I tracked it down to a random stalling of the SPI transfer. Channel 0 is MOSI and Channel 1 is SCK. The transfer gets interrupted two times:
For driving such LEDs, this is not good, of course, since the timing is quite tight, and halting the transfer for too long gets interpreted as the end of the transfer and the new color values get latched.
Any idea why this happens, and how to prevent it?
The complete script can be found in this post: http://forum.micropython.org/viewtopic. ... t=108#p580
Stalled SPI Transfer
Re: Stalled SPI Transfer
Is this from a single invocation of spi.send ?
If not, then I would expect there to be a pause between each call to spi.send (even if this were coded in C).
The typical way of combating this is to have some type of FIFO. If the HW doesn't provide one, then you can sometimes implement one using DMA.
If not, then I would expect there to be a pause between each call to spi.send (even if this were coded in C).
The typical way of combating this is to have some type of FIFO. If the HW doesn't provide one, then you can sometimes implement one using DMA.
- Markus Gritsch
- Posts: 41
- Joined: Fri May 16, 2014 9:04 pm
Re: Stalled SPI Transfer
Yes, this is a single SPI.send() transfer. It does not get interrupted most of the time, but now and then (on the scale of 1 stalled out of 100 unstalled) an interruption happens.
Re: Stalled SPI Transfer
OK - spi.send winds up calling HAL_SPI_Transmit which basically just has a loop in C which send 16 bits at a time to the SPI peripheral.
I'm going to guess that the gaps are caused by interrupts (millisecond tick timer, USB, etc).
So I think that you have 2 options:
1 - disable interrupts around the call to spi.send (pyb.disable_irq()/pyb.enable_irq())
2 - Fix spi.send to use DMA
Disabling interrupts for long periods of time may cause other problems. For example, disabling interrupts for more than a millisecond may cause timer ticks to get missed.
I'm going to guess that the gaps are caused by interrupts (millisecond tick timer, USB, etc).
So I think that you have 2 options:
1 - disable interrupts around the call to spi.send (pyb.disable_irq()/pyb.enable_irq())
2 - Fix spi.send to use DMA
Disabling interrupts for long periods of time may cause other problems. For example, disabling interrupts for more than a millisecond may cause timer ticks to get missed.
- Markus Gritsch
- Posts: 41
- Joined: Fri May 16, 2014 9:04 pm
Re: Stalled SPI Transfer
Thanks, this seems to fix the problem! I have it running for quite some time now, without any stallsdhylands wrote:1 - disable interrupts around the call to spi.send (pyb.disable_irq()/pyb.enable_irq())

I added a ticket/feature request for option 2: https://github.com/micropython/micropython/issues/685
BTW, thanks for doing such a great job on this forum. You and pfalcon seem to run this almost exclusively.