This library lets you control the addressable RGB LED strips from Pololu Robotics & Electronics.

Dependents:   WoYaoChengGOng V2-WoYaoChengGOng STM32_MagneticLight tape_Led_Sample ... more

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     calculateDelays();
00056 
00057     __disable_irq();   // Disable interrupts temporarily because we don't want our pulse timing to be messed up.
00058 
00059     while(count--)
00060     {
00061         led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask);
00062         colors++;
00063          
00064         if (interruptFriendly)
00065         {
00066             __enable_irq();
00067             __nop();
00068             __nop();
00069             __nop();
00070             __disable_irq();
00071         }
00072     }
00073         
00074     __enable_irq();   // Re-enable interrupts now that we are done.
00075     wait_us(80);      // Send the reset signal.
00076 }