WS2812B

Dependents:   high speed light Bracelet

Fork of PololuLedStrip by David Grayson

Committer:
DavidEGrayson
Date:
Fri Mar 01 04:34:54 2013 +0000
Revision:
12:b6df8ac053c8
Parent:
10:f1bb84b97788
Child:
13:9c72841ec45e
Introduced the delay_fudges array.  The code still works for the M0.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DavidEGrayson 1:102307d9b701 1 #include "PololuLedStrip.h"
DavidEGrayson 1:102307d9b701 2
DavidEGrayson 1:102307d9b701 3 bool PololuLedStrip::interruptFriendly = false;
DavidEGrayson 1:102307d9b701 4
DavidEGrayson 7:9a088f042ee0 5 uint8_t led_strip_write_delays[3];
DavidEGrayson 4:d3b60bd43811 6
DavidEGrayson 12:b6df8ac053c8 7 static const uint8_t delay_fudges[] = { 32, 0, 0 };
DavidEGrayson 12:b6df8ac053c8 8
DavidEGrayson 7:9a088f042ee0 9 void PololuLedStrip::calculateDelays()
DavidEGrayson 7:9a088f042ee0 10 {
DavidEGrayson 8:1578776ceac5 11 // Get the clock frequency in MHz.
DavidEGrayson 8:1578776ceac5 12 int f_mhz = SystemCoreClock / 1000000;
DavidEGrayson 8:1578776ceac5 13
DavidEGrayson 8:1578776ceac5 14 // Arrange for a 700 nanosecond delay between the rise time and the fall time for a 0 bit.
DavidEGrayson 10:f1bb84b97788 15 led_strip_write_delays[0] = 700*f_mhz/1000 - 32;
DavidEGrayson 8:1578776ceac5 16
DavidEGrayson 8:1578776ceac5 17 // Arrange for a 600 nanosecond delay between the fall time for a 0 bit and the fall time for a 1 bit.
DavidEGrayson 8:1578776ceac5 18 // This means the pulses representing a 1 will be 700+600 = 1300 nanoseconds.
DavidEGrayson 12:b6df8ac053c8 19 led_strip_write_delays[1] = 600*f_mhz/1000;
DavidEGrayson 8:1578776ceac5 20
DavidEGrayson 8:1578776ceac5 21 // Arrange for a 1200 nanosecond delay between the fall time for a 1 bit and rise time of the next bit.
DavidEGrayson 8:1578776ceac5 22 // This means the period of the signal will be 2500 nanoseconds.
DavidEGrayson 12:b6df8ac053c8 23 led_strip_write_delays[2] = 1200*f_mhz/1000;
DavidEGrayson 10:f1bb84b97788 24
DavidEGrayson 12:b6df8ac053c8 25 for(int i = 0; i < 3; i++)
DavidEGrayson 12:b6df8ac053c8 26 {
DavidEGrayson 12:b6df8ac053c8 27 if (led_strip_write_delays[i] < delay_fudges[i])
DavidEGrayson 12:b6df8ac053c8 28 {
DavidEGrayson 12:b6df8ac053c8 29 led_strip_write_delays[i] = 0;
DavidEGrayson 12:b6df8ac053c8 30 }
DavidEGrayson 12:b6df8ac053c8 31 else
DavidEGrayson 12:b6df8ac053c8 32 {
DavidEGrayson 12:b6df8ac053c8 33 led_strip_write_delays[i] -= delay_fudges[i];
DavidEGrayson 12:b6df8ac053c8 34 led_strip_write_delays[i] <<= 1;
DavidEGrayson 12:b6df8ac053c8 35 }
DavidEGrayson 12:b6df8ac053c8 36 }
DavidEGrayson 7:9a088f042ee0 37 }
DavidEGrayson 6:9d0530b7dae2 38
DavidEGrayson 1:102307d9b701 39 PololuLedStrip::PololuLedStrip(PinName pinName)
DavidEGrayson 1:102307d9b701 40 {
DavidEGrayson 1:102307d9b701 41 gpio_init(&gpio, pinName, PIN_OUTPUT);
DavidEGrayson 1:102307d9b701 42 }
DavidEGrayson 1:102307d9b701 43
DavidEGrayson 1:102307d9b701 44 void PololuLedStrip::write(rgb_color * colors, unsigned int count)
DavidEGrayson 1:102307d9b701 45 {
DavidEGrayson 8:1578776ceac5 46 calculateDelays();
DavidEGrayson 8:1578776ceac5 47
DavidEGrayson 1:102307d9b701 48 __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up.
DavidEGrayson 7:9a088f042ee0 49
DavidEGrayson 1:102307d9b701 50 while(count--)
DavidEGrayson 1:102307d9b701 51 {
DavidEGrayson 9:6ffb85d69eaf 52 led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask);
DavidEGrayson 9:6ffb85d69eaf 53 colors++;
DavidEGrayson 9:6ffb85d69eaf 54
DavidEGrayson 1:102307d9b701 55 if (interruptFriendly)
DavidEGrayson 1:102307d9b701 56 {
DavidEGrayson 1:102307d9b701 57 __enable_irq();
DavidEGrayson 1:102307d9b701 58 __nop();
DavidEGrayson 1:102307d9b701 59 __nop();
DavidEGrayson 1:102307d9b701 60 __nop();
DavidEGrayson 1:102307d9b701 61 __disable_irq();
DavidEGrayson 1:102307d9b701 62 }
DavidEGrayson 1:102307d9b701 63 }
DavidEGrayson 1:102307d9b701 64
DavidEGrayson 1:102307d9b701 65 __enable_irq(); // Re-enable interrupts now that we are done.
DavidEGrayson 1:102307d9b701 66 wait_us(24); // Hold the line low for 24 microseconds to send the reset signal.
DavidEGrayson 9:6ffb85d69eaf 67
DavidEGrayson 9:6ffb85d69eaf 68 //*(gpio.reg_set) = gpio.mask;
DavidEGrayson 9:6ffb85d69eaf 69 //*(gpio.reg_clr) = gpio.mask;
DavidEGrayson 9:6ffb85d69eaf 70
DavidEGrayson 1:102307d9b701 71 }