WS2812B
Dependents: high speed light Bracelet
Fork of PololuLedStrip by
PololuLedStrip.cpp@14:672baf3cf941, 2013-03-01 (annotated)
- Committer:
- DavidEGrayson
- Date:
- Fri Mar 01 05:00:49 2013 +0000
- Revision:
- 14:672baf3cf941
- Parent:
- 13:9c72841ec45e
- Child:
- 15:d69eebdee025
Cleaned up calculateDelays and made it work on the M0 48MHz again.
Who changed what in which revision?
User | Revision | Line number | New 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 | 14:672baf3cf941 | 5 | // The three timed delays, in units of half-instructions. |
DavidEGrayson | 7:9a088f042ee0 | 6 | uint8_t led_strip_write_delays[3]; |
DavidEGrayson | 4:d3b60bd43811 | 7 | |
DavidEGrayson | 7:9a088f042ee0 | 8 | void PololuLedStrip::calculateDelays() |
DavidEGrayson | 7:9a088f042ee0 | 9 | { |
DavidEGrayson | 8:1578776ceac5 | 10 | // Get the clock frequency in MHz. |
DavidEGrayson | 8:1578776ceac5 | 11 | int f_mhz = SystemCoreClock / 1000000; |
DavidEGrayson | 14:672baf3cf941 | 12 | |
DavidEGrayson | 14:672baf3cf941 | 13 | if (f_mhz <= 48) |
DavidEGrayson | 14:672baf3cf941 | 14 | { |
DavidEGrayson | 14:672baf3cf941 | 15 | // The delays below result in 800/1590 ns pulses and a 2500 ns period on the mbed NXP LPC11U24. |
DavidEGrayson | 14:672baf3cf941 | 16 | led_strip_write_delays[0] = 0; |
DavidEGrayson | 14:672baf3cf941 | 17 | led_strip_write_delays[1] = 0; |
DavidEGrayson | 14:672baf3cf941 | 18 | led_strip_write_delays[2] = 5 << 1; |
DavidEGrayson | 14:672baf3cf941 | 19 | } |
DavidEGrayson | 14:672baf3cf941 | 20 | else |
DavidEGrayson | 14:672baf3cf941 | 21 | { |
DavidEGrayson | 14:672baf3cf941 | 22 | // Try to generally compute what the delays should be for any frequency clock. |
DavidEGrayson | 14:672baf3cf941 | 23 | |
DavidEGrayson | 14:672baf3cf941 | 24 | // The fudge factors below were experimentally chosen so that we would have |
DavidEGrayson | 14:672baf3cf941 | 25 | // 700/1300 ns pulses and a ~ 2500 ns period on the mbed NXP LPC1768 (96 MHz Cortex-M3). |
DavidEGrayson | 14:672baf3cf941 | 26 | // If you ever change these numbers, it is important to check the the subtractions below |
DavidEGrayson | 14:672baf3cf941 | 27 | // will not overflow in the worst case, which is f_mhz = 48. |
DavidEGrayson | 14:672baf3cf941 | 28 | static const uint8_t delay_fudges[] = { 23, 28, 23 }; |
DavidEGrayson | 14:672baf3cf941 | 29 | |
DavidEGrayson | 14:672baf3cf941 | 30 | led_strip_write_delays[0] = 700*f_mhz/1000; |
DavidEGrayson | 14:672baf3cf941 | 31 | led_strip_write_delays[1] = 600*f_mhz/1000; |
DavidEGrayson | 14:672baf3cf941 | 32 | led_strip_write_delays[2] = 1200*f_mhz/1000; |
DavidEGrayson | 8:1578776ceac5 | 33 | |
DavidEGrayson | 14:672baf3cf941 | 34 | for(int i = 0; i < 3; i++) |
DavidEGrayson | 12:b6df8ac053c8 | 35 | { |
DavidEGrayson | 14:672baf3cf941 | 36 | if (led_strip_write_delays[i] < delay_fudges[i]) |
DavidEGrayson | 14:672baf3cf941 | 37 | { |
DavidEGrayson | 14:672baf3cf941 | 38 | led_strip_write_delays[i] = 0; |
DavidEGrayson | 14:672baf3cf941 | 39 | } |
DavidEGrayson | 14:672baf3cf941 | 40 | else |
DavidEGrayson | 14:672baf3cf941 | 41 | { |
DavidEGrayson | 14:672baf3cf941 | 42 | led_strip_write_delays[i] -= delay_fudges[i]; |
DavidEGrayson | 14:672baf3cf941 | 43 | led_strip_write_delays[i] <<= 1; |
DavidEGrayson | 14:672baf3cf941 | 44 | } |
DavidEGrayson | 12:b6df8ac053c8 | 45 | } |
DavidEGrayson | 12:b6df8ac053c8 | 46 | } |
DavidEGrayson | 7:9a088f042ee0 | 47 | } |
DavidEGrayson | 6:9d0530b7dae2 | 48 | |
DavidEGrayson | 1:102307d9b701 | 49 | PololuLedStrip::PololuLedStrip(PinName pinName) |
DavidEGrayson | 1:102307d9b701 | 50 | { |
DavidEGrayson | 1:102307d9b701 | 51 | gpio_init(&gpio, pinName, PIN_OUTPUT); |
DavidEGrayson | 1:102307d9b701 | 52 | } |
DavidEGrayson | 1:102307d9b701 | 53 | |
DavidEGrayson | 1:102307d9b701 | 54 | void PololuLedStrip::write(rgb_color * colors, unsigned int count) |
DavidEGrayson | 1:102307d9b701 | 55 | { |
DavidEGrayson | 8:1578776ceac5 | 56 | calculateDelays(); |
DavidEGrayson | 8:1578776ceac5 | 57 | |
DavidEGrayson | 1:102307d9b701 | 58 | __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up. |
DavidEGrayson | 7:9a088f042ee0 | 59 | |
DavidEGrayson | 1:102307d9b701 | 60 | while(count--) |
DavidEGrayson | 1:102307d9b701 | 61 | { |
DavidEGrayson | 9:6ffb85d69eaf | 62 | led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask); |
DavidEGrayson | 9:6ffb85d69eaf | 63 | colors++; |
DavidEGrayson | 9:6ffb85d69eaf | 64 | |
DavidEGrayson | 1:102307d9b701 | 65 | if (interruptFriendly) |
DavidEGrayson | 1:102307d9b701 | 66 | { |
DavidEGrayson | 1:102307d9b701 | 67 | __enable_irq(); |
DavidEGrayson | 1:102307d9b701 | 68 | __nop(); |
DavidEGrayson | 1:102307d9b701 | 69 | __nop(); |
DavidEGrayson | 1:102307d9b701 | 70 | __nop(); |
DavidEGrayson | 1:102307d9b701 | 71 | __disable_irq(); |
DavidEGrayson | 1:102307d9b701 | 72 | } |
DavidEGrayson | 1:102307d9b701 | 73 | } |
DavidEGrayson | 1:102307d9b701 | 74 | |
DavidEGrayson | 1:102307d9b701 | 75 | __enable_irq(); // Re-enable interrupts now that we are done. |
DavidEGrayson | 1:102307d9b701 | 76 | wait_us(24); // Hold the line low for 24 microseconds to send the reset signal. |
DavidEGrayson | 9:6ffb85d69eaf | 77 | |
DavidEGrayson | 9:6ffb85d69eaf | 78 | //*(gpio.reg_set) = gpio.mask; |
DavidEGrayson | 9:6ffb85d69eaf | 79 | //*(gpio.reg_clr) = gpio.mask; |
DavidEGrayson | 9:6ffb85d69eaf | 80 | |
DavidEGrayson | 1:102307d9b701 | 81 | } |