Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of PololuLedStrip by
PololuLedStrip.cpp
00001 #include "PololuLedStrip.h" 00002 00003 // Our assembly code currently does not work with chip families like the STM32F4 00004 // that use the same register and a different mask for setting and clearing 00005 // outputs. 00006 #ifdef GPIO_IP_WITHOUT_BRR 00007 #error This chip is not supported: does not have separate registers for setting and clearing GPIO outputs. 00008 #endif 00009 00010 bool PololuLedStrip::interruptFriendly = false; 00011 00012 // The two timed delays, in units of half-cycles. 00013 uint8_t led_strip_write_delays[2]; 00014 00015 void PololuLedStrip::calculateDelays() 00016 { 00017 int f_mhz = SystemCoreClock / 1000000; // Clock frequency in MHz. 00018 00019 if (f_mhz <= 48) 00020 { 00021 // The delays below result in 360/1120 ns pulses and a 1880 ns period on the mbed NXP LPC11U24. 00022 led_strip_write_delays[0] = 0; 00023 led_strip_write_delays[1] = 0; 00024 } 00025 else 00026 { 00027 // Try to generally compute what the delays should be for a wide range of clock frequencies. 00028 00029 // The fudge factors below were experimentally chosen so that we would have 00030 // ~100 ns and ~840 ns pulses and a ~1430 ns period on the mbed NXP LPC1768 (96 MHz Cortex-M3). 00031 // There seem to be some ~100 ns inconsistencies in the timing depending on which example program is 00032 // running; the most likely explanation is some kind of flash caching that affects the timing. 00033 // If you ever change these numbers, it is important to check the the subtractions below 00034 // will not overflow in the worst case (smallest possible f_mhz). 00035 // 00036 // On an STM32F303K8 (72 MHz Cortex-M4), these delays give us ~170 ns and ~840 ns pulses 00037 // and a ~1595 ns period, and there were no timing differences between the two 00038 // example programs. 00039 led_strip_write_delays[0] = 750*f_mhz/1000 - 33; 00040 led_strip_write_delays[1] = 550*f_mhz/1000 - 20; 00041 } 00042 00043 // Convert from units of cycles to units of half-cycles; it makes the assembly faster. 00044 led_strip_write_delays[0] <<= 1; 00045 led_strip_write_delays[1] <<= 1; 00046 } 00047 00048 PololuLedStrip::PololuLedStrip(PinName pinName) 00049 { 00050 gpio_init_out(&gpio, pinName); 00051 } 00052 00053 void PololuLedStrip::write(rgb_color * colors, unsigned int count) 00054 { 00055 uint8_t t; 00056 calculateDelays(); 00057 00058 __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up. 00059 00060 while(count--) 00061 { 00062 00063 #ifdef _POLOLU_ORDER_GRB 00064 //swap red and green for WS2812b strips 00065 t = colors->red; 00066 colors->red = colors->green; 00067 colors->green = t; 00068 #endif 00069 00070 led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask); 00071 colors++; 00072 00073 if (interruptFriendly) 00074 { 00075 __enable_irq(); 00076 __nop(); 00077 __nop(); 00078 __nop(); 00079 __disable_irq(); 00080 } 00081 } 00082 00083 __enable_irq(); // Re-enable interrupts now that we are done. 00084 wait_us(80); // Send the reset signal. 00085 }
Generated on Sat Aug 13 2022 02:11:54 by
1.7.2
