LED Strip with K64F

Fork of PololuLedStrip by David Grayson

Files at this revision

API Documentation at this revision

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

PololuLedStrip.cpp Show annotated file Show diff for this revision Revisions of this file
PololuLedStrip.h Show annotated file Show diff for this revision Revisions of this file
led_strip_write_color.s Show annotated file Show diff for this revision Revisions of this file
--- 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.