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

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?

UserRevisionLine numberNew 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 }