I'm driving a string of WS2812 LEDs with XMC1100 . WS2812 is an RGB LED with builtin controller, datasheet http://cdn.sparkfun.com/datasheets/Components/LED/WS2812.pdf The WS2812 requires an unusual waveform but with a quite tight signal timing, +/- 150ns (see page 4 of datasheet).
Currently I am using a bit banging approach which relies on a lot of NOPs, this works, but is sensitive to compiler, optimisation and other variances.
So the question is, is there anything in XMC1100 (e.g. with CCUs) that might be able to generate the required waveform more efficiently and more reliably? And ideally, easily portable between different XMC MCUs.
XMC1100 has a clock frequency of 64 MHz, meaning you can achieve CCU4 tick resolution of 15.625 ns with the prescaler initial value 1 (tick resolution = prescaler value / clock frequency). As you can see this resolution is more that sufficient to provide you with the signal that has tolerance lesser than +/- 150 ns. So yes, you should be able to successfully control WS2812 with CCU4 timer.
However, you can also try to use an SPI protocol for your application, while it´s less CPU intensive due to the fact that you can use FIFO buffer. Take a look at the SPI APP with corresponding examples to see the basic operation behind SPI protocol.
Instead I have made some progress with SPI, although unpacking the data into a bitstream for SPI is quite slow. Unfortunately the XMC library code for the SPI module doesn't allow the user to properly overlap unpacking with sending, so I get unwanted gaps in the output waveform. I will need to adapt the library code.
so this is the implementation that I was thinking about.
Some explanations regarding the figure above. From the documentation (page 4), you can see that TH+TL = 1.25us+/-600ns. I´ve defined the period to be exactly 1.25us while it´s easier to have constant period. However, the value may slightly be different depending on our tick resolution, but that´s still much smaller margin for error that this 600ns. As you can see CCU4 timer is set to edge-aligned count down mode, and interrupt should be triggered in case of compare match when counting down event.
Now some calculation. Let´s use the most precise tick resolution for the sake of example. Tick resolution = prescaler value / clock frequency = 15,625 ns. If we want to have a period of 1.25us, we need to count 1.25us/15,625 ns = 80 ticks. This now becomes the timer period value. Depending if you want to generate a "0" or "1", you need to use different compare match value. 0.35 us of 1.25us is 28%, and 28% of 80 ticks is 22.4 which we rounded to 22 or 23 (should be still precise enough). Due to the fact that we use counting down mode, you subtract this value from the period value (80 - 22/23 = 58/57). This becomes your compare match value when you want to generate "0". When you want to generate "1", you need to provide 36 or 35 as a compare match value (80 - ((0,7/1,25) * 80) = 35.2).
I guess the easiest way to verify this would be to use CCU4_SLICE_CONFIG APP. Maybe you´re right that this is not going to work while there is not so much time to go to interrupt handler routine and update the register but try, and let me know how it went.
I haven't been able to find a way to get a condition from the USIC module corresponding to "Transmit Shift Register Empty", which is quite awkward. I also need this for UART so that I can change direction on RS485 transceivers.
It would be possible for you to provide the communication protocol for the WS2812.
I was looking for a lib for the XMC1100 and this LED.
This lib works fine for the ARDUINO IDE.
In my case, I don't use the Arduino IDE, I use DAVE 4.4, we always have this difficulty, as we have many LIbs made for XMC for the Arduino IDE by the Infineon team. But you guys don't do anything for DAVE.
I can't use the Arduino IDE to develop products.
We have DAVE which is an excellent IDE, but it seems that it is being put aside, and the efforts are for the Arduino IDE.
Thanks for sharing your concern. The arduino libraries are maintained so that people can easily start using XMC product from Arduino background. But regarding Dave, it is not being put aside as it is not a priority. The support for XMC will be continues in ModusToolbox, with more features. Our teams are working to give you a better experience with XMC.
Ok, I understand that DAVE will no longer have support. But at the moment the ModusToolbox doesn't present an update for the Dave user to migrate to ModusToolbox. What is the Road Map for migrating from Dave to ModusToolbox? What features?
From the effort I see in the Arduino LIbs, I imagine you should make a port of the Arduino Libs to the Modustoolbox?
After the purchase of Cypress, I feel like XMC has been left out.
The ModusToolbox release will be coming up with a lot of examples which will help the customers to get started with XMC. XMClib based examples can be easily migrated to the new platform. More details on the features of the ModusToolbox will be coming up soon.
#define TXFill ((((USIC0_CH1->TRBSR)&(USIC_CH_TRBSR_TBFLVL_Msk))>>USIC_CH_TRBSR_TBFLVL_Pos))//Check FIFO buffer fill level
#define TXBusy ((((USIC0_CH1->PSR)&(USIC_CH_PSR_ASCMode_BUSY_Msk))>>USIC_CH_PSR_ASCMode_BUSY_Pos))//check busy
#define TXIdle ((((USIC0_CH1->PSR)&(USIC_CH_PSR_ASCMode_TFF_Msk))>>USIC_CH_PSR_ASCMode_TFF_Pos))//Determines if the actual transmit shift out is busy (PCR.TSTEN set to 1 elsewhere to enable)
Again this is UART mode, and I am also using the FIFO, so I check the FIFO fill level, if the busy flag is set and if the TFF flag is set. Check the bit defenitions for the PSR register for SPI to see if it has a similar option.
Just in case PSoC4 (instead of XMC1) could be an alternative for you, then please have a look to https://www.ihastings.com/ws2812-leds/ and download the library from https://www.ihastings.com/downloads/
Or see also some of my projects on www.hackster.io/holger where I am using PSoC and WS2812B.
Thank you very much for the indication, I believe I will have to change from XMC to Psoc4.
I thought your lib was pretty cool, it's well documented.