Any chance that RC2 fixes the "data and clock must be on separate ports

Any chance that RC2 fixes the “data and clock must be on separate ports for the 2801” problem?

Not yet - because of the way I optimize port and value access, having the two pins on the same port gets tricky, which is something that I used to my advantage to get even faster bit-banging speeds out of the system. Alas, ws2801 doesn’t play nicely with it :frowning:

What I think I might do is if the clock divider is set to anything other than “0” then do the juggling to do extra slow port access, but because with any clock dividers you’re not getting “fastest speed” anyway, that’s ok.

It’s just a tricky piece of logic to get right in all cases (and I"d need to test it on at least 4 MCU’s with at least 3 sets of LED chipsets - alas, my ws2801’s don’t wig out on the same port access! :slight_smile: - and i’m not doing major code that isn’t directly related to my Priceless project until after the 4th of july.

I was really bummed to find out about this ws2801 problem, though :frowning:

Sorry to be the bearer of bad news about the 2801; I appreaciate all the work it takes to maintain and extend the library.

It sure helped me stop pulling hair out when the cause of my 2801 problem (and the workaround of using different ports) was discovered!

Is this because of an optimization to change data values in the same port access that toggles the clock in the non-latching direction, rather than changing data only when clock is stable?

And it affects only some WS2801’s?

It’s actually a side effect of an optimization to pre-compute the values for setting the port registers. Setting a bit in a port register is two clock cycles, setting the port register to a value is one clock cycle. As for the reason for the glitching that happens, apparently with some MCUs just because you set two pins on a port to a value at the same time, the actual voltage levels on the pin may not change together.

When clock and data are on different ports, I only need to cache hi/lo pairs for each of the clock and data pins, and then can do fast setting of those values when bit banging.

When clock and data are on the same port, though - the cached values are datahi_clockhi, datahi_clocklo, datalo_clockhi, datalo_clocklo. To fix this I will need to either punt back to setting bits in the port individually or I will need to cache states based on previous values as well - but then i start running out of registers, and the point of caching gets lost.

I think my plan will be to make it so that if the clock divider field is 0 - allow for clock/data to be changed simultaneously, and with any other value, drop back to using the bit set instructions on. At the same time, I’ll probably also flip things over so that the ARM versions of the library use bit bands to do the value setting, which gets rid of the need to worry about the values of other bits on the port entirely. (And even with out bit bands, on AVR there are ports to set pins specifically hi or lo, where a 1 means “set value hi” or “set value lo” and a 0 means “don’t change anything” - which means you can just write masks out and don’t have to worry about xoring the current value of the port like you do on AVR.

Yea, I was looking at doing optimised TLS3001 a while back (never finished) and the only way I could make it fast enough was to use the hidden io port XOR function you mention at the end of your post. That’s a really handy technique in some circumstances, as it does let you flip one bit in a single cycle, without having to cache all the unchanged bits. I haven’t looked at optimizing the 2801 using that trick tho.

Actually, I was working on handling several strings in parallel. Which is one of the things I’m imagining you might be looking at for other chips. To do that I had to do some pre-manipulation of the data buffer, which doesn’t fit your current paradigm (users can assume their CRGB buffer is unchanged when returning from LEDS.show(), ), but which was OK from mine because the buffer would always be refilled by the upper levels before being sent out to the pixels again.

Thanks for being willing to discuss what’s under the hood, I enjoy that part only a bit less than I enjoy being able to control the lights so nicely.

I have a tls3001 strip at home, and an outline for it, should be straightforward to do - also working on the parallel out thing - it’s the only way I can imagine driving 3500 ws2811s and tm1809s with one due :slight_smile:

Also always happy to talk about under the hood, when things settled down a bit I want to write up the various optimization a I’ve done, how they may be applicable elsewhere, and the bits of code/library that are hopefully designed to be reused by other folks :slight_smile:

You should check out the gpio pin options for the sam8x (the due’s arm chip) or the Freescale k20 in the teensy 3, which I love. So many options for pin/port manipulation :slight_smile:

And just wait until I get my hands on the dma controller. and the usart. Now that the main library rewrite is done, and I’m almost done with the priceless project - I can’t wait to turn my attention to other things :slight_smile:

Yeah, as you know I’m looking forward to the AVR USART option. On a UNO class, it might allow hardware SPI control of a pixel string AND use of SPI peripherals (SD card, ethernet, rf transceiver), or two hardware pixel strings. And I’ve discovered that on an Arduino Mega, controlling a single wire pixel string is about the only use for SPI mode of the extra USARTs - as the Arduino team neglected to bring out ANY of the SCK pins for them.

It looks like I’m going to have to get into the Teensy 3, just too tempting. That you like it so much adds to that.

I think the 3001/3005 may be a bit more complicated than the others. Rather than just data bits like a shift register, they have a packet structure with 15 bit substructures (for each 12 bit channel), and there are three types of packets to interleave. Last I looked into them they were not well documented. Charles Kerr and his colleague finally got them working, but it looks like the forum board where his results were has been taken down.

I have docs on the 3001 saved, and the control/sync packets don’t seem to be much of a problem. The ugly part is the timing requirements. If I read the translation of the spec sheet right, there needs to be constant timing for all the bits. This may be a bit challenging, though I think I can abuse the spi hardware to get what I need, with a little bit of work.

I have docs on the 3001 saved, and the control/sync packets don’t seem to be much of a problem. The ugly part is the timing requirements. If I read the translation of the spec sheet right, there needs to be constant timing for all the bits. This may be a bit challenging, though I think I can abuse the spi hardware to get what I need, with a little bit of work.

Great. I have some of those too, and I look forward to a library to support them!