Use SysTick instead of a busy loop to blink the LED once per second
authorMatt Mullins <mmullins@mmlx.us>
Sun, 23 Dec 2012 05:59:45 +0000 (21:59 -0800)
committerMatt Mullins <mmullins@mmlx.us>
Sun, 23 Dec 2012 06:00:49 +0000 (22:00 -0800)
isr_table.c
led_blink.c
led_blink.h

index e013b40..33306c8 100644 (file)
@@ -19,7 +19,7 @@ void (*reset_vectors[])() = {
        infinite_loop_isr,
        infinite_loop_isr,
        infinite_loop_isr,
-       infinite_loop_isr,
+       systick_isr,
        infinite_loop_isr,
        infinite_loop_isr,
        infinite_loop_isr,
index 657255a..ddf5325 100644 (file)
@@ -3,6 +3,12 @@
 
 static void spin(int);
 
+// Since SysTick is only 24-bits, we'll need to divide it by 4 to produce a
+// 2Hz value from the 80MHz system clock.
+// Yes, I know I can just run the system clock slower, but this is more fun.
+static const int initial_systick_count = 3;
+static int systick_count;
+
 __attribute__((isr))
 void main_isr() {
        // Power on the PLL, set to 16MHz XTAL
@@ -44,13 +50,24 @@ void main_isr() {
        GPIO_PORTF_DEN_R = 0xE;
 
        // Set RGB pins to 1
-       *(GPIO_PORTF_DATA_BITS_R + 0xE) = 0x2;
+       *(GPIO_PORTF_DATA_BITS_R + 0xE) = 0xF;
+
+       // Initialize our SysTick prescaler
+       systick_count = initial_systick_count;
+
+       // Initialize the SysTick module
+       NVIC_ST_RELOAD_R = 10000000; // produce 8Hz from 80MHz clock
+       NVIC_ST_CURRENT_R = 0;
+       NVIC_ST_CTRL_R |= 0x7;
 
        // infinite loop
        for (;;) { 
-               *(GPIO_PORTF_DATA_BITS_R + 0xC) ^= 0xC;
+               asm("wfi");
 
-               spin(1000000);
+               // flip the green LED on every WFI, as an experiment to see if the
+               // CPU is really sleeping.
+               // Answer: it is.
+               // *(GPIO_PORTF_DATA_BITS_R + 0x8) ^= 0xFF;
        }
 }
 
@@ -61,3 +78,14 @@ void spin(int cycles) {
                asm("");
        }
 }
+
+__attribute__((isr))
+void systick_isr() {
+       if (systick_count) {
+               systick_count--;
+               return;
+       }
+
+       systick_count = initial_systick_count;
+       *(GPIO_PORTF_DATA_BITS_R + 0xE) ^= 0xF;
+}
index 24c4feb..ed70066 100644 (file)
@@ -2,5 +2,6 @@
 #define __led_blink_H__
 
 extern void main_isr();
+extern void systick_isr();
 
 #endif