Simple neopixel (WS2812) library, tuned for stm32 (L432) at 80 MHz Should be compatible with any stm32, different clock speed may require timing adjustments in neopixel.c

Dependents:   NEOPIXEL_SAMPLE ppd

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers neopixel.cpp Source File

neopixel.cpp

00001 #include "mbed.h"
00002 #include "neopixel.h"
00003 
00004 NeoPixelOut::NeoPixelOut(PinName pin) : DigitalOut(pin)
00005 {
00006      normalize = false;
00007      global_scale = 1.0f;
00008 }
00009 
00010 // The timing should be approximately 800ns/300ns, 300ns/800ns
00011 void NeoPixelOut::byte(register uint32_t byte)
00012 {        
00013     for (int i = 0; i < 8; i++) {
00014         gpio_write(&gpio, 1);
00015         
00016         // duty cycle determines bit value
00017         if (byte & 0x80) {
00018             // one
00019             for(int j = 0; j < 6; j++) __NOP();
00020             
00021             gpio_write(&gpio, 0);
00022             for(int j = 0; j < 2; j++) __NOP();
00023         }
00024         else {
00025             // zero
00026             for(int j = 0; j < 2; j++) __NOP();
00027             
00028             gpio_write(&gpio, 0);
00029             for(int j = 0; j < 5; j++) __NOP();
00030         }
00031 
00032         byte = byte << 1; // shift to next bit
00033     }
00034     
00035 }
00036 
00037 void NeoPixelOut::send(Pixel *colors, uint32_t count, bool flipwait)
00038 {
00039     // Disable interrupts in the critical section
00040     __disable_irq();
00041 
00042     Pixel* rgb;
00043     float fr,fg,fb;
00044     for (int i = 0; i < count; i++) {
00045         rgb = colors++;
00046         fr = (int)rgb->r;
00047         fg = (int)rgb->g;
00048         fb = (int)rgb->b;
00049         
00050         if (normalize) {
00051             float scale = 255.0f/(fr+fg+fb);           
00052             fr *= scale;
00053             fg *= scale;
00054             fb *= scale;            
00055         }
00056         
00057         fr *= global_scale;
00058         fg *= global_scale;
00059         fb *= global_scale;
00060         
00061         if (fr > 255) fr = 255; 
00062         if (fg > 255) fg = 255;
00063         if (fb > 255) fb = 255;
00064         if (fr < 0) fr = 0; 
00065         if (fg < 0) fg = 0;
00066         if (fb < 0) fb = 0;
00067         
00068         // Black magic to fix distorted timing
00069         #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE
00070         __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
00071         #endif
00072         
00073         byte((int)fg);
00074         byte((int)fr);
00075         byte((int)fb);
00076         
00077         #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE
00078         __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
00079         #endif
00080     }
00081 
00082     __enable_irq();
00083 
00084     if (flipwait) flip();   
00085 }
00086 
00087 
00088 void NeoPixelOut::flip(void)
00089 {
00090     wait_us(50);    
00091 }