Successfully changed clock to 12MHz.
authorethereal <ethereal@ethv.net>
Tue, 11 Mar 2014 15:47:17 +0000 (09:47 -0600)
committerethereal <ethereal@ethv.net>
Tue, 11 Mar 2014 15:47:17 +0000 (09:47 -0600)
vm/Makefile
vm/src/pmc.c [new file with mode: 0644]
vm/src/pmc.h [new file with mode: 0644]
vm/src/registers.c [new file with mode: 0644]
vm/src/registers.h [new file with mode: 0644]
vm/src/startup.c
vm/src/uart.c [new file with mode: 0644]
vm/src/uart.h [new file with mode: 0644]

index 9ba025c..98db2b7 100644 (file)
@@ -10,7 +10,7 @@ OBJCOPY=$(COMPILER_PREFIX)objcopy
 
 EXEC=vm
 
-LOCAL_CFLAGS=-std=c11 -Wextra -Wall -Wno-unused-parameter -ffreestanding -nostdlib
+LOCAL_CFLAGS=-std=c11 -Wextra -Wall -Wno-unused-parameter -ffreestanding -nostdlib -mthumb -mcpu=cortex-m3
 LOCAL_LDFLAGS=-nostdlib -T src/sam3n.ld
 
 CFLAGS=$(LOCAL_CFLAGS)
@@ -39,5 +39,5 @@ $(EXEC).bin: $(EXEC).elf
 
 .PHONY: clean
 clean:
-       rm -f $(EXEC) $(OBJECTS)
+       rm -f $(EXEC).elf $(EXEC).bin $(OBJECTS)
 
diff --git a/vm/src/pmc.c b/vm/src/pmc.c
new file mode 100644 (file)
index 0000000..367848d
--- /dev/null
@@ -0,0 +1,39 @@
+#include "pmc.h"
+#include "registers.h"
+
+static void pmc_setup_mclk(void);
+
+void pmc_init() {
+    /* set master clock speed to 12MHz */
+    pmc_setup_mclk();
+}
+
+static void pmc_setup_mclk(void) {
+    /* begin by slowing down the flash */
+    //register_write(EEFC_FMR, 0xf << 8);
+
+    /* set main oscillator to 12MHz */
+    register_write(CKGR_MOR, (0x37 << 16) | (0 << 4) | (1<<3));
+    while((register_read(PMC_SR) & 8) == 0) {}
+
+    #if 0
+    /* enable main oscillator */
+    register_write(CKGR_MOR, (0x37 << 16) | 1);
+    /* wait for oscillator to settle */
+    while((register_read(PMC_SR) & 1) == 0) {}
+    /* set up PLL to multiply main clock by 4 */
+    register_write(CKGR_PLLR, (1) | ((4-1) << 16) | (64) << 8);
+    /* wait for PLL to lock */
+    while((register_read(PMC_SR) & 2) == 0) {}
+
+    /* select PLL clock for MCLK */
+    /* start by changing prescaler */
+    register_write(PMC_MCKR, 1);
+    /* wait for prescaler change to finish */
+    while((register_read(PMC_SR) & 8) == 0) {}
+    /* change to PLL clock */
+    register_write(PMC_MCKR, 2);
+    /* wait for clock selection to finish */
+    while((register_read(PMC_SR) & 8) == 0) {}
+    #endif
+}
diff --git a/vm/src/pmc.h b/vm/src/pmc.h
new file mode 100644 (file)
index 0000000..6cf06d3
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef PMC_H
+#define PMC_H
+
+void pmc_init(void);
+
+#endif
diff --git a/vm/src/registers.c b/vm/src/registers.c
new file mode 100644 (file)
index 0000000..30c4e79
--- /dev/null
@@ -0,0 +1,9 @@
+#include "registers.h"
+
+void register_write(uint32_t which, uint32_t value) {
+    *(uint32_t *)which = value;
+}
+
+uint32_t register_read(uint32_t which) {
+    return *(uint32_t *)which;
+}
diff --git a/vm/src/registers.h b/vm/src/registers.h
new file mode 100644 (file)
index 0000000..1f45acb
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef REGISTERS_H
+#define REGISTERS_H
+
+#include <stdint.h>
+
+/* EEFC registers */
+#define EEFC_FMR 0x400e0a00
+
+/* PMC registers */
+#define PMC_SR   0x400E0468
+#define PMC_PCSR 0x400E0418
+#define CKGR_MOR 0x400E0420
+#define CKGR_PLLR 0x400E0428
+#define PMC_MCKR 0x400E0430
+
+void register_write(uint32_t which, uint32_t value);
+uint32_t register_read(uint32_t which);
+
+#endif
index e485149..adb9395 100644 (file)
@@ -1,5 +1,7 @@
 #include "interrupt.h"
 
+#include "pmc.h"
+
 /* Segment symbols */
 extern uint32_t _sfixed;
 extern uint32_t _efixed;
@@ -73,7 +75,7 @@ static void startup_dummy_handler(void) {
 }
 
 static void startup_reset_handler(void) {
-    /* relocation segment */
+    /* relocation segment, i.e. global data */
     uint32_t *src, *dest;
     src = &_etext;
     dest = &_srelocate;
@@ -92,15 +94,17 @@ static void startup_reset_handler(void) {
     /* need to initialize PIOC */
     /* TODO: not required for just outputs etc. */
 
+    pmc_init();
+
     /* make PA3 high */
     *(uint32_t *)(0x400e0e00) = 0x8;
     *(uint32_t *)(0x400e0e10) = 0x8;
 
     while(1) {
         *(uint32_t *)(0x400e0e30) = 0x8;
-        for(int i = 0; i < 1000000; i ++) {}
+        for(int i = 0; i < 100000; i ++) {}
         *(uint32_t *)(0x400e0e34) = 0x8;
-        for(int i = 0; i < 1000000; i ++) {}
+        for(int i = 0; i < 50000; i ++) {}
     }
 
     while(1) {}
diff --git a/vm/src/uart.c b/vm/src/uart.c
new file mode 100644 (file)
index 0000000..eb7c211
--- /dev/null
@@ -0,0 +1,9 @@
+#include "uart.h"
+
+void uart_initialize() {
+    
+}
+
+void uart_send(uint8_t *data, uint32_t count) {
+    
+}
diff --git a/vm/src/uart.h b/vm/src/uart.h
new file mode 100644 (file)
index 0000000..368a84e
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef UART_H
+#define UART_H
+
+#include <stdint.h>
+
+void uart_initialize(void);
+
+void uart_send(uint8_t *data, uint32_t count);
+
+#endif