How fast is GPIO DigitalOut?

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?

Based on this comment, I think it’s fast.

Have you looked at FastLED? They do that very well but it’s not always compatible with ARM/STM32.

If you can change your LEDs, I’d recommend SPI driven LED strips: Chipset reference · FastLED/FastLED Wiki · GitHub

I personally use the SK9822/APA102, they are amazing.