From 08614aca6b11a917b3445d572be869d7fcbdbeb0 Mon Sep 17 00:00:00 2001 From: dave Date: Thu, 4 Jan 2007 09:19:04 +0000 Subject: Initial implementation of Electric Storm, inspired a lot by the Lejos platform code, but with a few variations here and there. --- crt0/crt0_s.S | 2 +- estorm/Makefile | 39 +++++++++++++++++++++++++++++++++++++++ estorm/aic.c | 37 +++++++++++++++++++++++++++++++++++++ estorm/aic.h | 30 ++++++++++++++++++++++++++++++ estorm/main.c | 19 +++++++++++++++++++ estorm/sys_timer.c | 37 +++++++++++++++++++++++++++++++++++++ estorm/sys_timer.h | 11 +++++++++++ 7 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 estorm/Makefile create mode 100644 estorm/aic.c create mode 100644 estorm/aic.h create mode 100644 estorm/main.c create mode 100644 estorm/sys_timer.c create mode 100644 estorm/sys_timer.h 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 -- cgit v1.2.3