school project using led strip

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