Trying to drive some neopixels by bitbanging, but I can’t quite get them to work right. if fudgefactor is omited or defined less than 197, all addressed LEDs glow at full intensity (these are RGBW SK6812 leds) If I set fudgefactor to 200 or greater, the strip almost works but the first LED is always green and the order of the colors don’t match the datasheet (it seems the first 8 bits (MSB) affect green, next byte is red channel, next byte is green channel, blue channel, then white channel. The order is not matching the datasheet.
code:
#include "mbed.h"
#define WAIT_TIME_MS 1000
void neopixel_write(uint32_t packet )
{
uint32_t mask = 0x80000000;
do
{
if(packet & mask)
{
gpio0 = 1;
wait_ns(600 - fudgefactor);
gpio0 = 0;
wait_ns(600 - fudgefactor);
}
else
{
gpio0 = 1;
wait_ns(300 - fudgefactor);
gpio0 = 0;
wait_ns(900 - fudgefactor);
}
mask = mask << 1;
}
while(mask);
gpio0 = 1; // datasheet does not specify if the pin should remain in HIGH state between frames(?)
}
void neopixel_reset()
{
gpio0 = 0;
wait_us(80);
gpio0 = 1; // is this pin supposed to remain high after reset?
}
int main()
{
neopixel_write(0x00000000); // black, but first LED always lights green. behaves like I have a bitwise or with 0x80000000 somewhere.
neopixel_write(0x00000000); // black
neopixel_write(0x00000007); // white
neopixel_write(0x00000700); // blue
neopixel_write(0x00070000); // is red but should be green??
neopixel_write(0x07000000); // is green but should be red??
neopixel_reset();
}
I think the issue is that I don’t know how fast gpio library is. The target is STM32F411CEU6, and looking through the source code for the DigitalOut, there are many levels of abstraction, I was hoping that at compile time, setting a GPIO equal to a literal would compile down to a single instruction direct port manipulation.
If this isn’t the case, then is there a hardware-agnostic way to retrieve the GPIO mask and port to flip the pin quickly? I know Arduino has digitalPinToPort and digitalPinToBitMask function, is there an equivalent for MBED?