From d25385d2aae709c1f9c7673cd4d03a52c35db243 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 20 Apr 2009 14:15:24 -0400 Subject: [PATCH 01/10] blink blue but with the timer. --- Makefile | 2 +- tests/tmr.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 tests/tmr.c diff --git a/Makefile b/Makefile index f1dc502fa..1932e2fef 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ tests/rftest-tx.obj: src/maca.o src/nvm.o $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ %.dis: %.obj - $(OBJDUMP) -D $< > $@ + $(OBJDUMP) -SD $< > $@ %.obj: $(LDSCRIPT) %.o $(LD) $(LDFLAGS) $(AOBJS) \ diff --git a/tests/tmr.c b/tests/tmr.c new file mode 100644 index 000000000..22c12a75d --- /dev/null +++ b/tests/tmr.c @@ -0,0 +1,92 @@ +/* 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" + +__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" */ + + }; +} From e012142abe2f1bcb4870fd9c5c35329ba2ce4f61 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 20 Apr 2009 14:28:53 -0400 Subject: [PATCH 02/10] initial interrupt stuff taken from Contiki --- src/interrupt-utils.c | 84 +++++++++++++ src/interrupt-utils.h | 272 ++++++++++++++++++++++++++++++++++++++++++ src/sys-interrupt.c | 100 ++++++++++++++++ src/sys-interrupt.h | 31 +++++ tests/tmr-ints.c | 92 ++++++++++++++ 5 files changed, 579 insertions(+) create mode 100644 src/interrupt-utils.c create mode 100644 src/interrupt-utils.h create mode 100644 src/sys-interrupt.c create mode 100644 src/sys-interrupt.h create mode 100644 tests/tmr-ints.c diff --git a/src/interrupt-utils.c b/src/interrupt-utils.c new file mode 100644 index 000000000..cd3e1bd81 --- /dev/null +++ b/src/interrupt-utils.c @@ -0,0 +1,84 @@ +/****************************************************************************** + * + * $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) + +static inline unsigned __get_cpsr(void) +{ + unsigned long retval; + asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ ); + return retval; +} + +static inline void __set_cpsr(unsigned val) +{ + asm volatile (" msr cpsr_c, %0" : /* no outputs */ : "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/interrupt-utils.h b/src/interrupt-utils.h new file mode 100644 index 000000000..29b307d88 --- /dev/null +++ b/src/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/src/sys-interrupt.c b/src/sys-interrupt.c new file mode 100644 index 000000000..b540145cb --- /dev/null +++ b/src/sys-interrupt.c @@ -0,0 +1,100 @@ +#include +#include +#include + +#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(); + *AT91C_AIC_EOICR = 0; /* End of Interrupt */ + ISR_EXIT(); +} + +static unsigned int enabled = 0; /* Number of times the system + interrupt has been enabled */ + +#define DIS_INT *AT91C_AIC_IDCR = (1 << AT91C_ID_SYS) +#define EN_INT if (enabled > 0) *AT91C_AIC_IECR = (1 << AT91C_ID_SYS) + +void +sys_interrupt_enable() +{ + if (enabled++ == 0) { + /* Level trigged at priority 5 */ + AT91C_AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5; + /* Interrupt vector */ + AT91C_AIC_SVR[AT91C_ID_SYS] = (unsigned long) system_int; + /* 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/src/sys-interrupt.h b/src/sys-interrupt.h new file mode 100644 index 000000000..433db4a0f --- /dev/null +++ b/src/sys-interrupt.h @@ -0,0 +1,31 @@ +#ifndef __SYS_INTERRUPT_H__QIHZ66NP8K__ +#define __SYS_INTERRUPT_H__QIHZ66NP8K__ + + +/* Returns true if it handled an activbe 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__QIHZ66NP8K__ */ diff --git a/tests/tmr-ints.c b/tests/tmr-ints.c new file mode 100644 index 000000000..22c12a75d --- /dev/null +++ b/tests/tmr-ints.c @@ -0,0 +1,92 @@ +/* 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" + +__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" */ + + }; +} From 4f45e439844eca2940ebe93704c47822369d273d Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 20 Apr 2009 14:29:20 -0400 Subject: [PATCH 03/10] nvm source file --- src/nvm.c | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/nvm.c 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; From cfd985c8371d2678de0d372f97af946b32b1accb Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 20 Apr 2009 15:42:21 -0400 Subject: [PATCH 04/10] modified at91 interrupt code from contiki to use the mc1322x registers and to produce code that works with THUMB. --- include/interrupt-utils.h | 272 ++++++++++++++++++++++++++++++++++++++ include/sys-interrupt.h | 31 +++++ src/interrupt-utils.c | 19 ++- src/sys-interrupt.c | 17 +-- 4 files changed, 325 insertions(+), 14 deletions(-) create mode 100644 include/interrupt-utils.h create mode 100644 include/sys-interrupt.h 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/sys-interrupt.h b/include/sys-interrupt.h new file mode 100644 index 000000000..433db4a0f --- /dev/null +++ b/include/sys-interrupt.h @@ -0,0 +1,31 @@ +#ifndef __SYS_INTERRUPT_H__QIHZ66NP8K__ +#define __SYS_INTERRUPT_H__QIHZ66NP8K__ + + +/* Returns true if it handled an activbe 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__QIHZ66NP8K__ */ diff --git a/src/interrupt-utils.c b/src/interrupt-utils.c index cd3e1bd81..2e2f7c1e2 100644 --- a/src/interrupt-utils.c +++ b/src/interrupt-utils.c @@ -17,18 +17,29 @@ #define FIQ_MASK 0x00000040 #define INT_MASK (IRQ_MASK | FIQ_MASK) -static inline unsigned __get_cpsr(void) +unsigned __get_cpsr(void) { unsigned long retval; - asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ ); + asm volatile ( + ".code 32;" + "mrs %0, cpsr;" + ".code 16;" + : "=r" (retval) : + ); return retval; } -static inline void __set_cpsr(unsigned val) +void __set_cpsr(unsigned val) { - asm volatile (" msr cpsr_c, %0" : /* no outputs */ : "r" (val) ); + asm volatile ( + ".code 32;" + "msr cpsr_c, %0;" + ".code 16;" + : : "r" (val) + ); } + unsigned disableIRQ(void) { unsigned _cpsr; diff --git a/src/sys-interrupt.c b/src/sys-interrupt.c index b540145cb..6a8b36e1d 100644 --- a/src/sys-interrupt.c +++ b/src/sys-interrupt.c @@ -1,6 +1,7 @@ -#include -#include -#include +#include "sys-interrupt.h" +#include "interrupt-utils.h" + +#include "embedded_types.h" #define ATTR @@ -30,24 +31,20 @@ system_int (void) /* System Interrupt Handler */ { ISR_ENTRY(); system_int_safe(); - *AT91C_AIC_EOICR = 0; /* End of Interrupt */ ISR_EXIT(); } static unsigned int enabled = 0; /* Number of times the system interrupt has been enabled */ -#define DIS_INT *AT91C_AIC_IDCR = (1 << AT91C_ID_SYS) -#define EN_INT if (enabled > 0) *AT91C_AIC_IECR = (1 << AT91C_ID_SYS) +#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) { - /* Level trigged at priority 5 */ - AT91C_AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5; - /* Interrupt vector */ - AT91C_AIC_SVR[AT91C_ID_SYS] = (unsigned long) system_int; /* Enable */ EN_INT; } From 28c1ed2105114f8a3e99f8cef83e08e1516a8daa Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 20 Apr 2009 15:43:24 -0400 Subject: [PATCH 05/10] added function sections and long-calls --- Makefile | 1 + config.mk | 4 +- src/interrupt-utils.h | 272 ------------------------------------------ src/sys-interrupt.h | 31 ----- 4 files changed, 3 insertions(+), 305 deletions(-) delete mode 100644 src/interrupt-utils.h delete mode 100644 src/sys-interrupt.h diff --git a/Makefile b/Makefile index 1932e2fef..563cd2a01 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,7 @@ all: src/start.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.c: src/interrupt-utils.o src/sys-interrupt.o %.srec: %.obj $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ diff --git a/config.mk b/config.mk index 7352f6d74..3fb973e44 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 -mcallee-super-interworking -mthumb -mthumb-interwork -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ TEXT_BASE = 0x00400000 ######################################################################### diff --git a/src/interrupt-utils.h b/src/interrupt-utils.h deleted file mode 100644 index 29b307d88..000000000 --- a/src/interrupt-utils.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * 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/src/sys-interrupt.h b/src/sys-interrupt.h deleted file mode 100644 index 433db4a0f..000000000 --- a/src/sys-interrupt.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __SYS_INTERRUPT_H__QIHZ66NP8K__ -#define __SYS_INTERRUPT_H__QIHZ66NP8K__ - - -/* Returns true if it handled an activbe 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__QIHZ66NP8K__ */ From 09b15558a15a4c440b82cdd1070e8d54c8ef64f8 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 20 Apr 2009 18:31:13 -0400 Subject: [PATCH 06/10] preliminary interrupts. looks like it is entering the isr but isn't leaving correctly. --- Makefile | 19 +++++++++++---- boot.lds | 1 + include/sys-interrupt.h | 10 ++++---- src/start.S | 2 +- tests/blink-blue.c | 3 +++ tests/blink-green.c | 3 +++ tests/blink-red.c | 3 +++ tests/blink-white.c | 3 +++ tests/nvm-read.c | 4 ++++ tests/rftest-rx.c | 3 +++ tests/rftest-tx.c | 3 +++ tests/romimg.c | 3 +++ tests/tmr-ints.c | 52 +++++++++++++++++++++++++++++------------ tests/tmr.c | 3 +++ tests/uart1-loopback.c | 3 +++ 15 files changed, 89 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 563cd2a01..dc29499dc 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,12 +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.c: src/interrupt-utils.o src/sys-interrupt.o +tests/tmr-ints.obj: src/interrupt-utils.o src/sys-interrupt.o 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 -mthumb-interwork -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ + + +src/isr.o: src/isr.c + $(CC) $(NOTHUMB_CPPFLAGS) $(NOTHUMB_CPPFLAGS_EXTRA) -c -o $@ $< %.srec: %.obj $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ @@ -77,7 +88,7 @@ tests/tmr-ints.c: src/interrupt-utils.o src/sys-interrupt.o %.dis: %.obj $(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/include/sys-interrupt.h b/include/sys-interrupt.h index 433db4a0f..cdaf8d2c3 100644 --- a/include/sys-interrupt.h +++ b/include/sys-interrupt.h @@ -1,8 +1,7 @@ -#ifndef __SYS_INTERRUPT_H__QIHZ66NP8K__ -#define __SYS_INTERRUPT_H__QIHZ66NP8K__ +#ifndef __SYS_INTERRUPT_H +#define __SYS_INTERRUPT_H - -/* Returns true if it handled an activbe interrupt */ +/* Returns true if it handled an active interrupt */ typedef int (*SystemInterruptFunc)(); typedef struct _SystemInterruptHandler SystemInterruptHandler; @@ -12,7 +11,6 @@ struct _SystemInterruptHandler SystemInterruptFunc handler; }; - void sys_interrupt_enable(); @@ -28,4 +26,4 @@ sys_interrupt_prepend_handler(SystemInterruptHandler *handler); void sys_interrupt_remove_handler(SystemInterruptHandler *handler); -#endif /* __SYS_INTERRUPT_H__QIHZ66NP8K__ */ +#endif /* __SYS_INTERRUPT_H */ diff --git a/src/start.S b/src/start.S index ec6f93444..2e17e424e 100644 --- a/src/start.S +++ b/src/start.S @@ -197,7 +197,7 @@ not_used: .align 5 irq: - + b isr .align 5 fiq: 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 index 22c12a75d..acb324c64 100644 --- a/tests/tmr-ints.c +++ b/tests/tmr-ints.c @@ -47,12 +47,40 @@ #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 */ + +} __attribute__ ((section ("startup"))) void main(void) { /* pin direction */ - reg32(GPIO_PAD_DIR0) = 0x00000400; + led_init(); /* timer setup */ /* CTRL */ @@ -66,7 +94,8 @@ void main(void) { #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_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? */ @@ -74,19 +103,12 @@ void main(void) { 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(); + enableIRQ(); + 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" */ - + /* sit here and let the interrupts do the work */ }; } diff --git a/tests/tmr.c b/tests/tmr.c index 22c12a75d..d09912e63 100644 --- a/tests/tmr.c +++ b/tests/tmr.c @@ -48,6 +48,9 @@ #include "embedded_types.h" +#include "isr.h" +no_isrs(); + __attribute__ ((section ("startup"))) void main(void) { 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 */ From 10fdafbcb2dfdb87af5aadea13f0138b85891d59 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 20 Apr 2009 18:38:45 -0400 Subject: [PATCH 07/10] initial isr. has problems. --- include/isr.h | 22 ++++++++++++++++++++++ src/isr.c | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 include/isr.h create mode 100644 src/isr.c diff --git a/include/isr.h b/include/isr.h new file mode 100644 index 000000000..4939d42c4 --- /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) +#define no_tmr_isr() void tmr_isr(void) { return; } + +extern void tmr_isr(void); + +#endif + diff --git a/src/isr.c b/src/isr.c new file mode 100644 index 000000000..5b27130a0 --- /dev/null +++ b/src/isr.c @@ -0,0 +1,20 @@ +#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 :( */ + +} From bdbf279d0f8d9b3f470be5150f33e4c9b0bade3a Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Wed, 22 Apr 2009 14:55:40 -0400 Subject: [PATCH 08/10] tmr imts works. I'm not thrilled with how the interrupts and modes are set... but I'm not sure what to do about it. The big problem is that I have to be in user mode to service irqs, but I can't enable and disable F and I in usermode. All I can do is an swi and then have handler which lets me enable or disable them (like a mini-syscall). --- Makefile | 6 +-- config.mk | 2 +- include/isr.h | 2 +- src/isr.c | 8 ++-- src/start.S | 112 +++++++++++++++++++++++++++++------------------ tests/tmr-ints.c | 22 ++++++++-- 6 files changed, 98 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index dc29499dc..1f12d73dd 100644 --- a/Makefile +++ b/Makefile @@ -63,14 +63,14 @@ 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/interrupt-utils.o src/sys-interrupt.o src/isr.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 -mthumb-interwork -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ +NOTHUMB_CPPFLAGS_EXTRA = -march=armv4t -mlong-calls -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ #-mthumb-interwork src/isr.o: src/isr.c @@ -88,7 +88,7 @@ src/isr.o: src/isr.c %.dis: %.obj $(OBJDUMP) -SD $< > $@ -%.obj: $(LDSCRIPT) %.o src/interrupt-utils.o +%.obj: $(LDSCRIPT) %.o #src/interrupt-utils.o $(LD) $(LDFLAGS) $(AOBJS) \ --start-group $(PLATFORM_LIBS) --end-group \ -Map $*.map $^ -o $@ diff --git a/config.mk b/config.mk index 3fb973e44..b5f092959 100644 --- a/config.mk +++ b/config.mk @@ -26,7 +26,7 @@ # clean the slate ... PLATFORM_LDFLAGS = PLATFORM_RELFLAGS = -fno-strict-aliasing -fno-common -ffixed-r8 -ffunction-sections -msoft-float -PLATFORM_CPPFLAGS = -march=armv4t -mlong-calls -mcallee-super-interworking -mthumb -mthumb-interwork -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ +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/isr.h b/include/isr.h index 4939d42c4..0583ffc7e 100644 --- a/include/isr.h +++ b/include/isr.h @@ -13,7 +13,7 @@ #define no_isrs() no_tmr_isr(); -#define enable_tmr_irq() *(volatile uint32_t *)(INTENNUM) +#define enable_tmr_irq() *(volatile uint32_t *)(INTENNUM) = 5; #define no_tmr_isr() void tmr_isr(void) { return; } extern void tmr_isr(void); diff --git a/src/isr.c b/src/isr.c index 5b27130a0..913374208 100644 --- a/src/isr.c +++ b/src/isr.c @@ -1,15 +1,15 @@ #include "embedded_types.h" -#include "interrupt-utils.h" +//#include "interrupt-utils.h" #include "isr.h" #define reg32(x) (*(volatile uint32_t *)(x)) -__attribute__ ((interrupt("IRQ"))) +//__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 + 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 @@ -17,4 +17,6 @@ void isr(void) /* putting anything in here breaks the other code :( */ +// asm("ldmfd sp!, {r0-r12,lr}"); +// enableIRQ(); } diff --git a/src/start.S b/src/start.S index 2e17e424e..cbed1189a 100644 --- a/src/start.S +++ b/src/start.S @@ -23,15 +23,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 @@ -72,7 +90,37 @@ 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) +// add r1,r1,#usr_stack_size +// mov sp,r1 + + 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 +// swi b main _undefined_instruction: .word undefined_instruction @@ -82,9 +130,8 @@ _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq - .balignl 16,0xdeadbeef - - + .balignl 16,0xdeadbeef + /* ************************************************************************* * @@ -105,6 +152,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. */ @@ -118,6 +169,8 @@ _bss_end: _start_armboot: .word main + + /* ************************************************************************* * @@ -139,42 +192,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 @@ -197,8 +214,18 @@ not_used: .align 5 irq: + push {lr} + movs lr,pc b isr - .align 5 + 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 @@ -206,3 +233,4 @@ fiq: .globl reset_cpu reset_cpu: mov pc, r0 + diff --git a/tests/tmr-ints.c b/tests/tmr-ints.c index acb324c64..1fc7fe024 100644 --- a/tests/tmr-ints.c +++ b/tests/tmr-ints.c @@ -47,7 +47,7 @@ #define reg16(x) (*(volatile uint16_t *)(x)) #include "embedded_types.h" -#include "sys-interrupt.h" +//#include "sys-interrupt.h" #include "isr.h" @@ -76,9 +76,22 @@ void tmr_isr(void) { } + +/* 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(); @@ -94,8 +107,8 @@ void main(void) { #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_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? */ @@ -106,7 +119,8 @@ void main(void) { led_on(); enable_tmr_irq(); - enableIRQ(); + +// enIRQ(); while(1) { /* sit here and let the interrupts do the work */ From 9f31e40864c81cb018fbc60c7805cc5b6822cf31 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Wed, 22 Apr 2009 15:14:04 -0400 Subject: [PATCH 09/10] only go into usermode in the interrupt test... still sorting out the best way to handle this. --- src/start.S | 1 - tests/tmr-ints.c | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/start.S b/src/start.S index cbed1189a..683e79226 100644 --- a/src/start.S +++ b/src/start.S @@ -119,7 +119,6 @@ _begin: 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 // swi b main diff --git a/tests/tmr-ints.c b/tests/tmr-ints.c index 1fc7fe024..f72222f40 100644 --- a/tests/tmr-ints.c +++ b/tests/tmr-ints.c @@ -122,6 +122,10 @@ void main(void) { // enIRQ(); + /* go into user mode to handle IRQs */ + /* disabling interrupts is now difficult */ + asm("msr cpsr_c,#(0x10)"); + while(1) { /* sit here and let the interrupts do the work */ }; From 8964c60d9a62a93e06e6c493b9126c6cd16a678a Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Wed, 22 Apr 2009 16:04:50 -0400 Subject: [PATCH 10/10] enabling thumb only enter user mode in tmr-ints. usermode breaks rftests. --- Makefile | 2 +- config.mk | 2 +- src/start.S | 10 +++++----- tests/tmr-ints.c | 6 ++++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 1f12d73dd..4803b5e1b 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ NOTHUMB_CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \ -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 +NOTHUMB_CPPFLAGS_EXTRA = -march=armv4t -mlong-calls -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ -mthumb-interwork src/isr.o: src/isr.c diff --git a/config.mk b/config.mk index b5f092959..c21f9b280 100644 --- a/config.mk +++ b/config.mk @@ -26,7 +26,7 @@ # clean the slate ... PLATFORM_LDFLAGS = 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 +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/src/start.S b/src/start.S index 683e79226..bc991ad7d 100644 --- a/src/start.S +++ b/src/start.S @@ -113,13 +113,13 @@ _begin: mov sp,r1 // msr cpsr_c,#(USR_MODE | I_BIT | F_BIT) -// add r1,r1,#usr_stack_size -// mov sp,r1 - bl _rom_data_init+.-base - msr cpsr_c,#(SVC_MODE) // turn on interrupts --- for debug only -// swi + 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 diff --git a/tests/tmr-ints.c b/tests/tmr-ints.c index f72222f40..e93b142e1 100644 --- a/tests/tmr-ints.c +++ b/tests/tmr-ints.c @@ -124,8 +124,10 @@ void main(void) { /* go into user mode to handle IRQs */ /* disabling interrupts is now difficult */ - asm("msr cpsr_c,#(0x10)"); - + asm(".code 32;" + "msr cpsr_c,#(0x10);" + ".code 16; "); + while(1) { /* sit here and let the interrupts do the work */ };