aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordave2007-01-04 09:19:04 +0000
committerdave2007-01-04 09:19:04 +0000
commit08614aca6b11a917b3445d572be869d7fcbdbeb0 (patch)
tree7ff561c922e538aee45b0e4f07ea5f22d6f24d38
parentdf0b8b6664b3b8c41b49b23ecedf530ccc2a4e4c (diff)
Initial implementation of Electric Storm, inspired a lot by the Lejos
platform code, but with a few variations here and there.
-rw-r--r--crt0/crt0_s.S2
-rw-r--r--estorm/Makefile39
-rw-r--r--estorm/aic.c37
-rw-r--r--estorm/aic.h30
-rw-r--r--estorm/main.c19
-rw-r--r--estorm/sys_timer.c37
-rw-r--r--estorm/sys_timer.h11
7 files changed, 174 insertions, 1 deletions
diff --git a/crt0/crt0_s.S b/crt0/crt0_s.S
index 0f5503c..d9f1d6a 100644
--- a/crt0/crt0_s.S
+++ b/crt0/crt0_s.S
@@ -271,7 +271,7 @@ init_reset:
* application payload and crash.
*/
ldr lr, =end
- ldr ip, =main
+ ldr ip, =kernel_main
ldr r4, =MC_BASE
mov r5, #1
diff --git a/estorm/Makefile b/estorm/Makefile
new file mode 100644
index 0000000..490ebcc
--- /dev/null
+++ b/estorm/Makefile
@@ -0,0 +1,39 @@
+TOOL_PREFIX=arm-elf-
+TOOL_SUFFIX=-4.1.1
+
+S_SOURCES =
+C_SOURCES = main.c aic.c sys_timer.c
+
+S_OBJECTS = $(S_SOURCES:.S=.o)
+C_OBJECTS = $(C_SOURCES:.c=.o)
+
+GCC=$(TOOL_PREFIX)gcc$(TOOL_SUFFIX)
+AS=$(TOOL_PREFIX)as
+LD=$(TOOL_PREFIX)ld
+OBJCOPY=$(TOOL_PREFIX)objcopy
+OBJDUMP=$(TOOL_PREFIX)objdump
+
+OPTIMIZE=-O2
+
+CCFLAGS=-ffreestanding -W -Wall -Werror $(OPTIMIZE) -mcpu=arm7tdmi -mapcs -mthumb-interwork -I../support -I../crt0
+ASFLAGS=-W -Wall -Werrror $(OPTIMIZE) -Wa,-mcpu=arm7tdmi,-mapcs-32,-mthumb-interwork,-mfpu=softfpa
+LDFLAGS=-N -nostdlib $(OPTIMIZE) -T ../crt0/nxt.lds -L../crt0
+
+all: estorm.bin
+
+estorm.bin: estorm.elf
+ $(OBJCOPY) -O binary -R .bss $< $@
+ $(OBJDUMP) --disassemble-all -b binary -m arm7tdmi $@ > $@.asm
+
+estorm.elf: $(S_OBJECTS) $(C_OBJECTS) ../crt0/crt0.o ../crt0/nxt.lds
+ $(LD) -o $@ $(S_OBJECTS) $(C_OBJECTS) $(LDFLAGS)
+ $(OBJDUMP) --disassemble-all -m arm7tdmi $@ > $@.asm
+
+%.o: %.c
+ $(GCC) $(CCFLAGS) -c -o $@ $<
+
+%.o: %.S
+ $(GCC) $(ASFLAGS) -c -o $@ $<
+
+clean:
+ rm -f *.o *.asm *.bin *.elf *~
diff --git a/estorm/aic.c b/estorm/aic.c
new file mode 100644
index 0000000..2b1ac15
--- /dev/null
+++ b/estorm/aic.c
@@ -0,0 +1,37 @@
+/*
+ * Advanced Interrupt Controller routines
+ *
+ * The AIC was initialized by the bootstrap code, so we only have
+ * utility functions to install interrupts and mask selected interrupt
+ * lines.
+ *
+ * This code is very heavily inspired by the work of Charles Manning,
+ * of Lejos fame.
+ */
+
+#include "at91sam7s256.h"
+
+#include "aic.h"
+
+void aic_enable(aic_vector_t vector) {
+ *AT91C_AIC_IECR = (1 << vector);
+}
+
+void aic_disable(aic_vector_t vector) {
+ *AT91C_AIC_IDCR = (1 << vector);
+}
+
+void aic_install_isr(aic_vector_t vector, void *isr) {
+ /* Disable the interrupt we're installing. Getting interrupted while
+ * we are tweaking it could be bad.
+ */
+ aic_disable(vector);
+
+ /* Set the irq mode to positive edge triggered and priority 0. */
+ AT91C_AIC_SMR[vector] = (AT91C_AIC_PRIOR_LOWEST |
+ AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED);
+
+ /* Install the provided ISR. */
+ AT91C_AIC_SVR[vector] = (unsigned int)isr;
+
+}
diff --git a/estorm/aic.h b/estorm/aic.h
new file mode 100644
index 0000000..954c246
--- /dev/null
+++ b/estorm/aic.h
@@ -0,0 +1,30 @@
+/*
+ * Advanced Interrupt Controller routines
+ *
+ * The AIC was initialized by the bootstrap code, so we only have
+ * utility functions to install interrupts and mask selected interrupt
+ * lines.
+ *
+ * This code is very heavily inspired by the work of Charles Manning,
+ * of Lejos fame.
+ */
+
+#ifndef __ESTORM_AIC_H__
+#define __ESTORM_AIC_H__
+
+typedef long int aic_vector_t;
+
+/* Enable the interrupt VECTOR in the AIC. */
+void aic_enable(aic_vector_t vector);
+
+/* Disable the interrupt VECTOR in the AIC. */
+void aic_disable(aic_vector_t vector);
+
+/* Install the given ISR as the Interrupt Service Routine for the
+ * given interrupt VECTOR. On return, ISR is installed but the VECTOR
+ * line is left masked in the AIC. You need to enable yourself when
+ * ready with a call to aic_enable().
+ */
+void aic_install_isr(aic_vector_t vector, void *isr);
+
+#endif
diff --git a/estorm/main.c b/estorm/main.c
new file mode 100644
index 0000000..34a99db
--- /dev/null
+++ b/estorm/main.c
@@ -0,0 +1,19 @@
+/* Electric storm main code.
+ *
+ * This gets called as the payload of the crt0.
+ */
+
+#include "at91sam7s256.h"
+#include "crt0.h"
+
+#include "sys_timer.h"
+
+/*
+ * This is the first function to get executed after the bootstrapper
+ * does the bare metal board initialization. We arrive in this routine
+ * with interrupts disabled, so we're free to do all the setup we
+ * like.
+ */
+void kernel_main(void) {
+ sys_timer_init();
+}
diff --git a/estorm/sys_timer.c b/estorm/sys_timer.c
new file mode 100644
index 0000000..4938556
--- /dev/null
+++ b/estorm/sys_timer.c
@@ -0,0 +1,37 @@
+#include "at91sam7s256.h"
+
+#include "aic.h"
+
+/* The board is clocked at 48MHz */
+#define CLOCK_FREQ 48000000
+
+/* The Periodic Interval Timer has a frequency of CLK/16. */
+#define PIT_FREQ (CLOCK_FREQ/16)
+
+void sys_timer_isr(void) {
+}
+
+void sys_timer_init(void) {
+ /* Set the Periodic Interval Timer to a tiny interval, and set it
+ * disabled. This way, it should wrap around and shut down quickly,
+ * if it's already running.
+ */
+ *AT91C_PITC_PIMR = 1;
+
+ /* Wait for the timer's internal counter to return to zero. */
+ while (*AT91C_PITC_PIVR & AT91C_PITC_CPIV);
+
+ /* Install the interrupt handler for the system timer, and tell the
+ * AIC to handle that interrupt.
+ */
+ aic_install_isr(AT91C_ID_SYS, sys_timer_isr);
+ aic_enable(AT91C_ID_SYS);
+
+ /* Configure the Periodic Interval Timer with a frequency of
+ * 1000Hz. The timer is enabled, and will raise the interrupt we
+ * installed previously 1000 times a second.
+ */
+ *AT91C_PITC_PIMR = (((PIT_FREQ/1000)-1) |
+ AT91C_PITC_PITEN |
+ AT91C_PITC_PITIEN);
+}
diff --git a/estorm/sys_timer.h b/estorm/sys_timer.h
new file mode 100644
index 0000000..e4dccf5
--- /dev/null
+++ b/estorm/sys_timer.h
@@ -0,0 +1,11 @@
+/*
+ * Handling of the NXT's Periodic Interval Timer, which provides the
+ * clock source for the main system timer.
+ */
+
+#ifndef __ESTORM_SYS_TIMER_H__
+#define __ESTORM_SYS_TIMER_H__
+
+void sys_timer_init();
+
+#endif