K64F version
Fork of PololuLedStrip_r8 by
PololuLedStrip.cpp@25:3b22d6d32a7a, 2014-12-11 (annotated)
- 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?
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 | 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 | } |