From 6f275ae53307d29e22fde024a6479f80e60baf41 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 3 Mar 2007 19:17:15 +0000 Subject: Add logic to initialize timer 2 git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@34 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/c5471/src/up_timerisr.c | 11 +++++- nuttx/arch/pjrc-8051/src/Makefile | 60 ++++++++++++++++++++++-------- nuttx/arch/pjrc-8051/src/up_allocateheap.c | 5 ++- nuttx/arch/pjrc-8051/src/up_internal.h | 53 ++++++++++++++++++++++++++ nuttx/arch/pjrc-8051/src/up_irq.c | 2 +- nuttx/arch/pjrc-8051/src/up_timerisr.c | 35 ++++++++++++++++- 6 files changed, 144 insertions(+), 22 deletions(-) (limited to 'nuttx/arch') diff --git a/nuttx/arch/c5471/src/up_timerisr.c b/nuttx/arch/c5471/src/up_timerisr.c index ab1155b71..4e6ad1e93 100644 --- a/nuttx/arch/c5471/src/up_timerisr.c +++ b/nuttx/arch/c5471/src/up_timerisr.c @@ -79,7 +79,7 @@ ************************************************************/ /************************************************************ - * Function: timer_isr + * Function: up_timerisr * * Description: * The timer ISR will perform a variety of services for @@ -115,6 +115,15 @@ int up_timerisr(int irq, uint32 *regs) return 0; } +/************************************************************ + * Function: up_timerinit + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ************************************************************/ + void up_timerinit(void) { uint32 val; diff --git a/nuttx/arch/pjrc-8051/src/Makefile b/nuttx/arch/pjrc-8051/src/Makefile index 1ba57af9c..acd3746ec 100644 --- a/nuttx/arch/pjrc-8051/src/Makefile +++ b/nuttx/arch/pjrc-8051/src/Makefile @@ -66,33 +66,57 @@ LDLIBS = $(addprefix -l,$(notdir $(LINKLIBS))) LDFLAGS = --model-large --nostdlib \ --data-loc 0x30 --iram-size 0x100 \ - --code-loc 0x2040 --code-size 0x5fc0 \ + --code-loc 0x20c0 --code-size 0x5f40 \ --xram-loc 0x0100 --xram-size 0x1f00 -HEAP_START = ${shell cat pass1.mem | grep "EXTERNAL RAM" | sed -e "s/[ ][ ]*/ /g" | cut -d' ' -f5} - DEPSRCS = $(SRCS) $(LINKSSRCS) +HEAP1_BASE = ${shell cat pass1.mem | grep "EXTERNAL RAM" | sed -e "s/[ ][ ]*/ /g" | cut -d' ' -f5} +HEAP2_BASE = ${shell cat pass1.mem | grep "ROM/EPROM/FLASH" | sed -e "s/[ ][ ]*/ /g" | cut -d' ' -f4} +STACK_BASE = ${shell cat pass1.mem | grep "Stack starts" | cut -d' ' -f4} + all: up_head$(OBJEXT) libarch$(LIBEXT) $(ASRCS) $(LINKASRCS): %$(ASMEXT): %.S - $(CPP) -P $(CPPFLAGS) -D__ASSEMBLY__ -DUP_HEAP_START=0x0100 -DUP_HEAP_END=0x2000 $< -o $@ + $(CPP) -P $(CPPFLAGS) -D__ASSEMBLY__ $< -o $@ $(AOBJS) $(LINKOBJS): $(ASRCS) $(LINKASRCS) $(AS) $(ASFLAGS) $< $(COBJS): %$(OBJEXT): %.c - $(CC) -c $(CFLAGS) -DUP_HEAP_START=0x0100 -DUP_HEAP_END=0x2000 $< -o $@ + $(CC) -c $(CFLAGS) $< -o $@ + +# Create a header file that contains addressing information needed by the code + +pass1.mem: + +up_mem.h: pass1.mem + @echo "#ifndef __ARCH_MEM_H" >up_mem.h + @echo "#define __ARCH_MEM_H" >>up_mem.h + @if [ -e pass1.mem ]; then \ + echo "#define UP_STACK_BASE $(STACK_BASE)" >>up_mem.h ; \ + echo "#define UP_HEAP1_BASE $(HEAP1_BASE)" >> up_mem.h ; \ + echo "#define UP_HEAP1_END 0x2000" >> up_mem.h ; \ + echo "#define UP_HEAP2_BASE $(HEAP2_BASE)" >> up_mem.h ; \ + echo "#define UP_HEAP2_END 0x8000" >> up_mem.h ; \ + else \ + echo "#define UP_STACK_BASE 0x30" >>up_mem.h ; \ + echo "#define UP_HEAP1_BASE 0x0100" >> up_mem.h ; \ + echo "#define UP_HEAP1_END 0x2000" >> up_mem.h ; \ + echo "#define UP_HEAP2_BASE 0x6000" >> up_mem.h ; \ + echo "#define UP_HEAP2_END 0x8000" >> up_mem.h ; \ + fi + @echo "#endif /* __ARCH_MEM_H */" >>up_mem.h # Combine all objects in this directory into a library -libarch$(LIBEXT): $(OBJS) - ( for obj in $(OBJS) ; do \ +libarch$(LIBEXT): up_mem.h $(OBJS) + @( for obj in $(OBJS) ; do \ $(AR) $@ $${obj} || \ { echo "$(AR) $@ $${obj} FAILED!" ; exit 1 ; } ; \ done ; ) -# This is a kludge to work around some conflicting symbols in libsdcc.lib +# This is a kludge to work around some conflicting symbols in libsdcc.liXqueb $(SDCCLIBDIR)/libmysdcc.lib: $(SDCCLIBDIR)/libsdcc.lib @cat $(SDCCLIBDIR)/libsdcc.lib | \ @@ -106,27 +130,31 @@ $(SDCCLIBDIR)/libmysdcc.lib: $(SDCCLIBDIR)/libsdcc.lib # This target builds the final executable -pass1$(EXEEXT): $(SDCCLIBDIR)/libmysdcc.lib $(LINKOBJS) - $(CC) $(LDFLAGS) $(LDPATHES) $(SDCCPATH) $(LINKOBJS) $(LDLIBS) $(SDCCLIBS) -o pass1.ihx +pass1.ihx: up_mem.h $(SDCCLIBDIR)/libmysdcc.lib $(LINKOBJS) + $(CC) $(LDFLAGS) $(LDPATHES) $(SDCCPATH) $(LINKOBJS) $(LDLIBS) $(SDCCLIBS) -o $@ + @rm -f up_mem.h + @rm -f up_allocateheap$(OBJEXT) libarch$(LIBEXT) + @$(MAKE) TOPDIR=$(TOPDIR) libarch$(LIBEXT) + +nuttx.ihx: up_mem.h $(SDCCLIBDIR)/libmysdcc.lib $(LINKOBJS) + $(CC) $(LDFLAGS) $(LDPATHES) $(SDCCPATH) $(LINKOBJS) $(LDLIBS) $(SDCCLIBS) -o $@ -nuttx$(EXEEXT): pass1$(EXEEXT) - $(CC) -c $(CFLAGS) -DUP_HEAP_START=$(HEAP_START) -DUP_HEAP_END=0x2000 \ - up_allocateheap.c -o up_allocateheap$(OBJEXT) +nuttx$(EXEEXT): pass1.ihx nuttx.ihx @rm -f pass1.* - $(CC) $(LDFLAGS) $(LDPATHES) $(SDCCPATH) $(LINKOBJS) $(LDLIBS) $(SDCCLIBS) -o nuttx.ihx packihx nuttx.ihx > $(TOPDIR)/nuttx$(EXEEXT) @cp -f nuttx.map $(TOPDIR)/. # Build dependencies -.depend: Makefile $(DEPSRCS) +.depend: Makefile up_mem.h $(DEPSRCS) $(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep touch $@ depend: .depend clean: - rm -f libarch$(LIBEXT) *.asm *.rel *.lst *.rst *.sym *.adb *.lnk *.map *.mem *.ihx *.hex *~ + rm -f libarch$(LIBEXT) up_mem.h + rm -f *.asm *.rel *.lst *.rst *.sym *.adb *.lnk *.map *.mem *.ihx *.hex *~ if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi distclean: clean diff --git a/nuttx/arch/pjrc-8051/src/up_allocateheap.c b/nuttx/arch/pjrc-8051/src/up_allocateheap.c index 6a874ed2a..6f164f0d3 100644 --- a/nuttx/arch/pjrc-8051/src/up_allocateheap.c +++ b/nuttx/arch/pjrc-8051/src/up_allocateheap.c @@ -44,6 +44,7 @@ #include #include "os_internal.h" #include "up_internal.h" +#include "up_mem.h" /************************************************************ * Private Definitions @@ -74,6 +75,6 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) { - *heap_start = (FAR void*)UP_HEAP_START; - *heap_size = UP_HEAP_END - UP_HEAP_START; + *heap_start = (FAR void*)UP_HEAP1_BASE; + *heap_size = UP_HEAP1_END - UP_HEAP1_BASE; } diff --git a/nuttx/arch/pjrc-8051/src/up_internal.h b/nuttx/arch/pjrc-8051/src/up_internal.h index f471c1b83..54320a288 100644 --- a/nuttx/arch/pjrc-8051/src/up_internal.h +++ b/nuttx/arch/pjrc-8051/src/up_internal.h @@ -96,6 +96,59 @@ #define PM2_VECTOR_UART (PM2_VECTOR_BASE + 35) #define PM2_VECTOR_TIMER2 (PM2_VECTOR_BASE + 43) +/* Registers. 8052 regiser definitions are provided in the SDCC header + * file 8052.h. However, a few SFR registers are missing from that + * file (they can be found in mcs51reg.h, but that file is too much + * when the following simple addtions do the job). + */ + +sfr at 0xc9 T2MOD ; + +/* Timing information. + * + * The PJRC board is based on a standard 87C52 CPU clocked at 22.1184 MHz. + * The CPU clock is divided by 12 to yield a clock frequency of 1.8432 MHz. + */ + +#define CPU_CLOCK_HZ 22118400L +#define TIMER_CLOCK_HZ 1843200L + +/* The 87C52 has three timers, timer 0, timer 1, and timer 2. On the PJRC + * board, timer 1 and 2 have dedicated functions. They provide baud support + * support for the boards two serial ports. Unfortunately, only timer 2 + * can generate the accurate 100Hz timer desired by the OS. + * + * Timer 0 provides only a 8-bit auto-reload mode. + */ + +#define CONFIG_80C52_TIMER2 1 +#ifdef CONFIG_80C52_TIMER2 + +/* To use timer 2 as the 100Hz system timer, we need to calculate a 16-bit + * reload value that results in 100Hz overflow interrupts. That value + * is given by: + * + * Timer ticks = TIMER_CLOCK_HZ / (desired ticks-per-second) + * = 18432 + * Capture value = 0xffff - (Timer ticks) + * = 47103 = 0x67ff + */ + +# define TIMER2_CAPTURE_LOW 0xff +# define TIMER2_CAPTURE_HIGH 0x67 + +#else + +/* Timer 0, mode 0 can be used as a system timer. In that mode, the + * 1.8432 is further divided by 32. A single 8-bit value is incremented + * at 57600 Hz, which results in 225 Timer 0 overflow interrupts per + * second. + */ + +# warning "No support for timer 0 as the system timer" + +#endif + /************************************************************************** * Public Types **************************************************************************/ diff --git a/nuttx/arch/pjrc-8051/src/up_irq.c b/nuttx/arch/pjrc-8051/src/up_irq.c index d3a5ffdd2..c524fe3e7 100644 --- a/nuttx/arch/pjrc-8051/src/up_irq.c +++ b/nuttx/arch/pjrc-8051/src/up_irq.c @@ -154,4 +154,4 @@ void up_enable_irq(int irq) { _up_enable_irq(~(1 << irq)); } -} \ No newline at end of file +} diff --git a/nuttx/arch/pjrc-8051/src/up_timerisr.c b/nuttx/arch/pjrc-8051/src/up_timerisr.c index a270da15c..5580b5bb5 100644 --- a/nuttx/arch/pjrc-8051/src/up_timerisr.c +++ b/nuttx/arch/pjrc-8051/src/up_timerisr.c @@ -41,6 +41,7 @@ #include #include #include +#include <8052.h> #include "clock_internal.h" #include "up_internal.h" @@ -61,7 +62,7 @@ ************************************************************/ /************************************************************ - * Function: timer_isr + * Function: up_timerisr * * Description: * The timer ISR will perform a variety of services for @@ -77,15 +78,45 @@ int up_timerisr(int irq, FAR ubyte *frame) return 0; } +/************************************************************ + * Function: up_timerinit + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ************************************************************/ + void up_timerinit(void) { +#ifdef CONFIG_80C52_TIMER2 up_disable_irq(TIMER2_IRQ); -#warning "Missing TIMER2 setup logic here" + /* Set up timer 2 -- See up_internal.h for details */ + + T2MOD = 0; + + /* Set up the capture count to generate 100Hz system + * interrupts. + */ + + RCAP2L = TIMER2_CAPTURE_LOW; + RCAP2H = TIMER2_CAPTURE_HIGH; + + TL2 = TIMER2_CAPTURE_LOW; + TH2 = TIMER2_CAPTURE_HIGH; + + /* Configure for interrupts */ + + T2CON = 0x40; /* Attach and enable the timer interrupt */ irq_attach(TIMER2_IRQ, (xcpt_t)up_timerisr); up_enable_irq(TIMER2_IRQ); + +#else +# warning "No support for timer 0 as the system timer" +#endif } -- cgit v1.2.3