K64F version
Fork of PololuLedStrip_r8 by
Revision 25:3b22d6d32a7a, committed 2014-12-11
- Comitter:
- michaeljkoster
- Date:
- Thu Dec 11 23:14:12 2014 +0000
- Parent:
- 24:563061381da1
- Commit message:
- K64F support etc
Changed in this revision
diff -r 563061381da1 -r 3b22d6d32a7a PololuLedStrip.cpp --- a/PololuLedStrip.cpp Sat Oct 04 05:17:29 2014 +0000 +++ b/PololuLedStrip.cpp Thu Dec 11 23:14:12 2014 +0000 @@ -39,6 +39,18 @@ PololuLedStrip::PololuLedStrip(PinName pinName) { gpio_init_out(&gpio, pinName); + + #if defined(_K64F) + uint32_t port = pinName >> GPIO_PORT_SHIFT; + mask = 1 << (pinName & 0xFF); + uint32_t gpio_addrs[] = GPIO_BASE_ADDRS; + reg_set = (uint32_t*)(HW_GPIO_PSOR_ADDR(gpio_addrs[port])); + reg_clr = (uint32_t*)(HW_GPIO_PCOR_ADDR(gpio_addrs[port])); + #else + reg_set = gpio.reg_set; + reg_clr = gpio.reg_clr; + mask = gpio.mask; + #endif } void PololuLedStrip::write(rgb_color * colors, unsigned int count) @@ -49,7 +61,11 @@ while(count--) { - led_strip_write_color(colors, gpio.reg_set, gpio.reg_clr, gpio.mask); + #ifdef _K64F + led_strip_write_color_K64F(colors, reg_set, reg_clr, mask); + #else + led_strip_write_color(colors, reg_set, reg_clr, mask); + #endif colors++; if (interruptFriendly)
diff -r 563061381da1 -r 3b22d6d32a7a PololuLedStrip.h --- a/PololuLedStrip.h Sat Oct 04 05:17:29 2014 +0000 +++ b/PololuLedStrip.h Thu Dec 11 23:14:12 2014 +0000 @@ -5,67 +5,77 @@ namespace Pololu { - #ifndef _POLOLU_RGB_COLOR - #define _POLOLU_RGB_COLOR - - /** Represents an RGB color. */ - typedef struct rgb_color - { - uint8_t red; /*!< A number between 0 and 255 that represents the brightness of the red component. */ - uint8_t green; /*!< A number between 0 and 255 that represents the brightness of the green component. */ - uint8_t blue; /*!< A number between 0 and 255 that represents the brightness of the blue component. */ - } rgb_color; - #endif +#ifndef _POLOLU_RGB_COLOR +#define _POLOLU_RGB_COLOR + +#ifndef _K64F +#define _K64F //Define this to use with K64F +#endif + +/** Represents an RGB color. */ +typedef struct rgb_color { + uint8_t red; /*!< A number between 0 and 255 that represents the brightness of the red component. */ + uint8_t green; /*!< A number between 0 and 255 that represents the brightness of the green component. */ + uint8_t blue; /*!< A number between 0 and 255 that represents the brightness of the blue component. */ +} rgb_color; +#endif - extern "C" int led_strip_write_color(rgb_color *, volatile uint32_t * set, volatile uint32_t * clear, uint32_t mask); +#ifdef _K64F +extern "C" int led_strip_write_color_K64F(rgb_color *, volatile uint32_t * set, volatile uint32_t * clear, uint32_t mask); +#else +extern "C" int led_strip_write_color(rgb_color *, volatile uint32_t * set, volatile uint32_t * clear, uint32_t mask); +#endif + +/** This class lets you control the addressable RGB LED strips from Pololu</a>, +or any other LED strip based on the TM1804 chip. */ +class PololuLedStrip +{ + gpio_t gpio; + uint32_t mask; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + +public: + + /** This constructor lets you make an led strip object by specifying the pin name. + There are no restrictions on what pin you can choose. - /** This class lets you control the addressable RGB LED strips from Pololu</a>, - or any other LED strip based on the TM1804 chip. */ - class PololuLedStrip - { - gpio_t gpio; - - public: - - /** This constructor lets you make an led strip object by specifying the pin name. - There are no restrictions on what pin you can choose. - - Example: - @code -PololuLedStrip ledStrip(p8); - @endcode - */ - PololuLedStrip(PinName pin); - - /** Writes the specified series of colors to the LED strip. - @param colors should be a pointer to an array of rgb_color structs. - @param count should be the number of colors to write. - - The first color in the array will be written to the LED closest to the data input connector. - To update all the LEDs in the LED strip, count should be equal to or greater than the number of LEDs in the strip. - If count is less than the number of LEDs in the strip, then some LEDs near the end of the strip will not be updated. - - The colors are sent in series and each color takes about 45 microseconds to send. - This function disables interrupts temporarily while it is running. - This function waits for over 10 us at the end before returning to allow the colors to take effect. - */ - void write(rgb_color * colors, unsigned int count); - - /** This option defaults to <code>false</code>. - Setting this to true changes the behavior of the write function, making it enable interrupts - after each color is sent, about every 60 microseconds. - This allows your program to respond to interrupts faster, but makes it possible for an interrupt - that takes longer than 8 microseconds to screw up the transmission of colors to the LED strip. - - Example: - @code - PololuLedStrip::interruptFriendly = true; - @endcode - */ - static bool interruptFriendly; - - static void calculateDelays(); - }; + Example: + @code + PololuLedStrip ledStrip(p8); + @endcode + */ + PololuLedStrip(PinName pin); + + /** Writes the specified series of colors to the LED strip. + @param colors should be a pointer to an array of rgb_color structs. + @param count should be the number of colors to write. + + The first color in the array will be written to the LED closest to the data input connector. + To update all the LEDs in the LED strip, count should be equal to or greater than the number of LEDs in the strip. + If count is less than the number of LEDs in the strip, then some LEDs near the end of the strip will not be updated. + + The colors are sent in series and each color takes about 45 microseconds to send. + This function disables interrupts temporarily while it is running. + This function waits for over 10 us at the end before returning to allow the colors to take effect. + */ + void write(rgb_color * colors, unsigned int count); + + /** This option defaults to <code>false</code>. + Setting this to true changes the behavior of the write function, making it enable interrupts + after each color is sent, about every 60 microseconds. + This allows your program to respond to interrupts faster, but makes it possible for an interrupt + that takes longer than 8 microseconds to screw up the transmission of colors to the LED strip. + + Example: + @code + PololuLedStrip::interruptFriendly = true; + @endcode + */ + static bool interruptFriendly; + + static void calculateDelays(); +}; } using namespace Pololu;
diff -r 563061381da1 -r 3b22d6d32a7a led_strip_write_color.s --- a/led_strip_write_color.s Sat Oct 04 05:17:29 2014 +0000 +++ b/led_strip_write_color.s Thu Dec 11 23:14:12 2014 +0000 @@ -65,6 +65,7 @@ delay #0 + ;tst r6, r8 ldr r4, =0x80000000 tst r6, r4 beq delay1
diff -r 563061381da1 -r 3b22d6d32a7a led_strip_write_color_K64F.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/led_strip_write_color_K64F.s Thu Dec 11 23:14:12 2014 +0000 @@ -0,0 +1,431 @@ + AREA asm_func, CODE, READONLY + EXPORT led_strip_write_color_K64F + IMPORT led_strip_write_delays + + MACRO + delay $id + ldr r5, =led_strip_write_delays + ldrb r5, [r5, $id] + ldr r4, =delay_region_end + subs r4, r4, r5 + blx r4 + MEND + +led_strip_write_color_K64F + ; Register usage: + ; These are the first 4 arguments to the method: + ; R0: pointer to the color to send + ; R1: pointer to the register for setting the pin + ; R2: pointer to the register for clearing the pin + ; R3: pin mask + ; Additionally, we use these registers: + ; R4: temporary register + ; R5: temporary register + ; R6: shift register that holds the 24-bit color + ; R7: the number of bits we still need to send + ; R13: Link Register, holds return addresses. + + ; Push those registers so we can restore them later. + push {r4, r5, r6, r7, lr} + + ldrb r6, [r0, #1] ; Load green. + lsls r6, r6, #24 ; Put green in MSB of r6. + ldrb r4, [r0, #0] ; Load red. + lsls r4, r4, #16 + orrs r6, r6, r4 ; Put red in r6. + ldrb r4, [r0, #2] ; Load blue. + lsls r4, r4, #8 + orrs r6, r6, r4 ; Put blue in r6. + + ; On the Cortex-M3 we simply did: + ; ldr r6, [r0] ; Read the color. Now we have: xxBbGgRr + ; rbit r6, r6 ; Reverse the order of the bits: rRgGbBxx + ; rev r6, r6 ; Reverse the order of the bytes: xxbBgGrR + ; and then we used rrxs for shifting to the right through carry. + + ldr r7, =24 ; Initialize the loop counter register. + +send_led_strip_bit + str r3, [r1] ; Drive the line high. + + ; It doesn't really matter exactly how long we delay here as long as it is + ; less than 540 microseconds. + nop + nop + nop + nop + nop + nop + nop + nop + nop + + ldr r4, =0x80000000 + tst r6, r4 + bne delay0 + str r3, [r2] ; If the bit to send it 0, drive the line low. +delay0 + + delay #0 + + ;tst r6, r8 + ldr r4, =0x80000000 + tst r6, r4 + beq delay1 + str r3, [r2] ; If the bit to send is 1, drive the line low. +delay1 + + delay #1 + + lsls r6, r6, #1 ; Shift color bits. + subs r7, r7, #1 ; Decrement the loop counter. + bne send_led_strip_bit ; Send another bit if we have not reached zero. + pop {r4, r5, r6, r7, pc} ; Otherwise, restore the registers and return. + bx lr; + +delay_region + ; The following is 128 nops. + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + +delay_region_end + bx lr ; return + + END \ No newline at end of file