Merge branch 'untested'
This commit is contained in:
commit
e510c078d8
18
Makefile
18
Makefile
|
@ -58,11 +58,23 @@ ALL = $(TESTS:.c=.srec) $(TESTS:.c=.bin) $(TESTS:.c=.dis)
|
||||||
|
|
||||||
.PRECIOUS: $(COBJS) $(TARGETS) $(TESTS:.c=.obj)
|
.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/nvm-read.obj: src/maca.o src/nvm.o
|
||||||
tests/rftest-rx.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/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
|
%.srec: %.obj
|
||||||
$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
|
$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
|
||||||
|
@ -74,9 +86,9 @@ tests/rftest-tx.obj: src/maca.o src/nvm.o
|
||||||
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
|
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
|
||||||
|
|
||||||
%.dis: %.obj
|
%.dis: %.obj
|
||||||
$(OBJDUMP) -D $< > $@
|
$(OBJDUMP) -SD $< > $@
|
||||||
|
|
||||||
%.obj: $(LDSCRIPT) %.o
|
%.obj: $(LDSCRIPT) %.o #src/interrupt-utils.o
|
||||||
$(LD) $(LDFLAGS) $(AOBJS) \
|
$(LD) $(LDFLAGS) $(AOBJS) \
|
||||||
--start-group $(PLATFORM_LIBS) --end-group \
|
--start-group $(PLATFORM_LIBS) --end-group \
|
||||||
-Map $*.map $^ -o $@
|
-Map $*.map $^ -o $@
|
||||||
|
|
1
boot.lds
1
boot.lds
|
@ -33,6 +33,7 @@ SECTIONS
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
src/start.o (.text)
|
src/start.o (.text)
|
||||||
|
src/isr.o (.text)
|
||||||
*(.text)
|
*(.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
# clean the slate ...
|
# clean the slate ...
|
||||||
PLATFORM_LDFLAGS =
|
PLATFORM_LDFLAGS =
|
||||||
PLATFORM_RELFLAGS = -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float
|
PLATFORM_RELFLAGS = -fno-strict-aliasing -fno-common -ffixed-r8 -ffunction-sections -msoft-float
|
||||||
PLATFORM_CPPFLAGS = -march=armv4t -mcallee-super-interworking -mthumb -mtune=arm7tdmi-s -mthumb-interwork -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
|
TEXT_BASE = 0x00400000
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
272
include/interrupt-utils.h
Normal file
272
include/interrupt-utils.h
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
/*
|
||||||
|
* Defines and Macros for Interrupt-Service-Routines
|
||||||
|
* collected and partly created by
|
||||||
|
* Martin Thomas <mthomas@rhrk.uni-kl.de>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
22
include/isr.h
Normal file
22
include/isr.h
Normal file
|
@ -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
|
||||||
|
|
29
include/sys-interrupt.h
Normal file
29
include/sys-interrupt.h
Normal file
|
@ -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 */
|
95
src/interrupt-utils.c
Normal file
95
src/interrupt-utils.c
Normal file
|
@ -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;
|
||||||
|
}
|
22
src/isr.c
Normal file
22
src/isr.c
Normal file
|
@ -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();
|
||||||
|
}
|
5
src/nvm.c
Normal file
5
src/nvm.c
Normal file
|
@ -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;
|
107
src/start.S
107
src/start.S
|
@ -26,6 +26,25 @@
|
||||||
* MA 02111-1307 USA
|
* 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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
|
@ -35,7 +54,6 @@
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
.set base, .
|
.set base, .
|
||||||
.set _rom_data_init, 0x108d0
|
.set _rom_data_init, 0x108d0
|
||||||
|
|
||||||
|
@ -75,7 +93,36 @@ ROM_var_end: .word 0
|
||||||
.code 32
|
.code 32
|
||||||
.align
|
.align
|
||||||
_begin:
|
_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
|
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
|
b main
|
||||||
|
|
||||||
_undefined_instruction: .word undefined_instruction
|
_undefined_instruction: .word undefined_instruction
|
||||||
|
@ -87,7 +134,6 @@ _irq: .word irq
|
||||||
_fiq: .word fiq
|
_fiq: .word fiq
|
||||||
.balignl 16,0xdeadbeef
|
.balignl 16,0xdeadbeef
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -108,6 +154,10 @@ _TEXT_BASE:
|
||||||
_armboot_start:
|
_armboot_start:
|
||||||
.word _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.
|
* These are defined in the board-specific linker script.
|
||||||
*/
|
*/
|
||||||
|
@ -121,6 +171,8 @@ _bss_end:
|
||||||
|
|
||||||
_start_armboot: .word main
|
_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
|
* exception handlers
|
||||||
|
@ -200,8 +216,18 @@ not_used:
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
irq:
|
irq:
|
||||||
|
push {lr}
|
||||||
.align 5
|
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:
|
fiq:
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
|
@ -209,3 +235,4 @@ fiq:
|
||||||
.globl reset_cpu
|
.globl reset_cpu
|
||||||
reset_cpu:
|
reset_cpu:
|
||||||
mov pc, r0
|
mov pc, r0
|
||||||
|
|
||||||
|
|
97
src/sys-interrupt.c
Normal file
97
src/sys-interrupt.c
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,9 @@
|
||||||
#define DELAY 400000
|
#define DELAY 400000
|
||||||
|
|
||||||
#include "embedded_types.h"
|
#include "embedded_types.h"
|
||||||
|
#include "isr.h"
|
||||||
|
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
__attribute__ ((section ("startup")))
|
__attribute__ ((section ("startup")))
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#define DELAY 400000
|
#define DELAY 400000
|
||||||
|
|
||||||
#include "embedded_types.h"
|
#include "embedded_types.h"
|
||||||
|
#include "isr.h"
|
||||||
|
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
__attribute__ ((section ("startup")))
|
__attribute__ ((section ("startup")))
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#define DELAY 400000
|
#define DELAY 400000
|
||||||
|
|
||||||
#include "embedded_types.h"
|
#include "embedded_types.h"
|
||||||
|
#include "isr.h"
|
||||||
|
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
__attribute__ ((section ("startup"))) void main(void) {
|
__attribute__ ((section ("startup"))) void main(void) {
|
||||||
*(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000100;
|
*(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000100;
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#define DELAY 400000
|
#define DELAY 400000
|
||||||
|
|
||||||
#include "embedded_types.h"
|
#include "embedded_types.h"
|
||||||
|
#include "isr.h"
|
||||||
|
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
__attribute__ ((section ("startup")))
|
__attribute__ ((section ("startup")))
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
|
|
@ -29,6 +29,10 @@ void put_hex32(uint32_t x);
|
||||||
const uint8_t hex[16]={'0','1','2','3','4','5','6','7',
|
const uint8_t hex[16]={'0','1','2','3','4','5','6','7',
|
||||||
'8','9','a','b','c','d','e','f'};
|
'8','9','a','b','c','d','e','f'};
|
||||||
|
|
||||||
|
#include "isr.h"
|
||||||
|
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
#define NBYTES 1024
|
#define NBYTES 1024
|
||||||
__attribute__ ((section ("startup")))
|
__attribute__ ((section ("startup")))
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
|
|
@ -77,6 +77,9 @@ void toggle_led(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "isr.h"
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
__attribute__ ((section ("startup")))
|
__attribute__ ((section ("startup")))
|
||||||
void main(void) {
|
void main(void) {
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
|
|
@ -112,6 +112,9 @@ void fill_data(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "isr.h"
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
__attribute__ ((section ("startup")))
|
__attribute__ ((section ("startup")))
|
||||||
void main(void) {
|
void main(void) {
|
||||||
uint8_t c;
|
uint8_t 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 0x00014000
|
||||||
//#define DUMP_LEN 16
|
//#define DUMP_LEN 16
|
||||||
|
|
||||||
|
#include "isr.h"
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
__attribute__ ((section ("startup")))
|
__attribute__ ((section ("startup")))
|
||||||
void main(void) {
|
void main(void) {
|
||||||
volatile uint32_t i;
|
volatile uint32_t i;
|
||||||
|
|
134
tests/tmr-ints.c
Normal file
134
tests/tmr-ints.c
Normal file
|
@ -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 */
|
||||||
|
};
|
||||||
|
}
|
95
tests/tmr.c
Normal file
95
tests/tmr.c
Normal file
|
@ -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" */
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -11,6 +11,9 @@
|
||||||
|
|
||||||
#include "embedded_types.h"
|
#include "embedded_types.h"
|
||||||
|
|
||||||
|
#include "isr.h"
|
||||||
|
no_isrs();
|
||||||
|
|
||||||
__attribute__ ((section ("startup")))
|
__attribute__ ((section ("startup")))
|
||||||
void main(void) {
|
void main(void) {
|
||||||
/* Restore UART regs. to default */
|
/* Restore UART regs. to default */
|
||||||
|
|
Loading…
Reference in a new issue