cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Communication with TIM1

longchair
Associate III
Posted on September 23, 2012 at 11:10

Hello everyone,

In my current project, I am working with Digital ledstrips. The strips I want to use have a WS2811 chip which is basically running a 1 Wire SPI interface (no clock Line).

I will try to explain roughly how this works.

RGB values are send on the bus line with the following encoding.

bits are encoded on the line with PWM dutycycles over a 800Khz base frequency.

basically :

0 = 20% Duty cycle

1 = 48% Duty cycle

From what I have looked in the documentation, SPI works on a divider over main frequency and 800Khz will not be a standard frequency .. closest being around 525Khz.

Therefore I thought that using TIM1 might be an option. configuring it to run 800Khz. then I need to update the PWM dutycycle. From the samples in the libraries, I looked at the DMA sample which allows to update the DutyCycle. though as I must update it to each cycle and that one update = 1 data bit, I am a bit worried about the data volume I'll need to keep for a full frame.

Actually the barled will have around 300 Leds. each leds requires 24 Bits for RGB.

that makes :

300 Leds * 24 Bits * (2 bytes per bit to define the duty cycle) = 14Kbytes of data for a frame.

That is way too much for the internal memory, and I guess that we cannot run dma from flash.

The other option would be to handle the TIM1 interrup and update the duty cycle with the next bit to send. Though I supposed that having an interrupt at 800 Khz is not a good idea.

if you have any suggestions for this application, That would be appreciated 🙂

9 REPLIES 9
Posted on September 23, 2012 at 18:19

Yeah, a 800 KHz interrupt probably not a good thing.

DMA is the way to go, you don't need to do the whole thing, perhaps you could use a 48 word circular buffer, interrupt off the HT (Half Transfer), and TC (Transfer Complete), and use those to build output ''words'' for the alternating LEDs in the array. This would decimate the interrupt loading, and the memory footprint.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
longchair
Associate III
Posted on September 27, 2012 at 08:58

HI Clive,

I tried DMA to update the pwm duty cycle with a prepared table for the 256 bytes values encoded each in 48 bytes.

As the timing is quite tight and that I must ensure that there is less than 50µs between each RGB packet, I have used the flash to store the big data (about 300 leds packet). I store them into flash (its a 14k packet) and i can run the dma trasfer directly from flash which is good to save the ram. it looks to work so far even if I haven't tried with the 300 leds yet 🙂

longchair
Associate III
Posted on September 28, 2012 at 09:57

Well here is the follow up.

Flash reading and DMA transfer works fine, but trying to use double buffer with flash is not a good idea for two points :

- Reading / writting flash at high rates will reduce stringly it's lifetime.

- To work in double buffer, you need to erase the flash and this operation is slow. It takes about 80ms to have my flash buffer erased, which reduces my output update frequency around 10Hz.

I have checked that I can use my ledstrip at two frequencies. 400Khz & 800Khz.

I will check what you mention clive. one pixel data buffer that would be used for dma dutycycle on TIM1 is 48 bytes. I could of course use a buffer containing 96 bytes for two leds data and use half buffer interrupt. But my question is :

one half buffer transfer will take 60µs, so it means I will have an interrupt each 60µs. that is a 16Khz interrupt Rate.

At each interrupt I will need to transfer 48 bytes from flash to main memory, to update teh half buffer.

What do you think of this scenario in terms of load on the CPU ? is it still reasonnable of will it completely overload the chip ?

Posted on September 28, 2012 at 12:07

I'm not convinced flash is required at all for this application's data.

Assuming at STM32F1 @ 72 MHz, you have 4285 cycles to play with in 60us. Should be doable with some efficient coding, and will be busy.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Ian Legg
Senior
Posted on November 04, 2015 at 11:21

Hello,

I realise this is a few years ago now but did you ever get this working as you wanted on the WS2811? I was wondering if the same technique/code would run on an STM8L part?

Thanks,

Ian

Posted on November 04, 2015 at 19:02

I'm not a user of STM8 parts, you'd have to review the TIM/DMA functionality and connectivity.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Amel NASRI
ST Employee
Posted on November 10, 2015 at 17:52

Hi Ian,

If not yet done, I suggest you ask your question in the STM8 forum.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Ian Legg
Senior
Posted on November 12, 2015 at 14:13

Hello Mayla, Clive,

Thank you both for your input. I'd noticed from the original poster that an 800KHz interrupt is not really possible with a 16MHz clock, even if the DMA capabilities are present in an STM8L!

However, I've discovered that the timing for an WS2811 is not as critical as one might think and thus making it perfectly achievable on an STM8L 🙂 See the following if you're interested by Josh:

http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/

Thanks,

Ian

Posted on November 12, 2015 at 15:10

The goal of the DMA is to provide the data for 10, or 100, patterns, and thus decimate the interrupt loading.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..