Teensy 4.0 with OctoWS2811

theSilverFox

New member
I'm using Arduino 1.8.11 / Teensyduino 1.50 with the Teensy 4.0 / OctoWS2811 Adapter Board. When I run the BasicTest I get the following error:

Code:
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/OctoWS2811/OctoWS2811.cpp: In member function 'void OctoWS2811::begin()':
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/OctoWS2811/OctoWS2811.cpp:94:2: error: 'GPIOD_PCOR' was not declared in this scope
  GPIOD_PCOR = 0xFF;
  ^
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/OctoWS2811/OctoWS2811.cpp:177:19: error: 'GPIOD_PSOR' was not declared in this scope
  dma1.destination(GPIOD_PSOR);
                   ^
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/OctoWS2811/OctoWS2811.cpp:184:19: error: 'GPIOD_PDOR' was not declared in this scope
  dma2.destination(GPIOD_PDOR);
                   ^
Error compiling for board Teensy 4.0.

It looks like the OctoWS2811 library isn't currently supported by Teensy 4.0, is there a known workaround or plan to support OctoWS2811 in the future?
 
I was curious, so I thought I would take a quick look,

Looks like this one would be a bit of a challenge and it is not something I have or use... Actually I think I did buy one in my last PJRC purchase, but...

Some of the challenges associated with this include:
The board is setup to use pins: 2, 14, 7, 8, 6, 20, 21, 5 on the T3.x (and LC) which maps to Port pins D0-D7 on T3.6/3.5 (did not look at others, but assume on same Port pins 0-7)

Problem(s) with T4: These pins are not on the same port nor are there any 8 pins that are consecutive bits on the same port, nor does the T4 have 8 bit access to IO ports (access is 32 bits).
These 8 pins are spread out like:(4.4, 1.18, 2.17, 2.16, 2.10, 1.17, 1.16, 4.8)

So I don't see any obvious way to translate the DMA operations used in this library over to something that would work on T4.
My guess is it would take a sort of rethink... For example if one has 8 pins on the same IO buss, could this could be setup to do DMA not to the Data register but only use the SET/CLEAR registers... Or if 8 pins were all on the same FLEX IO controller, could we setup to do this.. Note: would probably need to be FLexIO 1 or 2 as 3 does not have DMA...

So sorry, I don't think I am much help here, probably needs someone like Paul who set this up originally.
 
Awesome! Can you share a little about your method to provide output on an arbitrary set of 8 pins?

It looks like you set up DMA to transfer 32 bits to each of GPIO1, GPIO2, GPIO3, and GPIO4 in sequence (as opposed to the T3 code which transfered 8 bits to a single GPIO) - is that correct?
 
Thanks! I was waiting for this! Directly upgraded two of the LED walls you can see in the video which were using OctoWS2811 on a T3.6 to a T4.0 and the increase in performance makes the animation run way smoother! It went from varying around 40 fps to maxing out at 140 fps (the limit for the amount of leds/strip I'm using). Thank you so much!
 
It looks like you set up DMA to transfer 32 bits to each of GPIO1, GPIO2, GPIO3, and GPIO4 in sequence (as opposed to the T3 code which transfered 8 bits to a single GPIO) - is that correct?

Yes, that's exactly how it works.

Because the data expanded to 128 bits is so large, it's generated on-the-fly into a pair of buffers. DMA scatter-gather is used to seamlessly transition between using each buffer.
 
I've committed code on github for OctoWS2811 on Teensy 4.0.

https://github.com/PaulStoffregen/OctoWS2811/commit/35c6ff24cf0b598cfb5339aa83bf0a2d4c607f13

This will be in Teensyduino 1.52, which will begin beta testing next week.

Im trying to use this with a bno080 over i2c but what happens is, the frame-rate drops for a while then the sensor doesn't return readings anymore. If I don't call leds.show(), the sensor works normally. Could this library interfere with i2c in some way?
I also tried using bno055 on i2c and a different thing happens, works fine for a while then the frame-rate drops and doesn't recover. The sensor still returns values though.

These are the pins I'm using: uint8_t pinList[] = {34, 36 , 28 , 38, 31, 39, 35, 37};

Using bno080 on spi works ok but its not an option for us because of the distance to the sensor. We are making a dress covered in about 3200 leds, and the IMUs are supposed to be in the hands.

Any ideas how I should debug this?
 
After looking a bit more this is what i found so far.

Using the debug feature of the bno080 library I get:

Received: Header: 12 00 05 64 Body: E3 22 0E 01 AC 00 A3 35 00 00 00 00 00 00 Length:18 Channel:Gyro-vector
Received: Header: 12 00 05 66 Body: E3 22 0E 01 AC 00 A3 35 00 00 00 00 00 00 Length:18 Channel:Gyro-vector
Received: Header: 12 00 05 68 Body: E3 22 0E 01 AC 00 A3 35 00 00 00 00 00 00 Length:18 Channel:Gyro-vecto
Received: Header: 12 00 05 6A Body: FF FF FF FF FF FF FF FF FF FF FF FF FF FF Length:18 Channel:Gyro-vector <- this seems to be where the problem starts
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
Received: Header: 14 01 00 00 Body: 00 01 04 00 00 00 00 80 06 31 2E 30 2E 30 00 02 Length:276 Channel:Command <- still figuring out
Received: Header: 14 00 02 00 Body: F1 00 84 00 00 00 01 00 00 00 00 00 00 00 00 00 Length:20 Channel:Control <- what these two mean
Received: Header: 05 00 01 00 Body: 01 Length:5 Channel:Executable <- this means the sensor reset itself


The library first reads four bytes to get the header and figure out how many bytes are coming then reads the rest in a separate read. In the packet where the problem starts this second read seems to fail for some reason.
 
I don't know how to really interpret this but it seems the library somehow borks i2c.

Another debug trace:

Received: Header: 12 00 05 BA Body: 4B 10 FF 02 D0 00 D0 3D 00 00 00 00 00 00 Length:18 Channel:Gyro-vector
Received: Header: 12 00 05 BC Body: 4B 10 FF 02 FF FF FF FF FF FF FF FF FF FF Length:18 Channel:Gyro-vector <- sh*t hits the fan
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout everything below here just means the sensor reset itself and is sending another 'hello im here, this is who i am'
Received: Header: 14 01 00 00 Body: 00 01 04 00 00 00 00 80 06 31 2E 30 2E 30 00 02 Length:276 Channel:Command
Received: Header: 14 00 02 00 Body: F1 00 84 00 00 00 01 00 00 00 00 00 00 00 00 00 Length:20 Channel:Control
Received: Header: 05 00 01 00 Body: 01 Length:5 Channel:Executable


Screenshot 2020-05-20 at 14.37.51.jpg

The image shows a logic analyser trace at the point it all borks.
 
Can you try it with all the LEDs disconnected, so Teensy does all the same things but no LEDs actually receive the data. The idea is to check whether their massive changes in power consumption are somehow interfering? Spending a lot of time on the software side would be a shame if the problem is due to power.
 
Hey Paul, yes I tried doing that early on. Actually as I'm trying to debug this I only have the control box and nothing but the IMU connected. The only thing that helps is not calling leds.show(). Without that call the IMU works for hours (left it over night), with the call, i2c freezes (teensy stops clocking) in less than 10 seconds. I pretty much tried everything I know to find out what is going on. Debugging OctoWS2811 is WAY over my head.
 
Will the Teensy 4,1 also work seamlessly with the OctoWS2811 PCB and Teensyduino 1.52 ?

Yes, Teensy 4.1 works with the OctoWS2811 board.

For "seamlessly", you need to get the 14 pin sockets and tall 14 pin headers. Used together, these stack up to vertically position Teensy 4.1 (or 3.5 or 3.6) so the longer part of the board overhangs the RJ45 jacks. If you use only normal length header pins, it physically won't fit.

On Teensy 4.0 or 4.1, the OctoWS2811 can be configured to use any combination of digital pins. But the default setting is the same set of 8 pins used on Teensy 3.x, so it will "just work" with the OctoWS2811 board.



I'm assuming the 60K EEPROM emulationn that applies to the Teensy 4.0 will also apply to the 4.1?

Yes, but it's not 60K. On Teensy 4.1 the top 252K (just below the 4K restore program) is used for eeprom emulation.

The actual emulated size is 4284 bytes. Details here:

https://www.pjrc.com/teensy/td_libs_EEPROM.html
 
Yes, that's exactly how it works.

Because the data expanded to 128 bits is so large, it's generated on-the-fly into a pair of buffers. DMA scatter-gather is used to seamlessly transition between using each buffer.

Does this mean you can drive more than 8 WS2811 strings on the Teensy 4? Looks like you can do as many strings as there are data pins when I skimmed through the code. If so, that's a pretty impressive feature I haven't seen specifically called out anywhere.
 
Hey Paul, yes I tried doing that early on. Actually as I'm trying to debug this I only have the control box and nothing but the IMU connected. The only thing that helps is not calling leds.show(). Without that call the IMU works for hours (left it over night), with the call, i2c freezes (teensy stops clocking) in less than 10 seconds. I pretty much tried everything I know to find out what is going on. Debugging OctoWS2811 is WAY over my head.

Did this get resolved? I'm thinking of getting a teensy to use with OctoWS2811 but not sure whether teensy 4 or teensy 3 will be best at this point.
 
Did this get resolved?

For future reference yes it did. Be careful not to use the library through the arduino menu - the up to date version is installed and accessible already by arduino by the teensyduino installer.
 
Back
Top