LED Strip with K64F
Fork of PololuLedStrip by
Revision 7:9a088f042ee0, committed 2013-03-01
- Comitter:
- DavidEGrayson
- Date:
- Fri Mar 01 01:16:48 2013 +0000
- Parent:
- 6:9d0530b7dae2
- Child:
- 8:1578776ceac5
- Commit message:
- Things are still working well.
Changed in this revision
--- a/PololuLedStrip.cpp Fri Mar 01 00:31:24 2013 +0000 +++ b/PololuLedStrip.cpp Fri Mar 01 01:16:48 2013 +0000 @@ -2,26 +2,26 @@ bool PololuLedStrip::interruptFriendly = false; -// TODO: read clock frequency from SystemCoreClock and use that to make this work on different boards. -// calculate the three delays needed and pass them to the assembly. The assembly can implement them with computed jumps. +uint8_t led_strip_write_delays[3]; -uint8_t led_strip_write_delays[3]; +void PololuLedStrip::calculateDelays() +{ + int fmhz = SystemCoreClock / 1000000; + led_strip_write_delays[0] = 700*fmhz/1000 - 25; + led_strip_write_delays[1] = 600*fmhz/1000 - 19; + led_strip_write_delays[2] = 1200*fmhz/1000 - 24; +} PololuLedStrip::PololuLedStrip(PinName pinName) { gpio_init(&gpio, pinName, PIN_OUTPUT); + calculateDelays(); // Assumption } void PololuLedStrip::write(rgb_color * colors, unsigned int count) { __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up. - - int f = SystemCoreClock/1000000; - led_strip_write_delays[0] = 700*f/1000 - 10; - led_strip_write_delays[1] = 600*f/1000 - 10; - led_strip_write_delays[2] = 1200*f/1000 - 10; - led_strip_write_delays[0] = 59; - + while(count--) { led_strip_write_color(colors++, gpio.reg_set, gpio.reg_clr, gpio.mask);
--- a/PololuLedStrip.h Fri Mar 01 00:31:24 2013 +0000 +++ b/PololuLedStrip.h Fri Mar 01 01:16:48 2013 +0000 @@ -51,7 +51,7 @@ 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. @@ -64,6 +64,8 @@ @endcode */ static bool interruptFriendly; + + static void calculateDelays(); }; }
--- a/led_strip_write_color.s Fri Mar 01 00:31:24 2013 +0000 +++ b/led_strip_write_color.s Fri Mar 01 01:16:48 2013 +0000 @@ -2,6 +2,16 @@ EXPORT led_strip_write_color IMPORT led_strip_write_delays + MACRO + delay $id + ldr r5, =led_strip_write_delays + ldrb r5, [r5, $id] + lsl r5, r5, #1 + ldr r4, =delay_region_end + sub r4, r4, r5 + blx r4 + MEND + led_strip_write_color ; Register usage: ; These are the first 4 arguments to the method: @@ -15,39 +25,29 @@ ; R7: the number of bits we still need to send ; R12: shift register that holds the 24-bit color ; R13: Link Register, holds return addresses. - + + push {r4, r5, r12, r7, lr} ; Push those registers so we can restore them later. - push {r4, r5, r12, r7, lr} - - ldr r12, [r0] ; Read the next color. - rbit r12, r12 ; Reverse the order of the bits. - rev r12, r12 ; Reverse the order of the bytes. + ldr r12, [r0] ; Read the color. Now we have: xxBbGgRr + rbit r12, r12 ; Reverse the order of the bits: rRgGbBxx + rev r12, r12 ; Reverse the order of the bytes: xxbBgGrR mov r7, #24 ; Initialize the loop counter register. send_led_strip_bit str r3, [r1] ; Drive the line high. rrxs r12, r12 ; Rotate right through carry. - ldr r5, =led_strip_write_delays - ldrb r5, [r5, #0] - lsl r5, r5, #1 - ldr r4, =delay_region_end - sub r4, r4, r5 - blx r4 + delay #0 - it cc ; If the bit to send it 0... - strcc r3, [r2] ; Drive the line low. + it cc ; If the bit to send it 0... + strcc r3, [r2] ; Drive the line low. - ldr r4, =delay_region_end - sub r4, r4, #59*2 - blx r4 + delay #1 - it cs ; If the bit to send is 1... - strcs r3, [r2] ; Drive the line low. + it cs ; If the bit to send is 1... + strcs r3, [r2] ; Drive the line low. - ldr r4, =delay_region - add r4, r4, #68 - blx r4 + delay #2 subs r7, r7, #1 ; Decrement the loop counter. bne send_led_strip_bit ; Send another bit if we have not reached zero.