This library lets you control the addressable RGB LED strips from Pololu Robotics. Forked to add selectable colour order (Support RGB or GRB Leds)

Fork of PololuLedStrip by David Grayson

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PololuLedStrip.cpp Source File

PololuLedStrip.cpp

00001 #include "PololuLedStrip.h"
00002 
00003 // Our assembly code currently does not work with chip families like the STM32F4
00004 // that use the same register and a different mask for setting and clearing
00005 // outputs.
00006 #ifdef GPIO_IP_WITHOUT_BRR
00007 #error This chip is not supported: does not have separate registers for setting and clearing GPIO outputs.
00008 #endif
00009 
00010 bool PololuLedStrip::interruptFriendly = false;
00011 
00012 // The two timed delays, in units of half-cycles.
00013 uint8_t led_strip_write_delays[2];
00014 
00015 void PololuLedStrip::calculateDelays()
00016 {
00017     int f_mhz = SystemCoreClock / 1000000;   // Clock frequency in MHz.
00018 
00019     if (f_mhz <= 48)
00020     {
00021         // The delays below result in 360/1120 ns pulses and a 1880 ns period on the mbed NXP LPC11U24.        
00022         led_strip_write_delays[0] = 0;
00023         led_strip_write_delays[1] = 0;
00024     }
00025     else
00026     {
00027         // Try to generally compute what the delays should be for a wide range of clock frequencies.
00028         
00029         // The fudge factors below were experimentally chosen so that we would have
00030         // ~100 ns and ~840 ns pulses and a ~1430 ns period on the mbed NXP LPC1768 (96 MHz Cortex-M3).
00031         // There seem to be some ~100 ns inconsistencies in the timing depending on which example program is
00032         // running; the most likely explanation is some kind of flash caching that affects the timing.
00033         // If you ever change these numbers, it is important to check the the subtractions below
00034         // will not overflow in the worst case (smallest possible f_mhz).
00035         //
00036         // On an STM32F303K8 (72 MHz Cortex-M4), these delays give us ~170 ns and ~840 ns pulses
00037         // and a ~1595 ns period, and there were no timing differences between the two
00038         // example programs.
00039         led_strip_write_delays[0] = 750*f_mhz/1000 - 33;
00040         led_strip_write_delays[1] = 550*f_mhz/1000 - 20;    
00041     }
00042  
00043     // Convert from units of cycles to units of half-cycles; it makes the assembly faster.   
00044     led_strip_write_delays[0] <<= 1;
00045     led_strip_write_delays[1] <<= 1;
00046 }
00047 
00048 PololuLedStrip::PololuLedStrip(PinName pinName)
00049 {
00050     gpio_init_out(&gpio, pinName);
00051 }
00052 
00053 void PololuLedStrip::write(rgb_color * colors, unsigned int count)
00054 {
00055     uint8_t t;
00056     calculateDelays();
00057     
00058     __disable_irq();   // Disable interrupts temporarily because we don't want our pulse timing to be messed up.
00059 
00060     while(count--)
00061     {
00062 
00063 #ifdef _POLOLU_ORDER_GRB
00064         //swap red and green for WS2812b strips
00065         t = colors->red;
00066         colors->red = colors->green;
00067         colors->green = t;
00068 #endif
00069 
00070         led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask);
00071         colors++;
00072          
00073         if (interruptFriendly)
00074         {
00075             __enable_irq();
00076             __nop();
00077             __nop();
00078             __nop();
00079             __disable_irq();
00080         }
00081     }
00082         
00083     __enable_irq();   // Re-enable interrupts now that we are done.
00084     wait_us(80);      // Send the reset signal.
00085 }