K64F version

Fork of PololuLedStrip_r8 by Michael Koster

Committer:
michaeljkoster
Date:
Thu Dec 11 23:14:12 2014 +0000
Revision:
25:3b22d6d32a7a
Parent:
22:77e743378104
K64F support etc

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 19:46d7ab0ba3e7 5 // The two timed delays, in units of half-cycles.
DavidEGrayson 19:46d7ab0ba3e7 6 uint8_t led_strip_write_delays[2];
DavidEGrayson 4:d3b60bd43811 7
DavidEGrayson 7:9a088f042ee0 8 void PololuLedStrip::calculateDelays()
DavidEGrayson 7:9a088f042ee0 9 {
DavidEGrayson 15:d69eebdee025 10 int f_mhz = SystemCoreClock / 1000000; // Clock frequency in MHz.
DavidEGrayson 14:672baf3cf941 11
DavidEGrayson 14:672baf3cf941 12 if (f_mhz <= 48)
DavidEGrayson 14:672baf3cf941 13 {
DavidEGrayson 19:46d7ab0ba3e7 14 // The delays below result in 360/1120 ns pulses and a 1880 ns period on the mbed NXP LPC11U24.
DavidEGrayson 14:672baf3cf941 15 led_strip_write_delays[0] = 0;
DavidEGrayson 14:672baf3cf941 16 led_strip_write_delays[1] = 0;
DavidEGrayson 14:672baf3cf941 17 }
DavidEGrayson 14:672baf3cf941 18 else
DavidEGrayson 14:672baf3cf941 19 {
DavidEGrayson 15:d69eebdee025 20 // Try to generally compute what the delays should be for a ide range of clock frequencies.
DavidEGrayson 14:672baf3cf941 21
DavidEGrayson 14:672baf3cf941 22 // The fudge factors below were experimentally chosen so that we would have
DavidEGrayson 19:46d7ab0ba3e7 23 // ~100/840 ns pulses and a ~1430 ns period on the mbed NXP LPC1768 (96 MHz Cortex-M3).
DavidEGrayson 17:91fb934a2166 24 // There seem to be some ~100 ns inconsistencies in the timing depending on which example program is
DavidEGrayson 17:91fb934a2166 25 // running; the most likely explanation is some kind of flash caching that affects the timing.
DavidEGrayson 14:672baf3cf941 26 // If you ever change these numbers, it is important to check the the subtractions below
DavidEGrayson 19:46d7ab0ba3e7 27 // will not overflow in the worst case (smallest possible f_mhz).
DavidEGrayson 19:46d7ab0ba3e7 28 led_strip_write_delays[0] = 750*f_mhz/1000 - 33;
DavidEGrayson 19:46d7ab0ba3e7 29 led_strip_write_delays[1] = 550*f_mhz/1000 - 20;
DavidEGrayson 15:d69eebdee025 30 }
DavidEGrayson 15:d69eebdee025 31
DavidEGrayson 15:d69eebdee025 32 // Convert from units of cycles to units of half-cycles; it makes the assembly faster.
DavidEGrayson 19:46d7ab0ba3e7 33 for(int i = 0; i < 2; i++)
DavidEGrayson 15:d69eebdee025 34 {
DavidEGrayson 15:d69eebdee025 35 led_strip_write_delays[i] <<= 1;
DavidEGrayson 12:b6df8ac053c8 36 }
DavidEGrayson 7:9a088f042ee0 37 }
DavidEGrayson 6:9d0530b7dae2 38
DavidEGrayson 1:102307d9b701 39 PololuLedStrip::PololuLedStrip(PinName pinName)
DavidEGrayson 1:102307d9b701 40 {
michaeljkoster 22:77e743378104 41 gpio_init_out(&gpio, pinName);
michaeljkoster 25:3b22d6d32a7a 42
michaeljkoster 25:3b22d6d32a7a 43 #if defined(_K64F)
michaeljkoster 25:3b22d6d32a7a 44 uint32_t port = pinName >> GPIO_PORT_SHIFT;
michaeljkoster 25:3b22d6d32a7a 45 mask = 1 << (pinName & 0xFF);
michaeljkoster 25:3b22d6d32a7a 46 uint32_t gpio_addrs[] = GPIO_BASE_ADDRS;
michaeljkoster 25:3b22d6d32a7a 47 reg_set = (uint32_t*)(HW_GPIO_PSOR_ADDR(gpio_addrs[port]));
michaeljkoster 25:3b22d6d32a7a 48 reg_clr = (uint32_t*)(HW_GPIO_PCOR_ADDR(gpio_addrs[port]));
michaeljkoster 25:3b22d6d32a7a 49 #else
michaeljkoster 25:3b22d6d32a7a 50 reg_set = gpio.reg_set;
michaeljkoster 25:3b22d6d32a7a 51 reg_clr = gpio.reg_clr;
michaeljkoster 25:3b22d6d32a7a 52 mask = gpio.mask;
michaeljkoster 25:3b22d6d32a7a 53 #endif
DavidEGrayson 1:102307d9b701 54 }
DavidEGrayson 1:102307d9b701 55
DavidEGrayson 1:102307d9b701 56 void PololuLedStrip::write(rgb_color * colors, unsigned int count)
DavidEGrayson 1:102307d9b701 57 {
DavidEGrayson 8:1578776ceac5 58 calculateDelays();
DavidEGrayson 8:1578776ceac5 59
DavidEGrayson 1:102307d9b701 60 __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up.
DavidEGrayson 7:9a088f042ee0 61
DavidEGrayson 1:102307d9b701 62 while(count--)
DavidEGrayson 1:102307d9b701 63 {
michaeljkoster 25:3b22d6d32a7a 64 #ifdef _K64F
michaeljkoster 25:3b22d6d32a7a 65 led_strip_write_color_K64F(colors, reg_set, reg_clr, mask);
michaeljkoster 25:3b22d6d32a7a 66 #else
michaeljkoster 25:3b22d6d32a7a 67 led_strip_write_color(colors, reg_set, reg_clr, mask);
michaeljkoster 25:3b22d6d32a7a 68 #endif
DavidEGrayson 9:6ffb85d69eaf 69 colors++;
DavidEGrayson 9:6ffb85d69eaf 70
DavidEGrayson 1:102307d9b701 71 if (interruptFriendly)
DavidEGrayson 1:102307d9b701 72 {
DavidEGrayson 1:102307d9b701 73 __enable_irq();
DavidEGrayson 1:102307d9b701 74 __nop();
DavidEGrayson 1:102307d9b701 75 __nop();
DavidEGrayson 1:102307d9b701 76 __nop();
DavidEGrayson 1:102307d9b701 77 __disable_irq();
DavidEGrayson 1:102307d9b701 78 }
DavidEGrayson 1:102307d9b701 79 }
DavidEGrayson 1:102307d9b701 80
DavidEGrayson 1:102307d9b701 81 __enable_irq(); // Re-enable interrupts now that we are done.
DavidEGrayson 1:102307d9b701 82 wait_us(24); // Hold the line low for 24 microseconds to send the reset signal.
DavidEGrayson 9:6ffb85d69eaf 83
DavidEGrayson 9:6ffb85d69eaf 84 //*(gpio.reg_set) = gpio.mask;
DavidEGrayson 9:6ffb85d69eaf 85 //*(gpio.reg_clr) = gpio.mask;
DavidEGrayson 9:6ffb85d69eaf 86
DavidEGrayson 1:102307d9b701 87 }