0

NeoPixel error: "CPU SPEED NOT SUPPORTED" - easy fix!
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

NeoPixel error: "CPU SPEED NOT SUPPORTED" - easy fix!

by 626pilot on Wed Mar 12, 2014 3:41 am

I'm working on a Sanguino derivative, using an ATMega644P-20PU at 20MHz. I bought a bunch of PermaProto boards, NeoPixel rings, and SOIC-8 breakouts from Adafruit. Unfortunately, when I tried to compile the example code, it complained that the CPU speed was not supported. It looks like the communication routines use hand-coded assembly. I haven't written anything in assembly since 1997, so I feel a little rusty! However, I tried increasing the speed limit on the 16MHz code to 21MHz and uploaded, and sure enough:

644.png
644.png (321.66 KiB) Viewed 2145 times


The change is simple. Around line 550 of Adafruit_NeoPixel.cpp, find:

// 16 MHz(ish) AVR --------------------------------------------------------
#elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L)

Change that last number from 19000000L to 21000000L. That's it!

By the way, I noticed interrupts are disabled when it's clocking out the data stream. Is that likely to interfere with stuff that runs over I2C and SPI? I need to be able to use those too.

626pilot
 
Posts: 25
Joined: Thu Feb 20, 2014 12:53 pm

Re: NeoPixel error: "CPU SPEED NOT SUPPORTED" - easy fix!

by adafruit_support_rick on Wed Mar 12, 2014 11:13 am

I2C interrupts will be delayed, but they should not be lost. SPI doesn't specifically rely on interrupts. The timing of the NeoPixel data transfer is critical enough that interrupts must be disabled during the transfer.

adafruit_support_rick
 
Posts: 35095
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: NeoPixel error: "CPU SPEED NOT SUPPORTED" - easy fix!

by 626pilot on Wed Mar 12, 2014 6:44 pm

I have read some opinions that the timing for NeoPixel stuff is so critical that the Arduino won't have time for much else, but that can be put to bed. I did some profiling and discovered that it takes about 570 microseconds to shift out one sequence of 24 colors. That's less than 1% duty cycle! It's hand-coded clock-cycle-specific assembly, so it should be the same on a 16MHz chip. The controller should have plenty of time for everything else it does. I guess it could "lag" some I2C/SPI communication a little, but if it's going by the ATMega's supplied clock signal I guess it'll be alright. It doesn't seem to interfere with serial running at 57600 either.

626pilot
 
Posts: 25
Joined: Thu Feb 20, 2014 12:53 pm

Re: NeoPixel error: "CPU SPEED NOT SUPPORTED" - easy fix!

by 1chicagodave on Wed Mar 12, 2014 7:07 pm

626Pilot wrote:I have read some opinions that the timing for NeoPixel stuff is so critical that the Arduino won't have time for much else, but that can be put to bed. I did some profiling and discovered that it takes about 570 microseconds to shift out one sequence of 24 colors. That's less than 1% duty cycle! It's hand-coded clock-cycle-specific assembly, so it should be the same on a 16MHz chip. The controller should have plenty of time for everything else it does. I guess it could "lag" some I2C/SPI communication a little, but if it's going by the ATMega's supplied clock signal I guess it'll be alright. It doesn't seem to interfere with serial running at 57600 either.


Did you calculate or measure the NeoPixel timing? That's pretty accurate -

Running at 20MHZ, each clock tick takes 1/20,000,000 seconds.
Each bit of color info takes 20 clock ticks == 1 us/bit
Each pixel takes 24 bits == 24 us/pixel
You have 24 pixels == 576 us/update

The colors only get updated when strip.show() is called. And, that only needs to be called whenever there is a change in colors to be made. — Though, most code you'll find is written to update pixels regardless of any changes. — The pixels will hold the last value until updated again (or they lose power). Interrupts are only disabled while actually clocking data out to the pixels (with strip.show() ). So, as long as you don't initiate a strip.show() during another interrupt-dependent operation....you should be fine.
Please forgive my hyperanthropomorphization.
Every answer reveals new questions.
And, yes... there's always a better way to 'do that'.
1chicagodave
 
Posts: 564
Joined: Wed Jun 19, 2013 3:35 am
Location: Chicago

Please be positive and constructive with your questions and comments.