2007-04-25 Ray Xu <xr@trasin.net>

* Makefile.am, configure.ac: Add lpc22xx support.
	* lpc22xx/clock/clockdrv.c, lpc22xx/include/lpc22xx.h,
	lpc22xx/irq/bsp_irq_asm.S, lpc22xx/timer/lpc_timer.h,
	lpc22xx/timer/timer.c: New (Initial submission).
This commit is contained in:
Ralf Corsepius committed 2007-04-25 11:48:32 +00:00
1 parent 0ab34c90a2
commit 7d33199a93
8 files changed
+867

No files matched your search

+7
View File
@@ -1,3 +1,10 @@
2007-04-25 Ray Xu <xr@trasin.net>
* Makefile.am, configure.ac: Add lpc22xx support.
* lpc22xx/clock/clockdrv.c, lpc22xx/include/lpc22xx.h,
lpc22xx/irq/bsp_irq_asm.S, lpc22xx/timer/lpc_timer.h,
lpc22xx/timer/timer.c: New (Initial submission).
2007-03-12 Joel Sherrill <joel@OARcorp.com>
* at91rm9200/clock/clock.c, at91rm9200/dbgu/dbgu.c,
+26
View File
@@ -115,5 +115,31 @@ s3c2400_irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
s3c2400_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
if lpc22xx
include_HEADERS = lpc22xx/include/lpc22xx.h
## lpc22xx/clock
noinst_PROGRAMS += lpc22xx/clock.rel
lpc22xx_clock_rel_SOURCES = lpc22xx/clock/clockdrv.c
lpc22xx_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
lpc22xx_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## lpc22xx/timer
noinst_PROGRAMS += lpc22xx/timer.rel
lpc22xx_timer_rel_SOURCES = lpc22xx/timer/timer.c
lpc22xx_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
lpc22xx_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## lpc22xx/interrupt
include_HEADERS += lpc22xx/irq/irq.h
noinst_PROGRAMS += lpc22xx/irq.rel
lpc22xx_irq_rel_SOURCES = lpc22xx/irq/irq.c lpc22xx/irq/bsp_irq_init.c \
../../libbsp/arm/shared/irq/irq_init.c lpc22xx/irq/bsp_irq_asm.S \
../../libbsp/arm/shared/irq/irq_asm.S lpc22xx/irq/irq.h
lpc22xx_irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
lpc22xx_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
include $(srcdir)/preinstall.am
include $(top_srcdir)/../../../automake/local.am
+1
View File
@@ -27,6 +27,7 @@ AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "at91rm9200" || \
AM_CONDITIONAL(at91rm9200, test "$RTEMS_CPU_MODEL" = "at91rm9200")
AM_CONDITIONAL(mc9328mxl, test "$RTEMS_CPU_MODEL" = "mc9328mxl")
AM_CONDITIONAL(s3c2400, test "$RTEMS_CPU_MODEL" = "s3c2400")
AM_CONDITIONAL(lpc22xx, test "$RTEMS_CPU_MODEL" = "lpc22xx")
RTEMS_AMPOLISH3
@@ -0,0 +1,143 @@
/*
* LPC22XX clock specific using the System Timer
* set the Time0
* This is hardware specific part of the clock driver. At the end of this
* file, the generic part of the driver is #included.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.OARcorp.com/rtems/license.html.
*
*
* clockdrv.c,v 1.1 2002/11/13 17:55:04 joel Exp
*/
#include <rtems.h>
#include <bsp.h>
#include <irq.h>
#include <lpc22xx.h>
#include <rtems/bspIo.h> /* for printk */
/* this is defined in ../../../shared/clockdrv_shell.c */
rtems_isr Clock_isr(rtems_vector_number vector);
static void clock_isr_on(const rtems_irq_connect_data *unused);
static void clock_isr_off(const rtems_irq_connect_data *unused);
static int clock_isr_is_on(const rtems_irq_connect_data *irq);
/* Replace the first value with the clock's interrupt name. */
rtems_irq_connect_data clock_isr_data = {LPC22xx_INTERRUPT_TIMER0,
(rtems_irq_hdl)Clock_isr,
clock_isr_on,
clock_isr_off,
clock_isr_is_on,
3, /* unused for ARM cpus */
0 }; /* unused for ARM cpus */
/* If you follow the code, this is never used, so any value
* should work
*/
#define CLOCK_VECTOR 0
/*use the /shared/clockdrv_shell.c code template */
/**
* When we get the clock interrupt
* - clear the interrupt bit?
* - restart the timer?
*/
#define Clock_driver_support_at_tick() \
do { \
if (!(T0IR & 0x01)) return; \
T0IR = 0x01; \
VICVectAddr = 0x00;\
} while(0)
/**
* Installs the clock ISR. You shouldn't need to change this.
*/
#define Clock_driver_support_install_isr( _new, _old ) \
do { \
(_old) = NULL; \
BSP_install_rtems_irq_handler(&clock_isr_data); \
} while(0)
/**
* Initialize the hardware for the clock
* - Set the frequency
* - enable it
* - clear any pending interrupts
*
* Since you may want the clock always running, you can
* enable interrupts here. If you do so, the clock_isr_on(),
* clock_isr_off(), and clock_isr_is_on() functions can be
* NOPs.
*/
/* set timer to generate interrupt every BSP_Configuration.microseconds_per_tick */
/* MR0/(LPC22xx_Fpclk/(PR0+1)) = 10/1000 = 0.01s */
#define Clock_driver_support_initialize_hardware() \
do { \
T0TCR &= 0; /* disable and clear timer 0, set to */ \
T0PC = 0; /* TC is incrementet on every pclk.*/ \
T0MR0 = ((LPC22xx_Fpclk/1000* BSP_Configuration.microseconds_per_tick) / 1000); /* initialize the timer period and prescaler */ \
/*T0PR = (((LPC22xx_Fpclk / 1000) * BSP_Configuration.microseconds_per_tick) / 1000-1); \ */ \
T0MCR |= 0x03; /* generate interrupt when T0MR0 match T0TC and Reset Timer Count*/ \
T0EMR = 0; /*No external match*/ \
T0TCR = 1; /*enable timer0*/ \
} while (0)
/**
* Do whatever you need to shut the clock down and remove the
* interrupt handler. Since this normally only gets called on
* RTEMS shutdown, you may not need to do anything other than
* remove the ISR.
*/
#define Clock_driver_support_shutdown_hardware() \
do { \
/* Disable timer */ \
T0TCR&=~0x02; \
BSP_remove_rtems_irq_handler(&clock_isr_data); \
} while (0)
/**
* Enables clock interrupt.
*
* If the interrupt is always on, this can be a NOP.
*/
static void clock_isr_on(const rtems_irq_connect_data *unused)
{
T0IR&=0x01;
//return;
}
/**
* Disables clock interrupts
*
* If the interrupt is always on, this can be a NOP.
*/
static void clock_isr_off(const rtems_irq_connect_data *unused)
{
T0IR=0x00;
//return;
}
/**
* Tests to see if clock interrupt is enabled, and returns 1 if so.
* If interrupt is not enabled, returns 0.
*
* If the interrupt is always on, this always returns 1.
*/
static int clock_isr_is_on(const rtems_irq_connect_data *irq)
{
return T0IR & 0x01; /*MR0 mask*/
}
/* Make sure to include this, and only at the end of the file */
#include "../../../../libbsp/shared/clockdrv_shell.c"
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,48 @@
/*
* LPC22XX Intererrupt handler
*
* Copyright (c) 2002 by Jay Monkman <jtm@lopingdog.com>
*
* Modified by ray
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.OARcorp.com/rtems/license.html.
*
*
* bsp_irq_asm.S,v 1.1 2002/11/13 17:55:06 joel Exp
*/
#define __asm__
/*
* BSP specific interrupt handler for INT or FIQ. In here
* you do determine which interrupt happened and call its
* handler.
*/
.globl ExecuteITHandler
ExecuteITHandler :
/*
* Look at interrupt status register to determine source.
* From source, determine offset into expanded vector table
* and load handler address into r0.
*/
ldr r0, =0xFFFFF030 /* Read the vector number */
ldr r1, [r0]
/* find the ISR's address based on the vector VICVectAddr0 */
/*ldr r0, =0xFFFFF100*/
/*ldr r0, [r0, r1, LSL #2]*/ /* Read the address */
stmdb sp!,{lr}
ldr lr, =IRQ_return /* prepare the return from handler */
mov pc, r1 /* EXECUTE INT HANDLER */
IRQ_return:
ldmia sp!,{lr}
mov pc, lr
@@ -0,0 +1,48 @@
#ifndef __LPC_TIMER_H
#define __LPC_TIMER_H
/*************************************************************************
*
* File name : Timer.h
*
**************************************************************************/
/* Timer Control register bit descriptions */
#define TCR_ENABLE_BIT 0
#define TCR_RESET_BIT 1
// The channel name which is used in matching, in fact they represent
// corresponding Match Register
#define CH_MAXNUM 4
#define CH0 0
#define CH1 1
#define CH2 2
#define CH3 3
// The channel name which is used in capturing, in fact they represent
// corresponding Capture Register
#define CPCH_MAXNUM 4
#define CPCH0 0
#define CPCH1 1
#define CPCH2 2
#define CPCH3 3
//The actions when matching
#define TimerAction_Interrupt 0x1
#define TimerAction_ResetTimer 0x2
#define TimerAction_StopTimer 0x4
//Interrupt source type
#define TIMERMR0Int 0x01
#define TIMERMR1Int 0x02
#define TIMERMR2Int 0x04
#define TIMERMR3Int 0x08
#define TIMERCR0Int 0x10
#define TIMERCR1Int 0x20
#define TIMERCR2Int 0x40
#define TIMERCR3Int 0x80
#define TIMERALLInt 0xFF
#endif //__LPC_Timer_H
+115
View File
@@ -0,0 +1,115 @@
/*
* RTL22xx board Timer driver
*
* This uses Timer1 for timing measurments.
*
* By Ray xu, modify form Mc9328mxl RTEMS DSP
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.OARcorp.com/rtems/license.html.
*
* Notes:
* This file manages the benchmark timer used by the RTEMS Timing Test
* Suite. Each measured time period is demarcated by calls to
* Timer_initialize() and Read_timer(). Read_timer() usually returns
* the number of microseconds since Timer_initialize() exitted.
*
* It is important that the timer start/stop overhead be determined
* when porting or modifying this code.
*
* timer.c,v 1.1 2002/11/13 17:55:09 joel Exp
*/
#include <rtems.h>
#include <bsp.h>
#include <lpc22xx.h>
#include "lpc_timer.h"
uint32_t g_start;
uint32_t g_freq;
#ifndef __cplusplus
#define bool int
#define true 1
#define false 0
#endif/* __cplusplus */
rtems_boolean Timer_driver_Find_average_overhead;
/*
* Set up Timer 1
*/
void Timer_initialize( void )
{
T1TCR &= 0; /* disable and clear timer 0 */
g_start = (T1TC/(LPC22xx_Fpclk/1000000));
T1PC = 0; /* TC is incrementet on every pclk.*/
T1MR0 = ((LPC22xx_Fpclk/1000* BSP_Configuration.microseconds_per_tick) / 1000); /* initialize the timer period and prescaler */
T1EMR = 0; /*No external match*/
T1TCR = 1; /*enable timer1*/
g_freq = LPC22xx_Fpclk / 1000;
}
/*
* The following controls the behavior of Read_timer().
*
* AVG_OVEREHAD is the overhead for starting and stopping the timer. It
* is usually deducted from the number returned.
*
* LEAST_VALID is the lowest number this routine should trust. Numbers
* below this are "noise" and zero is returned.
*/
#define AVG_OVERHEAD 0 /* It typically takes X.X microseconds */
/* (Y countdowns) to start/stop the timer. */
/* This value is in microseconds. */
#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */
int Read_timer( void )
{
uint32_t t;
unsigned long long total;
t = (T1TC/(LPC22xx_Fpclk/1000000));
/*
* Total is calculated by taking into account the number of timer overflow
* interrupts since the timer was initialized and clicks since the last
* interrupts. currently it is not supported
*/
total = (t - g_start);
/* convert to nanoseconds */
if ( Timer_driver_Find_average_overhead == 1 ) {
return (int) total;
} else if ( total < LEAST_VALID ) {
return 0;
}
/*
* Somehow convert total into microseconds
*/
return (total - AVG_OVERHEAD);
}
/*
* Empty function call used in loops to measure basic cost of looping
* in Timing Test Suite.
*/
rtems_status_code Empty_function( void )
{
return RTEMS_SUCCESSFUL;
}
void Set_find_average_overhead(
rtems_boolean find_flag
)
{
Timer_driver_Find_average_overhead = find_flag;
}