forked from Imagelibrary/rtems
committed by
Sebastian Huber
parent
7cd2484c4c
commit
75acd9e69f
@@ -22,8 +22,6 @@
|
||||
#include <at91rm9200.h>
|
||||
#include <at91rm9200_pmc.h>
|
||||
|
||||
static unsigned long st_pimr_reload;
|
||||
|
||||
/**
|
||||
* Enables clock interrupt.
|
||||
*
|
||||
@@ -77,17 +75,16 @@ rtems_irq_connect_data clock_isr_data = {
|
||||
BSP_install_rtems_irq_handler(&clock_isr_data); \
|
||||
} while(0)
|
||||
|
||||
uint16_t st_pimr_value;
|
||||
static void Clock_driver_support_initialize_hardware(void)
|
||||
{
|
||||
uint32_t st_str;
|
||||
int slck;
|
||||
unsigned long value;
|
||||
|
||||
/* the system timer is driven from SLCK */
|
||||
slck = at91rm9200_get_slck();
|
||||
st_pimr_value = (((rtems_configuration_get_microseconds_per_tick() * slck) +
|
||||
value = (((rtems_configuration_get_microseconds_per_tick() * slck) +
|
||||
(1000000/2))/ 1000000);
|
||||
st_pimr_reload = st_pimr_value;
|
||||
|
||||
/* read the status to clear the int */
|
||||
st_str = ST_REG(ST_SR);
|
||||
@@ -97,21 +94,9 @@ static void Clock_driver_support_initialize_hardware(void)
|
||||
AIC_SMR_REG(AIC_SMR_SYSIRQ) = AIC_SMR_PRIOR(0x7);
|
||||
|
||||
/* set the timer value */
|
||||
ST_REG(ST_PIMR) = st_pimr_reload;
|
||||
ST_REG(ST_PIMR) = value;
|
||||
}
|
||||
|
||||
static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
||||
{
|
||||
uint16_t slck_counts;
|
||||
|
||||
slck_counts = st_pimr_value - st_pimr_reload;
|
||||
return (rtems_configuration_get_microseconds_per_tick() * slck_counts * 1000)
|
||||
/ st_pimr_value;
|
||||
}
|
||||
|
||||
#define Clock_driver_nanoseconds_since_last_tick \
|
||||
bsp_clock_nanoseconds_since_last_tick
|
||||
|
||||
#define Clock_driver_support_at_tick() \
|
||||
do { \
|
||||
uint32_t st_str; \
|
||||
@@ -126,4 +111,6 @@ static void Clock_driver_support_shutdown_hardware( void )
|
||||
BSP_remove_rtems_irq_handler(&clock_isr_data);
|
||||
}
|
||||
|
||||
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
|
||||
|
||||
#include "../../../../libbsp/shared/clockdrv_shell.h"
|
||||
|
||||
@@ -17,12 +17,39 @@
|
||||
#include <bsp/irq.h>
|
||||
#include <lpc22xx.h>
|
||||
#include <rtems/bspIo.h> /* for printk */
|
||||
#include <rtems/timecounter.h>
|
||||
|
||||
void Clock_isr(rtems_irq_hdl_param arg);
|
||||
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);
|
||||
|
||||
static rtems_timecounter_simple lpc22xx_tc;
|
||||
|
||||
static uint32_t lpc22xx_tc_get(rtems_timecounter_simple *tc)
|
||||
{
|
||||
return T0TC;
|
||||
}
|
||||
|
||||
static bool lpc22xx_tc_is_pending(rtems_timecounter_simple *tc)
|
||||
{
|
||||
return (T0IR & 0x1) != 0;
|
||||
}
|
||||
|
||||
static uint32_t lpc22xx_tc_get_timecount(struct timecounter *tc)
|
||||
{
|
||||
return rtems_timecounter_simple_upcounter_get(
|
||||
tc,
|
||||
lpc22xx_tc_get,
|
||||
lpc22xx_tc_is_pending
|
||||
);
|
||||
}
|
||||
|
||||
static void lpc22xx_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_upcounter_tick(&lpc22xx_tc, lpc22xx_tc_get);
|
||||
}
|
||||
|
||||
/* Replace the first value with the clock's interrupt name. */
|
||||
rtems_irq_connect_data clock_isr_data = {
|
||||
.name = LPC22xx_INTERRUPT_TIMER0,
|
||||
@@ -74,9 +101,10 @@ rtems_irq_connect_data clock_isr_data = {
|
||||
*/
|
||||
#define Clock_driver_support_initialize_hardware() \
|
||||
do { \
|
||||
uint32_t mask; \
|
||||
/* disable and clear timer 0, set to */ \
|
||||
T0TCR &= 0; \
|
||||
/* TC is incrementet on every pclk.*/ \
|
||||
/* TC is incremented on every pclk.*/ \
|
||||
T0PC = 0; \
|
||||
/* initialize the timer period and prescaler */ \
|
||||
T0MR0 = ((LPC22xx_Fpclk/1000 * \
|
||||
@@ -89,6 +117,13 @@ rtems_irq_connect_data clock_isr_data = {
|
||||
T0TCR = 1; \
|
||||
/* enable interrupt, skyeye will check this*/ \
|
||||
T0IR |= 0x01; \
|
||||
/* install timecounter */ \
|
||||
rtems_timecounter_simple_install( \
|
||||
&lpc22xx_tc, \
|
||||
LPC22xx_Fpclk, \
|
||||
T0MR0, \
|
||||
lpc22xx_tc_get_timecount \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
@@ -104,20 +139,6 @@ rtems_irq_connect_data clock_isr_data = {
|
||||
BSP_remove_rtems_irq_handler(&clock_isr_data); \
|
||||
} while (0)
|
||||
|
||||
static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
||||
{
|
||||
uint32_t clicks;
|
||||
uint32_t microseconds;
|
||||
|
||||
clicks = T0TC; /* T0TC is the 32bit time counter 0 */
|
||||
|
||||
microseconds = (rtems_configuration_get_microseconds_per_tick() - clicks);
|
||||
return microseconds * 1000;
|
||||
}
|
||||
|
||||
#define Clock_driver_nanoseconds_since_last_tick \
|
||||
bsp_clock_nanoseconds_since_last_tick
|
||||
|
||||
/**
|
||||
* Enables clock interrupt.
|
||||
*
|
||||
@@ -149,6 +170,8 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq)
|
||||
return T0IR & 0x01; /* MR0 mask */
|
||||
}
|
||||
|
||||
#define Clock_driver_timecounter_tick() lpc22xx_tc_tick()
|
||||
|
||||
/* Make sure to include this, and only at the end of the file */
|
||||
#include "../../../../libbsp/shared/clockdrv_shell.h"
|
||||
|
||||
|
||||
@@ -130,5 +130,8 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq)
|
||||
return MC9328MXL_TMR1_TCTL & MC9328MXL_TMR_TCTL_IRQEN;
|
||||
}
|
||||
|
||||
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
|
||||
|
||||
/* Make sure to include this, and only at the end of the file */
|
||||
|
||||
#include "../../../../libbsp/shared/clockdrv_shell.h"
|
||||
|
||||
@@ -116,4 +116,6 @@ static void Clock_driver_support_shutdown_hardware( void )
|
||||
BSP_remove_rtems_irq_handler(&clock_isr_data);
|
||||
}
|
||||
|
||||
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
|
||||
|
||||
#include "../../../../libbsp/shared/clockdrv_shell.h"
|
||||
|
||||
@@ -27,17 +27,6 @@ rtems_irq_connect_data clock_isr_data = {
|
||||
.isOn = clock_isr_is_on,
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the nanoseconds since last tick
|
||||
*/
|
||||
static uint32_t clock_driver_get_nanoseconds_since_last_tick(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define Clock_driver_nanoseconds_since_last_tick \
|
||||
clock_driver_get_nanoseconds_since_last_tick
|
||||
|
||||
/**
|
||||
* When we get the clock interrupt
|
||||
* - clear the interrupt bit?
|
||||
@@ -74,6 +63,7 @@ static uint32_t clock_driver_get_nanoseconds_since_last_tick(void)
|
||||
do { \
|
||||
uint32_t cr; \
|
||||
uint32_t freq; \
|
||||
uint32_t mask; \
|
||||
/* set MUX for Timer4 to 1/16 */ \
|
||||
cr=rTCFG1 & 0xFFF0FFFF; \
|
||||
rTCFG1=(cr | (3<<16)); \
|
||||
@@ -131,5 +121,7 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
|
||||
|
||||
/* Make sure to include this, and only at the end of the file */
|
||||
#include "../../../../libbsp/shared/clockdrv_shell.h"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <libcpu/spr.h>
|
||||
#include <rtems/bspIo.h> /* for printk() */
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
#include <rtems/timecounter.h>
|
||||
|
||||
#include <bspopts.h> /* for CLOCK_DRIVER_USE_FAST_IDLE */
|
||||
|
||||
@@ -48,11 +49,12 @@ volatile uint32_t Clock_driver_ticks;
|
||||
*/
|
||||
static uint32_t Clock_Decrementer_value;
|
||||
|
||||
/*
|
||||
* This is the value by which elapsed count down timer ticks are multiplied to
|
||||
* give an elapsed duration in nanoseconds, left-shifted by 32 bits
|
||||
*/
|
||||
static uint64_t Clock_Decrementer_reference;
|
||||
static struct timecounter Clock_TC;
|
||||
|
||||
static uint32_t Clock_Get_timecount(struct timecounter *tc)
|
||||
{
|
||||
return ppc_time_base();
|
||||
}
|
||||
|
||||
void clockOff(void* unused)
|
||||
{
|
||||
@@ -94,16 +96,27 @@ void clockOn(void* unused)
|
||||
static void clockHandler(void)
|
||||
{
|
||||
#if (CLOCK_DRIVER_USE_FAST_IDLE == 1)
|
||||
do {
|
||||
rtems_clock_tick();
|
||||
} while (
|
||||
rtems_interrupt_level level;
|
||||
uint32_t tb;
|
||||
|
||||
rtems_interrupt_disable(level);
|
||||
|
||||
tb = ppc_time_base();
|
||||
rtems_timecounter_tick();
|
||||
|
||||
while (
|
||||
_Thread_Heir == _Thread_Executing
|
||||
&& _Thread_Executing->Start.entry_point
|
||||
== (Thread_Entry) rtems_configuration_get_idle_task()
|
||||
);
|
||||
) {
|
||||
tb += Clock_Decrementer_value;
|
||||
ppc_set_time_base( tb );
|
||||
rtems_timecounter_tick();
|
||||
}
|
||||
|
||||
rtems_interrupt_enable(level);
|
||||
#else
|
||||
rtems_clock_tick();
|
||||
rtems_timecounter_tick();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -141,7 +154,6 @@ void clockIsr(void *unused)
|
||||
rtems_interrupt_enable(flags);
|
||||
|
||||
Clock_driver_ticks += 1;
|
||||
|
||||
/*
|
||||
* Real Time Clock counter/timer is set to automatically reload.
|
||||
*/
|
||||
@@ -187,7 +199,6 @@ int clockIsOn(void* unused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clock_exit
|
||||
*
|
||||
@@ -199,53 +210,6 @@ void Clock_exit( void )
|
||||
(void) BSP_disconnect_clock_handler ();
|
||||
}
|
||||
|
||||
static uint32_t Clock_driver_nanoseconds_since_last_tick(void)
|
||||
{
|
||||
uint32_t clicks, tmp;
|
||||
|
||||
PPC_Get_decrementer( clicks );
|
||||
|
||||
/*
|
||||
* Multiply by 1000 here separately from below so we do not overflow
|
||||
* and get a negative value.
|
||||
*/
|
||||
tmp = (Clock_Decrementer_value - clicks) * 1000;
|
||||
tmp /= (BSP_bus_frequency/BSP_time_base_divisor);
|
||||
|
||||
return tmp * 1000;
|
||||
}
|
||||
|
||||
static uint32_t Clock_driver_nanoseconds_since_last_tick_bookE(void)
|
||||
{
|
||||
uint32_t clicks;
|
||||
uint64_t c;
|
||||
|
||||
PPC_Get_decrementer( clicks );
|
||||
c = Clock_Decrementer_value - clicks;
|
||||
|
||||
/*
|
||||
* Check whether a clock tick interrupt is pending and hence that the
|
||||
* decrementer's wrapped. If it has, we'll compensate by returning a time one
|
||||
* tick period longer.
|
||||
*
|
||||
* We have to check interrupt status after reading the decrementer. If we
|
||||
* don't, we may miss an interrupt and read a wrapped decrementer value
|
||||
* without compensating for it
|
||||
*/
|
||||
if ( _read_BOOKE_TSR() & BOOKE_TSR_DIS )
|
||||
{
|
||||
/*
|
||||
* Re-read the decrementer: The tick interrupt may have been
|
||||
* generated and the decrementer wrapped during the time since we
|
||||
* last read it and the time we checked the interrupt status
|
||||
*/
|
||||
PPC_Get_decrementer( clicks );
|
||||
c = (Clock_Decrementer_value - clicks) + Clock_Decrementer_value;
|
||||
}
|
||||
|
||||
return (uint32_t)((c * Clock_Decrementer_reference) >> 32);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clock_initialize
|
||||
*
|
||||
@@ -262,9 +226,6 @@ rtems_device_driver Clock_initialize(
|
||||
Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)*
|
||||
rtems_configuration_get_milliseconds_per_tick();
|
||||
|
||||
Clock_Decrementer_reference = ((uint64_t)1000000U<<32)/
|
||||
(BSP_bus_frequency/BSP_time_base_divisor);
|
||||
|
||||
/* set the decrementer now, prior to installing the handler
|
||||
* so no interrupts will happen in a while.
|
||||
*/
|
||||
@@ -283,23 +244,13 @@ rtems_device_driver Clock_initialize(
|
||||
_write_BOOKE_TCR(tcr);
|
||||
|
||||
rtems_interrupt_enable(l);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the nanoseconds since last tick handler
|
||||
*/
|
||||
rtems_clock_set_nanoseconds_extension(
|
||||
Clock_driver_nanoseconds_since_last_tick_bookE
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Set the nanoseconds since last tick handler
|
||||
*/
|
||||
rtems_clock_set_nanoseconds_extension(
|
||||
Clock_driver_nanoseconds_since_last_tick
|
||||
);
|
||||
}
|
||||
Clock_TC.tc_get_timecount = Clock_Get_timecount;
|
||||
Clock_TC.tc_counter_mask = 0xffffffff;
|
||||
Clock_TC.tc_frequency = (1000 * BSP_bus_frequency) / BSP_time_base_divisor;
|
||||
Clock_TC.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
|
||||
rtems_timecounter_install(&Clock_TC);
|
||||
|
||||
/*
|
||||
* If a decrementer exception was pending, it is cleared by
|
||||
|
||||
Reference in New Issue
Block a user