diff --git a/Makefile b/Makefile index f1dc502fa..4803b5e1b 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ include $(TOPDIR)/config.mk ######################################################################### # blink objects....order is important (i.e. start must be first) -AOBJS = +AOBJS = COBJS = $(patsubst %.c,%.o,$(wildcard src/*.c)) TESTS = $(wildcard tests/*.c) TARGETS = $(patsubst %.c,%.o,$(TESTS)) @@ -58,11 +58,23 @@ ALL = $(TESTS:.c=.srec) $(TESTS:.c=.bin) $(TESTS:.c=.dis) .PRECIOUS: $(COBJS) $(TARGETS) $(TESTS:.c=.obj) -all: src/start.o $(ALL) +all: src/start.o src/isr.o $(ALL) tests/nvm-read.obj: src/maca.o src/nvm.o tests/rftest-rx.obj: src/maca.o src/nvm.o tests/rftest-tx.obj: src/maca.o src/nvm.o +tests/tmr-ints.obj: src/isr.o + +NOTHUMB_CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \ + -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \ + -I$(TOPDIR)/include \ + -fno-builtin -ffreestanding -nostdinc -isystem \ + $(gccincdir) -pipe +NOTHUMB_CPPFLAGS_EXTRA = -march=armv4t -mlong-calls -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ -mthumb-interwork + + +src/isr.o: src/isr.c + $(CC) $(NOTHUMB_CPPFLAGS) $(NOTHUMB_CPPFLAGS_EXTRA) -c -o $@ $< %.srec: %.obj $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ @@ -74,9 +86,9 @@ tests/rftest-tx.obj: src/maca.o src/nvm.o $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ %.dis: %.obj - $(OBJDUMP) -D $< > $@ + $(OBJDUMP) -SD $< > $@ -%.obj: $(LDSCRIPT) %.o +%.obj: $(LDSCRIPT) %.o #src/interrupt-utils.o $(LD) $(LDFLAGS) $(AOBJS) \ --start-group $(PLATFORM_LIBS) --end-group \ -Map $*.map $^ -o $@ diff --git a/boot.lds b/boot.lds index 5b6ae7aef..0d4bb767b 100644 --- a/boot.lds +++ b/boot.lds @@ -33,6 +33,7 @@ SECTIONS .text : { src/start.o (.text) + src/isr.o (.text) *(.text) } diff --git a/config.mk b/config.mk index 7352f6d74..c21f9b280 100644 --- a/config.mk +++ b/config.mk @@ -25,8 +25,8 @@ # clean the slate ... PLATFORM_LDFLAGS = -PLATFORM_RELFLAGS = -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -PLATFORM_CPPFLAGS = -march=armv4t -mcallee-super-interworking -mthumb -mtune=arm7tdmi-s -mthumb-interwork -DCONFIG_ARM -D__ARM__ +PLATFORM_RELFLAGS = -fno-strict-aliasing -fno-common -ffixed-r8 -ffunction-sections -msoft-float +PLATFORM_CPPFLAGS = -march=armv4t -mlong-calls -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ -mcallee-super-interworking -mthumb -mthumb-interwork TEXT_BASE = 0x00400000 ######################################################################### diff --git a/include/interrupt-utils.h b/include/interrupt-utils.h new file mode 100644 index 000000000..29b307d88 --- /dev/null +++ b/include/interrupt-utils.h @@ -0,0 +1,272 @@ +/* + * Defines and Macros for Interrupt-Service-Routines + * collected and partly created by + * Martin Thomas + * + * Copyright 2005 M. Thomas + * No guarantees, warrantees, or promises, implied or otherwise. + * May be used for hobby or commercial purposes provided copyright + * notice remains intact. + */ + +#ifndef interrupt_utils_ +#define interrupt_utils_ + +/* + The following defines are usefull for + interrupt service routine declarations. +*/ + +/* + RAMFUNC + Attribute which defines a function to be located + in memory section .fastrun and called via "long calls". + See linker-skript and startup-code to see how the + .fastrun-section is handled. + The definition is not only useful for ISRs but since + ISRs should be executed fast the macro is defined in + this header. +*/ +#define RAMFUNC __attribute__ ((long_call, section (".fastrun"))) + + +/* + INTFUNC + standard attribute for arm-elf-gcc which marks + a function as ISR (for the VIC). Since gcc seems + to produce wrong code if this attribute is used in + thumb/thumb-interwork the attribute should only be + used for "pure ARM-mode" binaries. +*/ +#define INTFUNC __attribute__ ((interrupt("IRQ"))) + + +/* + NACKEDFUNC + gcc will not add any code to a function declared + "nacked". The user has to take care to save registers + and add the needed code for ISR functions. Some + macros for this tasks are provided below. +*/ +#define NACKEDFUNC __attribute__((naked)) + + +/****************************************************************************** + * + * MACRO Name: ISR_STORE() + * + * Description: + * This MACRO is used upon entry to an ISR with interrupt nesting. + * Should be used together with ISR_ENABLE_NEST(). The MACRO + * performs the following steps: + * + * 1 - Save the non-banked registers r0-r12 and lr onto the IRQ stack. + * + *****************************************************************************/ +#define ISR_STORE() asm volatile( \ + "STMDB SP!,{R0-R12,LR}\n" ) + + /****************************************************************************** + * + * MACRO Name: ISR_RESTORE() + * + * Description: + * This MACRO is used upon exit from an ISR with interrupt nesting. + * Should be used together with ISR_DISABLE_NEST(). The MACRO + * performs the following steps: + * + * 1 - Load the non-banked registers r0-r12 and lr from the IRQ stack. + * 2 - Adjusts resume adress + * + *****************************************************************************/ +#define ISR_RESTORE() asm volatile( \ + "LDMIA SP!,{R0-R12,LR}\n" \ + "SUBS R15,R14,#0x0004\n" ) + +/****************************************************************************** + * + * MACRO Name: ISR_ENABLE_NEST() + * + * Description: + * This MACRO is used upon entry from an ISR with interrupt nesting. + * Should be used after ISR_STORE. + * + *****************************************************************************/ + +#define ISR_ENABLE_NEST() asm volatile( \ + "MRS LR, SPSR \n" \ + "STMFD SP!, {LR} \n" \ + "MSR CPSR_c, #0x1f \n" \ + "STMFD SP!, {LR} " ) + +/****************************************************************************** + * + * MACRO Name: ISR_DISABLE_NEST() + * + * Description: + * This MACRO is used upon entry from an ISR with interrupt nesting. + * Should be used before ISR_RESTORE. + * + *****************************************************************************/ + +#define ISR_DISABLE_NEST() asm volatile( \ + "LDMFD SP!, {LR} \n" \ + "MSR CPSR_c, #0x92 \n" \ + "LDMFD SP!, {LR} \n" \ + "MSR SPSR_cxsf, LR \n" ) + + + +/* + * The following marcos are from the file "armVIC.h" by: + * + * Copyright 2004, R O SoftWare + * No guarantees, warrantees, or promises, implied or otherwise. + * May be used for hobby or commercial purposes provided copyright + * notice remains intact. + * + */ + +/****************************************************************************** + * + * MACRO Name: ISR_ENTRY() + * + * Description: + * This MACRO is used upon entry to an ISR. The current version of + * the gcc compiler for ARM does not produce correct code for + * interrupt routines to operate properly with THUMB code. The MACRO + * performs the following steps: + * + * 1 - Adjust address at which execution should resume after servicing + * ISR to compensate for IRQ entry + * 2 - Save the non-banked registers r0-r12 and lr onto the IRQ stack. + * 3 - Get the status of the interrupted program is in SPSR. + * 4 - Push it onto the IRQ stack as well. + * + *****************************************************************************/ +#define ISR_ENTRY() asm volatile(" sub lr, lr,#4\n" \ + " stmfd sp!,{r0-r12,lr}\n" \ + " mrs r1, spsr\n" \ + " stmfd sp!,{r1}") + +/****************************************************************************** + * + * MACRO Name: ISR_EXIT() + * + * Description: + * This MACRO is used to exit an ISR. The current version of the gcc + * compiler for ARM does not produce correct code for interrupt + * routines to operate properly with THUMB code. The MACRO performs + * the following steps: + * + * 1 - Recover SPSR value from stack + * 2 - and restore its value + * 3 - Pop the return address & the saved general registers from + * the IRQ stack & return + * + *****************************************************************************/ +#define ISR_EXIT() asm volatile(" ldmfd sp!,{r1}\n" \ + " msr spsr_c,r1\n" \ + " ldmfd sp!,{r0-r12,pc}^") + +/****************************************************************************** + * + * Function Name: disableIRQ() + * + * Description: + * This function sets the IRQ disable bit in the status register + * + * Calling Sequence: + * void + * + * Returns: + * previous value of CPSR + * + *****************************************************************************/ +unsigned disableIRQ(void); + +/****************************************************************************** + * + * Function Name: enableIRQ() + * + * Description: + * This function clears the IRQ disable bit in the status register + * + * Calling Sequence: + * void + * + * Returns: + * previous value of CPSR + * + *****************************************************************************/ +unsigned enableIRQ(void); + +/****************************************************************************** + * + * Function Name: restoreIRQ() + * + * Description: + * This function restores the IRQ disable bit in the status register + * to the value contained within passed oldCPSR + * + * Calling Sequence: + * void + * + * Returns: + * previous value of CPSR + * + *****************************************************************************/ +unsigned restoreIRQ(unsigned oldCPSR); + +/****************************************************************************** + * + * Function Name: disableFIQ() + * + * Description: + * This function sets the FIQ disable bit in the status register + * + * Calling Sequence: + * void + * + * Returns: + * previous value of CPSR + * + *****************************************************************************/ +unsigned disableFIQ(void); + +/****************************************************************************** + * + * Function Name: enableFIQ() + * + * Description: + * This function clears the FIQ disable bit in the status register + * + * Calling Sequence: + * void + * + * Returns: + * previous value of CPSR + * + *****************************************************************************/ +unsigned enableFIQ(void); + +/****************************************************************************** + * + * Function Name: restoreFIQ() + * + * Description: + * This function restores the FIQ disable bit in the status register + * to the value contained within passed oldCPSR + * + * Calling Sequence: + * void + * + * Returns: + * previous value of CPSR + * + *****************************************************************************/ +unsigned restoreFIQ(unsigned oldCPSR); + + +#endif + diff --git a/include/isr.h b/include/isr.h new file mode 100644 index 000000000..0583ffc7e --- /dev/null +++ b/include/isr.h @@ -0,0 +1,22 @@ +#ifndef ISR_H +#define ISR_H + +#include "embedded_types.h" + +#define INTBASE (0x80020000) +#define INTENNUM_OFF (0x8) +#define INTSRC_OFF (0x30) + +#define INTENNUM INTBASE + INTENNUM_OFF +#define INTSRC INTBASE + INTSRC_OFF + + +#define no_isrs() no_tmr_isr(); + +#define enable_tmr_irq() *(volatile uint32_t *)(INTENNUM) = 5; +#define no_tmr_isr() void tmr_isr(void) { return; } + +extern void tmr_isr(void); + +#endif + diff --git a/include/sys-interrupt.h b/include/sys-interrupt.h new file mode 100644 index 000000000..cdaf8d2c3 --- /dev/null +++ b/include/sys-interrupt.h @@ -0,0 +1,29 @@ +#ifndef __SYS_INTERRUPT_H +#define __SYS_INTERRUPT_H + +/* Returns true if it handled an active interrupt */ +typedef int (*SystemInterruptFunc)(); + +typedef struct _SystemInterruptHandler SystemInterruptHandler; +struct _SystemInterruptHandler +{ + SystemInterruptHandler *next; + SystemInterruptFunc handler; +}; + +void +sys_interrupt_enable(); + +void +sys_interrupt_disable(); + +void +sys_interrupt_append_handler(SystemInterruptHandler *handler); + +void +sys_interrupt_prepend_handler(SystemInterruptHandler *handler); + +void +sys_interrupt_remove_handler(SystemInterruptHandler *handler); + +#endif /* __SYS_INTERRUPT_H */ diff --git a/src/interrupt-utils.c b/src/interrupt-utils.c new file mode 100644 index 000000000..2e2f7c1e2 --- /dev/null +++ b/src/interrupt-utils.c @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * $RCSfile: interrupt-utils.c,v $ + * $Revision: 1.2 $ + * + * This module provides the interface routines for setting up and + * controlling the various interrupt modes present on the ARM processor. + * Copyright 2004, R O SoftWare + * No guarantees, warrantees, or promises, implied or otherwise. + * May be used for hobby or commercial purposes provided copyright + * notice remains intact. + * + *****************************************************************************/ +#include "interrupt-utils.h" + +#define IRQ_MASK 0x00000080 +#define FIQ_MASK 0x00000040 +#define INT_MASK (IRQ_MASK | FIQ_MASK) + +unsigned __get_cpsr(void) +{ + unsigned long retval; + asm volatile ( + ".code 32;" + "mrs %0, cpsr;" + ".code 16;" + : "=r" (retval) : + ); + return retval; +} + +void __set_cpsr(unsigned val) +{ + asm volatile ( + ".code 32;" + "msr cpsr_c, %0;" + ".code 16;" + : : "r" (val) + ); +} + + +unsigned disableIRQ(void) +{ + unsigned _cpsr; + + _cpsr = __get_cpsr(); + __set_cpsr(_cpsr | IRQ_MASK); + return _cpsr; +} + +unsigned restoreIRQ(unsigned oldCPSR) +{ + unsigned _cpsr; + + _cpsr = __get_cpsr(); + __set_cpsr((_cpsr & ~IRQ_MASK) | (oldCPSR & IRQ_MASK)); + return _cpsr; +} + +unsigned enableIRQ(void) +{ + unsigned _cpsr; + + _cpsr = __get_cpsr(); + __set_cpsr(_cpsr & ~IRQ_MASK); + return _cpsr; +} + +unsigned disableFIQ(void) +{ + unsigned _cpsr; + + _cpsr = __get_cpsr(); + __set_cpsr(_cpsr | FIQ_MASK); + return _cpsr; +} + +unsigned restoreFIQ(unsigned oldCPSR) +{ + unsigned _cpsr; + + _cpsr = __get_cpsr(); + __set_cpsr((_cpsr & ~FIQ_MASK) | (oldCPSR & FIQ_MASK)); + return _cpsr; +} + +unsigned enableFIQ(void) +{ + unsigned _cpsr; + + _cpsr = __get_cpsr(); + __set_cpsr(_cpsr & ~FIQ_MASK); + return _cpsr; +} diff --git a/src/isr.c b/src/isr.c new file mode 100644 index 000000000..913374208 --- /dev/null +++ b/src/isr.c @@ -0,0 +1,22 @@ +#include "embedded_types.h" +//#include "interrupt-utils.h" +#include "isr.h" + +#define reg32(x) (*(volatile uint32_t *)(x)) + +//__attribute__ ((interrupt("IRQ"))) +void isr(void) +{ +// ISR_ENTRY(); + /* check for TMR0 interrupt */ + tmr_isr(); // led turns off if I have this, indicating that the isr does jump to tmr_isr +// if(reg32(INTSRC) & (1<<5)) { tmr_isr(); } +// asm("SUBS PC,R14_IRQ,#4") +// enableIRQ(); // I think this is necessary, but the LED never turns off when I have this +// ISR_EXIT(); // behavior doesn't change if I have this or not. + +/* putting anything in here breaks the other code :( */ + +// asm("ldmfd sp!, {r0-r12,lr}"); +// enableIRQ(); +} diff --git a/src/nvm.c b/src/nvm.c new file mode 100644 index 000000000..c4d54d513 --- /dev/null +++ b/src/nvm.c @@ -0,0 +1,5 @@ +#include "nvm.h" + +volatile nvmErr_t (*nvm_detect)(nvmInterface_t nvmInterface,nvmType_t* pNvmType) = 0x00006cb9; +volatile nvmErr_t (*nvm_read)(nvmInterface_t nvmInterface , nvmType_t nvmType , void *pDest, uint32_t address, uint32_t numBytes) = 0x00006d69; +volatile void(*nvm_setsvar)(uint32_t zero_for_awesome) = 0x00007085; diff --git a/src/start.S b/src/start.S index 4d2b6cb68..0d96a513c 100644 --- a/src/start.S +++ b/src/start.S @@ -26,15 +26,33 @@ * MA 02111-1307 USA */ +/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */ + + .equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */ + .equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */ + + .equ USR_MODE, 0x10 + .equ FIQ_MODE, 0x11 + .equ IRQ_MODE, 0x12 + .equ SVC_MODE, 0x13 + .equ ABT_MODE, 0x17 + .equ UND_MODE, 0x1B + .equ SYS_MODE, 0x1F + .equ usr_stack_size, 256*4 + .equ irq_stack_size, 128*4 + .equ fiq_stack_size, 128*4 + .equ und_stack_size, 32*4 + .equ abt_stack_size, 32*4 + .equ sup_stack_size, 32*4 + /* ************************************************************************* * * Jump vector table as in table 3.1 in [1] * ************************************************************************* - */ - + */ .set base, . .set _rom_data_init, 0x108d0 @@ -75,7 +93,36 @@ ROM_var_end: .word 0 .code 32 .align _begin: + + ldr r1,=_system_stack + msr cpsr_c,#(SVC_MODE | I_BIT | F_BIT) + add r1,r1,#sup_stack_size + mov sp,r1 + + msr cpsr_c,#(IRQ_MODE | I_BIT | F_BIT) + add r1,r1,#irq_stack_size + mov sp,r1 + + msr cpsr_c,#(FIQ_MODE | I_BIT | F_BIT) + add r1,r1,#fiq_stack_size + mov sp,r1 + + msr cpsr_c,#(ABT_MODE | I_BIT | F_BIT) + add r1,r1,#abt_stack_size + mov sp,r1 + + msr cpsr_c,#(UND_MODE | I_BIT | F_BIT) + add r1,r1,#und_stack_size + mov sp,r1 + +// msr cpsr_c,#(USR_MODE | I_BIT | F_BIT) + bl _rom_data_init+.-base + msr cpsr_c,#(SVC_MODE) // turn on interrupts --- for debug only +// msr cpsr_c,#(USR_MODE) // turn on interrupts --- for debug only +// add r1,r1,#usr_stack_size +// mov sp,r1 + b main _undefined_instruction: .word undefined_instruction @@ -85,9 +132,8 @@ _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq - .balignl 16,0xdeadbeef - - + .balignl 16,0xdeadbeef + /* ************************************************************************* * @@ -108,6 +154,10 @@ _TEXT_BASE: _armboot_start: .word _start +_system_stack: + . = . + usr_stack_size + irq_stack_size + fiq_stack_size + und_stack_size + abt_stack_size + sup_stack_size + + /* * These are defined in the board-specific linker script. */ @@ -121,6 +171,8 @@ _bss_end: _start_armboot: .word main + + /* ************************************************************************* * @@ -142,42 +194,6 @@ cpu_init_crit: ************************************************************************* */ -@ -@ IRQ stack frame. -@ -#define S_FRAME_SIZE 72 - -#define S_OLD_R0 68 -#define S_PSR 64 -#define S_PC 60 -#define S_LR 56 -#define S_SP 52 - -#define S_IP 48 -#define S_FP 44 -#define S_R10 40 -#define S_R9 36 -#define S_R8 32 -#define S_R7 28 -#define S_R6 24 -#define S_R5 20 -#define S_R4 16 -#define S_R3 12 -#define S_R2 8 -#define S_R1 4 -#define S_R0 0 - -#define MODE_SVC 0x13 -#define I_BIT 0x80 - - - .macro get_irq_stack @ setup IRQ stack - ldr sp, IRQ_STACK_START - .endm - - .macro get_fiq_stack @ setup FIQ stack - ldr sp, FIQ_STACK_START - .endm /* * exception handlers @@ -200,8 +216,18 @@ not_used: .align 5 irq: - - .align 5 + push {lr} + movs lr,pc + b isr + pop {lr} + subs pc,r14,#4 // suggested irq return cmd +// STMFD sp!, {r0-r12,lr} +// MOVNE lr,pc +// ldr r0, =isr +// BX r0 +// LDMFD r13!, {r0-r12,r14} +// MOVS PC, R14 +// subs pc, r14, #4 fiq: .align 5 @@ -209,3 +235,4 @@ fiq: .globl reset_cpu reset_cpu: mov pc, r0 + diff --git a/src/sys-interrupt.c b/src/sys-interrupt.c new file mode 100644 index 000000000..6a8b36e1d --- /dev/null +++ b/src/sys-interrupt.c @@ -0,0 +1,97 @@ +#include "sys-interrupt.h" +#include "interrupt-utils.h" + +#include "embedded_types.h" + +#define ATTR + +#ifndef NULL +#define NULL 0 +#endif + + +static SystemInterruptHandler *handlers = NULL; + +static void +system_int_safe (void) __attribute__((noinline)); + +static void +system_int_safe (void) +{ + SystemInterruptHandler *h; + h = handlers; + while (h) { + if (h->handler()) break; + h = h->next; + } +} + +static void NACKEDFUNC ATTR +system_int (void) /* System Interrupt Handler */ +{ + ISR_ENTRY(); + system_int_safe(); + ISR_EXIT(); +} + +static unsigned int enabled = 0; /* Number of times the system + interrupt has been enabled */ + +#define INTCNTL 0x80020000 +#define DIS_INT *((volatile uint32_t *)INTCNTL) = 3 << 19; +#define EN_INT if (enabled > 0) *((volatile uint32_t *)INTCNTL) = 0; + +void +sys_interrupt_enable() +{ + if (enabled++ == 0) { + /* Enable */ + EN_INT; + } +} + + +void +sys_interrupt_disable() +{ + if (--enabled == 0) { + DIS_INT; + } +} + +void +sys_interrupt_append_handler(SystemInterruptHandler *handler) +{ + SystemInterruptHandler **h = &handlers; + while(*h) { + h = &(*h)->next; + } + DIS_INT; + *h = handler; + handler->next = NULL; + EN_INT; +} + +void +sys_interrupt_prepend_handler(SystemInterruptHandler *handler) +{ + DIS_INT; + handler->next = handlers; + handlers = handler; + EN_INT; +} + +void +sys_interrupt_remove_handler(SystemInterruptHandler *handler) +{ + SystemInterruptHandler **h = &handlers; + while(*h) { + if (*h == handler) { + DIS_INT; + *h = handler->next; + EN_INT; + break; + } + h = &(*h)->next; + } +} diff --git a/tests/blink-blue.c b/tests/blink-blue.c index dda1750bf..a0d59dee7 100644 --- a/tests/blink-blue.c +++ b/tests/blink-blue.c @@ -5,6 +5,9 @@ #define DELAY 400000 #include "embedded_types.h" +#include "isr.h" + +no_isrs(); __attribute__ ((section ("startup"))) void main(void) { diff --git a/tests/blink-green.c b/tests/blink-green.c index 2a7aa7add..c7bed04eb 100644 --- a/tests/blink-green.c +++ b/tests/blink-green.c @@ -5,6 +5,9 @@ #define DELAY 400000 #include "embedded_types.h" +#include "isr.h" + +no_isrs(); __attribute__ ((section ("startup"))) void main(void) { diff --git a/tests/blink-red.c b/tests/blink-red.c index 0780033e0..f1da55417 100644 --- a/tests/blink-red.c +++ b/tests/blink-red.c @@ -5,6 +5,9 @@ #define DELAY 400000 #include "embedded_types.h" +#include "isr.h" + +no_isrs(); __attribute__ ((section ("startup"))) void main(void) { *(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000100; diff --git a/tests/blink-white.c b/tests/blink-white.c index 87a7f6720..18ba37308 100644 --- a/tests/blink-white.c +++ b/tests/blink-white.c @@ -5,6 +5,9 @@ #define DELAY 400000 #include "embedded_types.h" +#include "isr.h" + +no_isrs(); __attribute__ ((section ("startup"))) void main(void) { diff --git a/tests/nvm-read.c b/tests/nvm-read.c index efbd22f64..12c2e44cc 100644 --- a/tests/nvm-read.c +++ b/tests/nvm-read.c @@ -29,6 +29,10 @@ void put_hex32(uint32_t x); const uint8_t hex[16]={'0','1','2','3','4','5','6','7', '8','9','a','b','c','d','e','f'}; +#include "isr.h" + +no_isrs(); + #define NBYTES 1024 __attribute__ ((section ("startup"))) void main(void) { diff --git a/tests/rftest-rx.c b/tests/rftest-rx.c index aeecbb35e..fb91e349e 100644 --- a/tests/rftest-rx.c +++ b/tests/rftest-rx.c @@ -77,6 +77,9 @@ void toggle_led(void) { } } +#include "isr.h" +no_isrs(); + __attribute__ ((section ("startup"))) void main(void) { uint8_t c; diff --git a/tests/rftest-tx.c b/tests/rftest-tx.c index de688bdef..b6f607934 100644 --- a/tests/rftest-tx.c +++ b/tests/rftest-tx.c @@ -112,6 +112,9 @@ void fill_data(void) { } } +#include "isr.h" +no_isrs(); + __attribute__ ((section ("startup"))) void main(void) { uint8_t c; diff --git a/tests/romimg.c b/tests/romimg.c index 51ba68d8b..5b2d346eb 100644 --- a/tests/romimg.c +++ b/tests/romimg.c @@ -28,6 +28,9 @@ const uint8_t hex[16]={'0','1','2','3','4','5','6','7', #define DUMP_LEN 0x00014000 //#define DUMP_LEN 16 +#include "isr.h" +no_isrs(); + __attribute__ ((section ("startup"))) void main(void) { volatile uint32_t i; diff --git a/tests/tmr-ints.c b/tests/tmr-ints.c new file mode 100644 index 000000000..e93b142e1 --- /dev/null +++ b/tests/tmr-ints.c @@ -0,0 +1,134 @@ +/* Timer registers are all 16-bit wide with 16-bit access only */ +#define TMR_OFFSET (0x20) +#define TMR_BASE (0x80007000) +#define TMR0_BASE (TMR_BASE) +#define TMR1_BASE (TMR_BASE + TMR_OFFSET*1) +#define TMR2_BASE (TMR_BASE + TMR_OFFSET*2) +#define TMR3_BASE (TMR_BASE + TMR_OFFSET*3) + +#define TMR_REGOFF_COMP1 (0x0) +#define TMR_REGOFF_COMP2 (0x2) +#define TMR_REGOFF_CAPT (0x4) +#define TMR_REGOFF_LOAD (0x6) +#define TMR_REGOFF_HOLD (0x8) +#define TMR_REGOFF_CNTR (0xa) +#define TMR_REGOFF_CTRL (0xc) +#define TMR_REGOFF_SCTRL (0xe) +#define TMR_REGOFF_CMPLD1 (0x10) +#define TMR_REGOFF_CMPLD2 (0x12) +#define TMR_REGOFF_CSCTRL (0x14) +#define TMR_REGOFF_ENBL (0x1e) + +/* Timer 0 registers */ +#define TMR0_COMP1 (TMR0_BASE + TMR_REGOFF_COMP1) +#define TMR0_COMP_UP TMR0_COMP1 +#define TMR0_COMP2 (TMR0_BASE + TMR_REGOFF_COMP2) +#define TMR0_COMP_DOWN TMR0_COMP2 +#define TMR0_CAPT (TMR0_BASE + TMR_REGOFF_CAPT) +#define TMR0_LOAD (TMR0_BASE + TMR_REGOFF_LOAD) +#define TMR0_HOLD (TMR0_BASE + TMR_REGOFF_HOLD) +#define TMR0_CNTR (TMR0_BASE + TMR_REGOFF_CTRL) +#define TMR0_CTRL (TMR0_BASE + TMR_REGOFF_CTRL) +#define TMR0_SCTRL (TMR0_BASE + TMR_REGOFF_SCTRL) +#define TMR0_CMPLD1 (TMR0_BASE + TMR_REGOFF_CMPLD1) +#define TMR0_CMPLD2 (TMR0_BASE + TMR_REGOFF_CMPLD2) +#define TMR0_CSCTRL (TMR0_BASE + TMR_REGOFF_CSCTRL) + +/* one enable register to rule them all */ +#define TMR_ENBL TMR0_BASE + TMR_REGOFF_ENBL + +#define MBAR_GPIO 0x80000000 +#define GPIO_PAD_DIR0 0x80000000 +#define GPIO_DATA0 0x80000008 +#define UART1_DATA 0x80005008 +#define DELAY 400000 + +#define reg32(x) (*(volatile uint32_t *)(x)) +#define reg16(x) (*(volatile uint16_t *)(x)) + +#include "embedded_types.h" +//#include "sys-interrupt.h" + +#include "isr.h" + +volatile uint8_t led; + +#define LED_VAL 0x00000300 +#define led_init() do { reg32(GPIO_PAD_DIR0) = LED_VAL; } while(0); +#define led_on() do { led = 1; reg32(GPIO_DATA0) = LED_VAL; } while(0); +#define led_off() do { led = 0; reg32(GPIO_DATA0) = 0x00000000; } while(0); + +void toggle_led(void) { + if(0 == led) { + led_on(); + led = 1; + + } else { + led_off(); + } +} + +void tmr_isr(void) { + + toggle_led(); + reg16(TMR0_SCTRL) = 0; + reg16(TMR0_CSCTRL) = 0x0040; /* clear compare flag */ + +} + + +/* void enIRQ(void) { */ +/* asm volatile ( */ +/* ".code 32;" */ +/* "msr cpsr_c,#0x10;" */ +/* ".code 16;" */ +/* ); */ +/* } */ + + +__attribute__ ((section ("startup"))) +void main(void) { + +// *(volatile uint32_t *)0x80020010 = 0x20; +// *(volatile uint32_t *)0x80020034 = 0xffff; //force an int. + + /* pin direction */ + led_init(); + + /* timer setup */ + /* CTRL */ +#define COUNT_MODE 1 /* use rising edge of primary source */ +#define PRIME_SRC 0xf /* Perip. clock with 128 prescale (for 24Mhz = 187500Hz)*/ +#define SEC_SRC 0 /* don't need this */ +#define ONCE 0 /* keep counting */ +#define LEN 1 /* count until compare then reload with value in LOAD */ +#define DIR 0 /* count up */ +#define CO_INIT 0 /* other counters cannot force a re-initialization of this counter */ +#define OUT_MODE 0 /* OFLAG is asserted while counter is active */ + + reg16(TMR_ENBL) = 0; /* tmrs reset to enabled */ + reg16(TMR0_SCTRL) = 0; + reg16(TMR0_CSCTRL) =0x0040; + reg16(TMR0_LOAD) = 0; /* reload to zero */ + reg16(TMR0_COMP_UP) = 18750; /* trigger a reload at the end */ + reg16(TMR0_CMPLD1) = 18750; /* compare 1 triggered reload level, 10HZ maybe? */ + reg16(TMR0_CNTR) = 0; /* reset count register */ + reg16(TMR0_CTRL) = (COUNT_MODE<<13) | (PRIME_SRC<<9) | (SEC_SRC<<7) | (ONCE<<6) | (LEN<<5) | (DIR<<4) | (CO_INIT<<3) | (OUT_MODE); + reg16(TMR_ENBL) = 0xf; /* enable all the timers --- why not? */ + + led_on(); + + enable_tmr_irq(); + +// enIRQ(); + + /* go into user mode to handle IRQs */ + /* disabling interrupts is now difficult */ + asm(".code 32;" + "msr cpsr_c,#(0x10);" + ".code 16; "); + + while(1) { + /* sit here and let the interrupts do the work */ + }; +} diff --git a/tests/tmr.c b/tests/tmr.c new file mode 100644 index 000000000..d09912e63 --- /dev/null +++ b/tests/tmr.c @@ -0,0 +1,95 @@ +/* Timer registers are all 16-bit wide with 16-bit access only */ +#define TMR_OFFSET (0x20) +#define TMR_BASE (0x80007000) +#define TMR0_BASE (TMR_BASE) +#define TMR1_BASE (TMR_BASE + TMR_OFFSET*1) +#define TMR2_BASE (TMR_BASE + TMR_OFFSET*2) +#define TMR3_BASE (TMR_BASE + TMR_OFFSET*3) + +#define TMR_REGOFF_COMP1 (0x0) +#define TMR_REGOFF_COMP2 (0x2) +#define TMR_REGOFF_CAPT (0x4) +#define TMR_REGOFF_LOAD (0x6) +#define TMR_REGOFF_HOLD (0x8) +#define TMR_REGOFF_CNTR (0xa) +#define TMR_REGOFF_CTRL (0xc) +#define TMR_REGOFF_SCTRL (0xe) +#define TMR_REGOFF_CMPLD1 (0x10) +#define TMR_REGOFF_CMPLD2 (0x12) +#define TMR_REGOFF_CSCTRL (0x14) +#define TMR_REGOFF_ENBL (0x1e) + +/* Timer 0 registers */ +#define TMR0_COMP1 (TMR0_BASE + TMR_REGOFF_COMP1) +#define TMR0_COMP_UP TMR0_COMP1 +#define TMR0_COMP2 (TMR0_BASE + TMR_REGOFF_COMP2) +#define TMR0_COMP_DOWN TMR0_COMP2 +#define TMR0_CAPT (TMR0_BASE + TMR_REGOFF_CAPT) +#define TMR0_LOAD (TMR0_BASE + TMR_REGOFF_LOAD) +#define TMR0_HOLD (TMR0_BASE + TMR_REGOFF_HOLD) +#define TMR0_CNTR (TMR0_BASE + TMR_REGOFF_CTRL) +#define TMR0_CTRL (TMR0_BASE + TMR_REGOFF_CTRL) +#define TMR0_SCTRL (TMR0_BASE + TMR_REGOFF_SCTRL) +#define TMR0_CMPLD1 (TMR0_BASE + TMR_REGOFF_CMPLD1) +#define TMR0_CMPLD2 (TMR0_BASE + TMR_REGOFF_CMPLD2) +#define TMR0_CSCTRL (TMR0_BASE + TMR_REGOFF_CSCTRL) + +/* one enable register to rule them all */ +#define TMR_ENBL TMR0_BASE + TMR_REGOFF_ENBL + +#define MBAR_GPIO 0x80000000 +#define GPIO_PAD_DIR0 0x80000000 +#define GPIO_DATA0 0x80000008 +#define UART1_DATA 0x80005008 +#define DELAY 400000 + +#define reg32(x) (*(volatile uint32_t *)(x)) +#define reg16(x) (*(volatile uint16_t *)(x)) + +#include "embedded_types.h" + +#include "isr.h" +no_isrs(); + +__attribute__ ((section ("startup"))) +void main(void) { + + /* pin direction */ + reg32(GPIO_PAD_DIR0) = 0x00000400; + + /* timer setup */ + /* CTRL */ +#define COUNT_MODE 1 /* use rising edge of primary source */ +#define PRIME_SRC 0xf /* Perip. clock with 128 prescale (for 24Mhz = 187500Hz)*/ +#define SEC_SRC 0 /* don't need this */ +#define ONCE 0 /* keep counting */ +#define LEN 1 /* count until compare then reload with value in LOAD */ +#define DIR 0 /* count up */ +#define CO_INIT 0 /* other counters cannot force a re-initialization of this counter */ +#define OUT_MODE 0 /* OFLAG is asserted while counter is active */ + + reg16(TMR_ENBL) = 0; /* tmrs reset to enabled */ + reg16(TMR0_SCTRL) = 0; + reg16(TMR0_LOAD) = 0; /* reload to zero */ + reg16(TMR0_COMP_UP) = 18750; /* trigger a reload at the end */ + reg16(TMR0_CMPLD1) = 18750; /* compare 1 triggered reload level, 10HZ maybe? */ + reg16(TMR0_CNTR) = 0; /* reset count register */ + reg16(TMR0_CTRL) = (COUNT_MODE<<13) | (PRIME_SRC<<9) | (SEC_SRC<<7) | (ONCE<<6) | (LEN<<5) | (DIR<<4) | (CO_INIT<<3) | (OUT_MODE); + reg16(TMR_ENBL) = 0xf; /* enable all the timers --- why not? */ + + while(1) { + + /* blink on */ + reg32(GPIO_DATA0) = 0x00000400; + + while((reg16(TMR0_SCTRL)>>15) == 0) { continue; } + reg16(TMR0_SCTRL) = 0; /*clear bit 15, and all the others --- should be ok, but clearly not "the right thing to do" */ + + /* blink off */ + reg32(GPIO_DATA0) = 0x00000000; + + while((reg16(TMR0_SCTRL)>>15) == 0) { continue; } + reg16(TMR0_SCTRL) = 0; /*clear bit 15, and all the others --- should be ok, but clearly not "the right thing to do" */ + + }; +} diff --git a/tests/uart1-loopback.c b/tests/uart1-loopback.c index ce516d7ad..b3eec3940 100644 --- a/tests/uart1-loopback.c +++ b/tests/uart1-loopback.c @@ -11,6 +11,9 @@ #include "embedded_types.h" +#include "isr.h" +no_isrs(); + __attribute__ ((section ("startup"))) void main(void) { /* Restore UART regs. to default */