my new gear...

Dependencies:   mbed

neopixel.cpp

Committer:
yootee
Date:
22 months ago
Revision:
22:394337a4205a
Parent:
3:a9b4b2565a23

File content as of revision 22:394337a4205a:

#include "mbed.h"
#include "neopixel.h"

#if defined(TARGET_NUCLEO_L432KC)

#define PIXEL_WAIT_1_ (6)
#define PIXEL_WAIT_2_ (2)
#define PIXEL_WAIT_3_ (3)
#define PIXEL_WAIT_4_ (5)

#elif defined(TARGET_NUCLEO_F446RE)

#define PIXEL_WAIT_1_ (9)
#define PIXEL_WAIT_2_ (5)
#define PIXEL_WAIT_3_ (4)
#define PIXEL_WAIT_4_ (9)

#else
#error This board is not supported
#endif

NeoPixelOut::NeoPixelOut(PinName pin, int num) : DigitalOut(pin)
{
    normalize = false;
    global_scale = 1.0f;
    num_pixels_ = num;
    strip_.resize(num);
}

// The timing should be approximately 800ns/300ns, 300ns/800ns
inline void NeoPixelOut::byte(register uint32_t byte)
{        
    for (int i = 0; i < 8; i++) {
        gpio_write(&gpio, 1);
        
        // duty cycle determines bit value
        if (byte & 0x80) {
            // one
            for(int j = 0; j < PIXEL_WAIT_1_; j++) asm("NOP");//6 9
            
            gpio_write(&gpio, 0);
            for(int j = 0; j < PIXEL_WAIT_2_; j++) asm("NOP");//2 5
        }
        else {
            // zero
            for(int j = 0; j < PIXEL_WAIT_3_; j++) asm("NOP");//3 4
            
            gpio_write(&gpio, 0);
            for(int j = 0; j < PIXEL_WAIT_4_; j++) asm("NOP");//5 9
        }

        byte = byte << 1; // shift to next bit
    }
    
}

void NeoPixelOut::setPixelColor(uint32_t i,uint8_t r,uint8_t g,uint8_t b){
    setPixelColor(i,color(r, g, b));
}

void NeoPixelOut::setPixelColor(uint32_t i,uint32_t color){
    if(i < num_pixels_){
        buf_.hex = color;
        if (normalize) {
            float sum = buf_.r+buf_.g+buf_.b;
            if(sum != 0){
                float scale = 255.0f/sum;
                buf_.r *= scale;
                buf_.g *= scale;
                buf_.b *= scale;
            }
        }
        buf_.r *= global_scale;
        buf_.g *= global_scale;
        buf_.b *= global_scale;
        
        strip_[i] = buf_;
    }
}

void NeoPixelOut::show(bool flipwait){
    // Disable interrupts in the critical section
    __disable_irq();
    
    for (int i = 0; i < num_pixels_; i++) {
        // Black magic to fix distorted timing
        #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE
        __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
        #endif

        byte((int)strip_[i].g);
        byte((int)strip_[i].r);
        byte((int)strip_[i].b);

        #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE
        __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
        #endif
    }

    __enable_irq();

    if (flipwait) flip();
}

void NeoPixelOut::send(Pixel *colors, uint32_t count, bool flipwait)
{
    changeNum(count);
    Pixel* rgb;
    for (int i = 0; i < count; i++) {
        rgb = colors++;
        setPixelColor(i, rgb->hex);
    }
    show(flipwait);
}

uint32_t NeoPixelOut::color(uint8_t r,uint8_t g,uint8_t b){
    return (uint32_t)b + ((uint32_t)g << 8) + ((uint32_t)r << 16);
}
 
int NeoPixelOut::numPixels(){
    return num_pixels_;
}

void NeoPixelOut::off(bool flag){
    for(int i = 0;i < num_pixels_;i++){
        strip_[i].hex = 0;
    }
    if(flag){
        show();
    }
}

void NeoPixelOut::changeNum(uint32_t num){
    if(num_pixels_ != num){
        strip_.resize(num);
        num_pixels_ = num;
    }
}

void NeoPixelOut::setBrightness(float brightness){
    global_scale = brightness;
}

void NeoPixelOut::flip(void)
{
    wait_us(50);
}