Code for controlling mbed hardware (LED's, motors), as well as code for the Raspberry Pi to run a Support Vector Machine that identifies objects using the Pi camera
Dependencies: mbed Motordriver mbed-rtos PololuLedStrip
mbed/PololuLedStrip/PololuLedStrip.cpp@0:e0dbd261724a, 2019-12-05 (annotated)
- Committer:
- arogliero3
- Date:
- Thu Dec 05 20:34:10 2019 -0500
- Revision:
- 0:e0dbd261724a
Adding code to mbed repo
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
arogliero3 | 0:e0dbd261724a | 1 | #include "PololuLedStrip.h" |
arogliero3 | 0:e0dbd261724a | 2 | |
arogliero3 | 0:e0dbd261724a | 3 | // Our assembly code currently does not work with chip families like the STM32F4 |
arogliero3 | 0:e0dbd261724a | 4 | // that use the same register and a different mask for setting and clearing |
arogliero3 | 0:e0dbd261724a | 5 | // outputs. |
arogliero3 | 0:e0dbd261724a | 6 | #ifdef GPIO_IP_WITHOUT_BRR |
arogliero3 | 0:e0dbd261724a | 7 | #error This chip is not supported: does not have separate registers for setting and clearing GPIO outputs. |
arogliero3 | 0:e0dbd261724a | 8 | #endif |
arogliero3 | 0:e0dbd261724a | 9 | |
arogliero3 | 0:e0dbd261724a | 10 | bool PololuLedStrip::interruptFriendly = false; |
arogliero3 | 0:e0dbd261724a | 11 | |
arogliero3 | 0:e0dbd261724a | 12 | // The two timed delays, in units of half-cycles. |
arogliero3 | 0:e0dbd261724a | 13 | uint8_t led_strip_write_delays[2]; |
arogliero3 | 0:e0dbd261724a | 14 | |
arogliero3 | 0:e0dbd261724a | 15 | void PololuLedStrip::calculateDelays() |
arogliero3 | 0:e0dbd261724a | 16 | { |
arogliero3 | 0:e0dbd261724a | 17 | int f_mhz = SystemCoreClock / 1000000; // Clock frequency in MHz. |
arogliero3 | 0:e0dbd261724a | 18 | |
arogliero3 | 0:e0dbd261724a | 19 | if (f_mhz <= 48) |
arogliero3 | 0:e0dbd261724a | 20 | { |
arogliero3 | 0:e0dbd261724a | 21 | // The delays below result in 360/1120 ns pulses and a 1880 ns period on the mbed NXP LPC11U24. |
arogliero3 | 0:e0dbd261724a | 22 | led_strip_write_delays[0] = 0; |
arogliero3 | 0:e0dbd261724a | 23 | led_strip_write_delays[1] = 0; |
arogliero3 | 0:e0dbd261724a | 24 | } |
arogliero3 | 0:e0dbd261724a | 25 | else |
arogliero3 | 0:e0dbd261724a | 26 | { |
arogliero3 | 0:e0dbd261724a | 27 | // Try to generally compute what the delays should be for a wide range of clock frequencies. |
arogliero3 | 0:e0dbd261724a | 28 | |
arogliero3 | 0:e0dbd261724a | 29 | // The fudge factors below were experimentally chosen so that we would have |
arogliero3 | 0:e0dbd261724a | 30 | // ~100 ns and ~840 ns pulses and a ~1430 ns period on the mbed NXP LPC1768 (96 MHz Cortex-M3). |
arogliero3 | 0:e0dbd261724a | 31 | // There seem to be some ~100 ns inconsistencies in the timing depending on which example program is |
arogliero3 | 0:e0dbd261724a | 32 | // running; the most likely explanation is some kind of flash caching that affects the timing. |
arogliero3 | 0:e0dbd261724a | 33 | // If you ever change these numbers, it is important to check the the subtractions below |
arogliero3 | 0:e0dbd261724a | 34 | // will not overflow in the worst case (smallest possible f_mhz). |
arogliero3 | 0:e0dbd261724a | 35 | // |
arogliero3 | 0:e0dbd261724a | 36 | // On an STM32F303K8 (72 MHz Cortex-M4), these delays give us ~170 ns and ~840 ns pulses |
arogliero3 | 0:e0dbd261724a | 37 | // and a ~1595 ns period, and there were no timing differences between the two |
arogliero3 | 0:e0dbd261724a | 38 | // example programs. |
arogliero3 | 0:e0dbd261724a | 39 | led_strip_write_delays[0] = 750*f_mhz/1000 - 33; |
arogliero3 | 0:e0dbd261724a | 40 | led_strip_write_delays[1] = 550*f_mhz/1000 - 20; |
arogliero3 | 0:e0dbd261724a | 41 | } |
arogliero3 | 0:e0dbd261724a | 42 | |
arogliero3 | 0:e0dbd261724a | 43 | // Convert from units of cycles to units of half-cycles; it makes the assembly faster. |
arogliero3 | 0:e0dbd261724a | 44 | led_strip_write_delays[0] <<= 1; |
arogliero3 | 0:e0dbd261724a | 45 | led_strip_write_delays[1] <<= 1; |
arogliero3 | 0:e0dbd261724a | 46 | } |
arogliero3 | 0:e0dbd261724a | 47 | |
arogliero3 | 0:e0dbd261724a | 48 | PololuLedStrip::PololuLedStrip(PinName pinName) |
arogliero3 | 0:e0dbd261724a | 49 | { |
arogliero3 | 0:e0dbd261724a | 50 | gpio_init_out(&gpio, pinName); |
arogliero3 | 0:e0dbd261724a | 51 | } |
arogliero3 | 0:e0dbd261724a | 52 | |
arogliero3 | 0:e0dbd261724a | 53 | void PololuLedStrip::write(rgb_color * colors, unsigned int count) |
arogliero3 | 0:e0dbd261724a | 54 | { |
arogliero3 | 0:e0dbd261724a | 55 | calculateDelays(); |
arogliero3 | 0:e0dbd261724a | 56 | |
arogliero3 | 0:e0dbd261724a | 57 | __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up. |
arogliero3 | 0:e0dbd261724a | 58 | |
arogliero3 | 0:e0dbd261724a | 59 | while(count--) |
arogliero3 | 0:e0dbd261724a | 60 | { |
arogliero3 | 0:e0dbd261724a | 61 | led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask); |
arogliero3 | 0:e0dbd261724a | 62 | colors++; |
arogliero3 | 0:e0dbd261724a | 63 | |
arogliero3 | 0:e0dbd261724a | 64 | if (interruptFriendly) |
arogliero3 | 0:e0dbd261724a | 65 | { |
arogliero3 | 0:e0dbd261724a | 66 | __enable_irq(); |
arogliero3 | 0:e0dbd261724a | 67 | __nop(); |
arogliero3 | 0:e0dbd261724a | 68 | __nop(); |
arogliero3 | 0:e0dbd261724a | 69 | __nop(); |
arogliero3 | 0:e0dbd261724a | 70 | __disable_irq(); |
arogliero3 | 0:e0dbd261724a | 71 | } |
arogliero3 | 0:e0dbd261724a | 72 | } |
arogliero3 | 0:e0dbd261724a | 73 | |
arogliero3 | 0:e0dbd261724a | 74 | __enable_irq(); // Re-enable interrupts now that we are done. |
arogliero3 | 0:e0dbd261724a | 75 | wait_us(80); // Send the reset signal. |
arogliero3 | 0:e0dbd261724a | 76 | } |