K64F version

Fork of PololuLedStrip_r8 by Michael Koster

PololuLedStrip.cpp

Committer:
DavidEGrayson
Date:
2013-03-01
Revision:
14:672baf3cf941
Parent:
13:9c72841ec45e
Child:
15:d69eebdee025

File content as of revision 14:672baf3cf941:

#include "PololuLedStrip.h"

bool PololuLedStrip::interruptFriendly = false;

// The three timed delays, in units of half-instructions.
uint8_t led_strip_write_delays[3];

void PololuLedStrip::calculateDelays()
{
    // Get the clock frequency in MHz.
    int f_mhz = SystemCoreClock / 1000000;

    if (f_mhz <= 48)
    {
        // The delays below result in 800/1590 ns pulses and a 2500 ns period on the mbed NXP LPC11U24.        
        led_strip_write_delays[0] = 0;
        led_strip_write_delays[1] = 0;
        led_strip_write_delays[2] = 5 << 1;
    }
    else
    {
        // Try to generally compute what the delays should be for any frequency clock.
        
        // The fudge factors below were experimentally chosen so that we would have
        // 700/1300 ns pulses and a ~ 2500 ns period on the mbed NXP LPC1768 (96 MHz Cortex-M3).
        // If you ever change these numbers, it is important to check the the subtractions below
        // will not overflow in the worst case, which is f_mhz = 48.
        static const uint8_t delay_fudges[] = { 23, 28, 23 };
        
        led_strip_write_delays[0] = 700*f_mhz/1000;
        led_strip_write_delays[1] = 600*f_mhz/1000;
        led_strip_write_delays[2] = 1200*f_mhz/1000;
    
        for(int i = 0; i < 3; i++)
        {
            if (led_strip_write_delays[i] < delay_fudges[i])
            {
                led_strip_write_delays[i] = 0;
            }
            else
            {
                led_strip_write_delays[i] -= delay_fudges[i];
                led_strip_write_delays[i] <<= 1;
            }
        }
    }
}

PololuLedStrip::PololuLedStrip(PinName pinName)
{
    gpio_init(&gpio, pinName, PIN_OUTPUT);
}

void PololuLedStrip::write(rgb_color * colors, unsigned int count)
{
    calculateDelays();

    __disable_irq();   // Disable interrupts temporarily because we don't want our pulse timing to be messed up.

    while(count--)
    {
        led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask);
        colors++;
         
        if (interruptFriendly)
        {
            __enable_irq();
            __nop();
            __nop();
            __nop();
            __disable_irq();
        }
    }
        
    __enable_irq();   // Re-enable interrupts now that we are done.
    wait_us(24);      // Hold the line low for 24 microseconds to send the reset signal.
    
    //*(gpio.reg_set) = gpio.mask;
    //*(gpio.reg_clr) = gpio.mask;

}