This library lets you control the addressable RGB LED strips from Pololu Robotics. Forked to add selectable colour order (Support RGB or GRB Leds)

Fork of PololuLedStrip by David Grayson

Committer:
thegink
Date:
Sat May 19 14:16:38 2018 +0000
Revision:
27:9a62663f3de2
Parent:
26:c3193bc73cff
Added #define for RGB/GRB order for WS2811 and WS2812b based strips, respectively. Ideally this should be selectable per instance, but it's late, and I'm tired.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DavidEGrayson 1:102307d9b701 1 #include "PololuLedStrip.h"
DavidEGrayson 1:102307d9b701 2
DavidEGrayson 26:c3193bc73cff 3 // Our assembly code currently does not work with chip families like the STM32F4
DavidEGrayson 26:c3193bc73cff 4 // that use the same register and a different mask for setting and clearing
DavidEGrayson 26:c3193bc73cff 5 // outputs.
DavidEGrayson 26:c3193bc73cff 6 #ifdef GPIO_IP_WITHOUT_BRR
DavidEGrayson 26:c3193bc73cff 7 #error This chip is not supported: does not have separate registers for setting and clearing GPIO outputs.
DavidEGrayson 26:c3193bc73cff 8 #endif
DavidEGrayson 26:c3193bc73cff 9
DavidEGrayson 1:102307d9b701 10 bool PololuLedStrip::interruptFriendly = false;
DavidEGrayson 1:102307d9b701 11
DavidEGrayson 19:46d7ab0ba3e7 12 // The two timed delays, in units of half-cycles.
DavidEGrayson 19:46d7ab0ba3e7 13 uint8_t led_strip_write_delays[2];
DavidEGrayson 4:d3b60bd43811 14
DavidEGrayson 7:9a088f042ee0 15 void PololuLedStrip::calculateDelays()
DavidEGrayson 7:9a088f042ee0 16 {
DavidEGrayson 15:d69eebdee025 17 int f_mhz = SystemCoreClock / 1000000; // Clock frequency in MHz.
DavidEGrayson 14:672baf3cf941 18
DavidEGrayson 14:672baf3cf941 19 if (f_mhz <= 48)
DavidEGrayson 14:672baf3cf941 20 {
DavidEGrayson 19:46d7ab0ba3e7 21 // The delays below result in 360/1120 ns pulses and a 1880 ns period on the mbed NXP LPC11U24.
DavidEGrayson 14:672baf3cf941 22 led_strip_write_delays[0] = 0;
DavidEGrayson 14:672baf3cf941 23 led_strip_write_delays[1] = 0;
DavidEGrayson 14:672baf3cf941 24 }
DavidEGrayson 14:672baf3cf941 25 else
DavidEGrayson 14:672baf3cf941 26 {
DavidEGrayson 22:5368af3ff07d 27 // Try to generally compute what the delays should be for a wide range of clock frequencies.
DavidEGrayson 14:672baf3cf941 28
DavidEGrayson 14:672baf3cf941 29 // The fudge factors below were experimentally chosen so that we would have
DavidEGrayson 23:881d93b8749a 30 // ~100 ns and ~840 ns pulses and a ~1430 ns period on the mbed NXP LPC1768 (96 MHz Cortex-M3).
DavidEGrayson 17:91fb934a2166 31 // There seem to be some ~100 ns inconsistencies in the timing depending on which example program is
DavidEGrayson 17:91fb934a2166 32 // running; the most likely explanation is some kind of flash caching that affects the timing.
DavidEGrayson 14:672baf3cf941 33 // If you ever change these numbers, it is important to check the the subtractions below
DavidEGrayson 19:46d7ab0ba3e7 34 // will not overflow in the worst case (smallest possible f_mhz).
DavidEGrayson 23:881d93b8749a 35 //
DavidEGrayson 23:881d93b8749a 36 // On an STM32F303K8 (72 MHz Cortex-M4), these delays give us ~170 ns and ~840 ns pulses
DavidEGrayson 23:881d93b8749a 37 // and a ~1595 ns period, and there were no timing differences between the two
DavidEGrayson 23:881d93b8749a 38 // example programs.
DavidEGrayson 19:46d7ab0ba3e7 39 led_strip_write_delays[0] = 750*f_mhz/1000 - 33;
DavidEGrayson 19:46d7ab0ba3e7 40 led_strip_write_delays[1] = 550*f_mhz/1000 - 20;
DavidEGrayson 15:d69eebdee025 41 }
DavidEGrayson 15:d69eebdee025 42
DavidEGrayson 15:d69eebdee025 43 // Convert from units of cycles to units of half-cycles; it makes the assembly faster.
DavidEGrayson 22:5368af3ff07d 44 led_strip_write_delays[0] <<= 1;
DavidEGrayson 22:5368af3ff07d 45 led_strip_write_delays[1] <<= 1;
DavidEGrayson 7:9a088f042ee0 46 }
DavidEGrayson 6:9d0530b7dae2 47
DavidEGrayson 1:102307d9b701 48 PololuLedStrip::PololuLedStrip(PinName pinName)
DavidEGrayson 1:102307d9b701 49 {
DavidEGrayson 22:5368af3ff07d 50 gpio_init_out(&gpio, pinName);
DavidEGrayson 1:102307d9b701 51 }
DavidEGrayson 1:102307d9b701 52
DavidEGrayson 1:102307d9b701 53 void PololuLedStrip::write(rgb_color * colors, unsigned int count)
DavidEGrayson 1:102307d9b701 54 {
thegink 27:9a62663f3de2 55 uint8_t t;
DavidEGrayson 8:1578776ceac5 56 calculateDelays();
thegink 27:9a62663f3de2 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 {
thegink 27:9a62663f3de2 62
thegink 27:9a62663f3de2 63 #ifdef _POLOLU_ORDER_GRB
thegink 27:9a62663f3de2 64 //swap red and green for WS2812b strips
thegink 27:9a62663f3de2 65 t = colors->red;
thegink 27:9a62663f3de2 66 colors->red = colors->green;
thegink 27:9a62663f3de2 67 colors->green = t;
thegink 27:9a62663f3de2 68 #endif
thegink 27:9a62663f3de2 69
DavidEGrayson 9:6ffb85d69eaf 70 led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask);
DavidEGrayson 9:6ffb85d69eaf 71 colors++;
DavidEGrayson 9:6ffb85d69eaf 72
DavidEGrayson 1:102307d9b701 73 if (interruptFriendly)
DavidEGrayson 1:102307d9b701 74 {
DavidEGrayson 1:102307d9b701 75 __enable_irq();
DavidEGrayson 1:102307d9b701 76 __nop();
DavidEGrayson 1:102307d9b701 77 __nop();
DavidEGrayson 1:102307d9b701 78 __nop();
DavidEGrayson 1:102307d9b701 79 __disable_irq();
DavidEGrayson 1:102307d9b701 80 }
DavidEGrayson 1:102307d9b701 81 }
DavidEGrayson 1:102307d9b701 82
DavidEGrayson 1:102307d9b701 83 __enable_irq(); // Re-enable interrupts now that we are done.
DavidEGrayson 25:d72818ba17cc 84 wait_us(80); // Send the reset signal.
DavidEGrayson 1:102307d9b701 85 }