@ -58,45 +58,50 @@
# define MR3S (1<<11)
# define MR3S (1<<11)
volatile unsigned int timer1 _rising [ 4 ] ;
volatile unsigned int timer0 _rising [ 4 ] ;
volatile unsigned int timer1 _width [ 4 ] ;
volatile unsigned int timer0 _width [ 4 ] ;
# ifdef TIMER_CPPM
# ifdef TIMER_CPPM
volatile unsigned int timer1 _cppm [ 8 ] ;
volatile unsigned int timer0 _cppm [ 8 ] ;
volatile unsigned int timer1 _cppm_chan = 0 ;
volatile unsigned int timer0 _cppm_chan = 0 ;
volatile unsigned int timer1 _sync_timestamp ;
volatile unsigned int timer0 _sync_timestamp ;
# endif
# endif
unsigned int timer_map [ ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 } ;
unsigned int timer_map [ ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 } ;
void __attribute__ ( ( interrupt ( " IRQ " ) ) ) timer_interrupt_handler ( void ) ;
void __attribute__ ( ( interrupt ( " IRQ " ) ) ) timer_interrupt_handler ( void ) ;
void __attribute__ ( ( interrupt ( " IRQ " ) ) ) timer1 _interrupt_handler ( void ) ;
void __attribute__ ( ( interrupt ( " IRQ " ) ) ) timer0 _interrupt_handler ( void ) ;
void timer_event_handler ( void ) ;
void timer_event_handler ( void ) ;
/* Timer 0 : Capture */
/* Timer 1 : Output */
/* Timer 2 : Output */
/* Timer 3 : System */
void init_timer ( void )
void init_timer ( void )
{
{
TREG ( TCR ) = TCR_ENABLE | TCR_RESET ;
T3 REG ( TCR ) = TCR_ENABLE | TCR_RESET ;
TREG ( CTCR ) = 0 ; /* Use PCLK */
T3 REG ( CTCR ) = 0 ; /* Use PCLK */
TWREG ( TC ) = 0 ;
T3 WREG ( TC ) = 0 ;
TWREG ( PR ) = TIMER_PRESCALE ;
T3 WREG ( PR ) = TIMER_PRESCALE ;
TWREG ( PC ) = 0 ;
T3 WREG ( PC ) = 0 ;
TREG ( TCR ) = TCR_ENABLE ;
T3 REG ( TCR ) = TCR_ENABLE ;
interrupt_register ( TIMER1 , timer1 _interrupt_handler ) ;
interrupt_register ( TIMER0 , timer0 _interrupt_handler ) ;
T1 REG ( TCR ) = TCR_ENABLE | TCR_RESET ;
TREG ( TCR ) = TCR_ENABLE | TCR_RESET ;
T1 REG ( CTCR ) = 0 ; /* Use PCLK */
TREG ( CTCR ) = 0 ; /* Use PCLK */
T1 WREG ( TC ) = 0 ;
TWREG ( TC ) = 0 ;
T1 WREG ( PR ) = TIMER_PRESCALE ;
TWREG ( PR ) = TIMER0 _PRESCALE ;
T1 WREG ( PC ) = 0 ;
TWREG ( PC ) = 0 ;
T1 WREG ( CCR ) = 0x00000fff ;
TWREG ( CCR ) = 0x00000fff ;
T1 REG ( TCR ) = TCR_ENABLE ;
TREG ( TCR ) = TCR_ENABLE ;
T2REG ( TCR ) = TCR_ENABLE | TCR_RESET ;
T2REG ( TCR ) = TCR_ENABLE | TCR_RESET ;
T2REG ( CTCR ) = 0 ; /* Use PCLK */
T2REG ( CTCR ) = 0 ; /* Use PCLK */
@ -105,36 +110,36 @@ void init_timer(void)
T2WREG ( TC ) = 0 ; // Reset the counter
T2WREG ( TC ) = 0 ; // Reset the counter
T2WREG ( MCR ) = 0x0400 ; // Reset on MR3 match
T2WREG ( MCR ) = 0x0400 ; // Reset on MR3 match
T2WREG ( PWM ) = 0x0000000d ; // Enable PWMs
T2WREG ( PWM ) = 0x00000005 ; // Enable PWMs
T2WREG ( MR3 ) = PWM_PERIOD ; // Period duration
T2WREG ( MR3 ) = PWM_PERIOD ; // Period duration
/* This is chosen to be an invalid output. */
/* This is chosen to be an invalid output. */
T2WREG ( MR1 ) = 1 ; // Pulse width
T2WREG ( MR2 ) = 1 ; // Pulse width
T2WREG ( MR0 ) = 1 ; // Pulse width
T2WREG ( MR0 ) = 1 ; // Pulse width
T3 REG ( TCR ) = TCR_ENABLE | TCR_RESET ;
T1 REG ( TCR ) = TCR_ENABLE | TCR_RESET ;
T3 REG ( CTCR ) = 0 ; /* Use PCLK */
T1 REG ( CTCR ) = 0 ; /* Use PCLK */
T3 WREG ( PR ) = 0 ; // Prescaling
T1 WREG ( PR ) = 0 ; // Prescaling
T3 WREG ( PC ) = 0 ; // Reset the prescale counter
T1 WREG ( PC ) = 0 ; // Reset the prescale counter
T3 WREG ( TC ) = 0 ; // Reset the counter
T1 WREG ( TC ) = 0 ; // Reset the counter
T3 WREG ( MCR ) = 0x001 0 ; // Reset on MR1 match
T1 WREG ( MCR ) = 0x04 00 ; // Reset on MR3 match
T3 WREG ( PWM ) = 0x0000000b ; // Enable PWMs
T1 WREG ( PWM ) = 0x00000003 ; // Enable PWMs
T3WREG ( MR1 ) = PWM_PERIOD ; // Period duration
T1WREG ( MR3 ) = PWM_PERIOD ; // Period duration
/* This is chosen to be an invalid output. */
/* This is chosen to be an invalid output. */
T3WREG ( MR3 ) = 1 ; // Pulse width
T1WREG ( MR1 ) = 1 ; // Pulse width
T3 WREG ( MR0 ) = 1 ; // Pulse width
T1 WREG ( MR0 ) = 1 ; // Pulse width
T2REG ( TCR ) = TCR_ENABLE ;
T2REG ( TCR ) = TCR_ENABLE ;
T3 REG ( TCR ) = TCR_ENABLE ;
T1 REG ( TCR ) = TCR_ENABLE ;
}
}
unsigned int timer_read ( void )
unsigned int timer_read ( void )
{
{
return T1 WREG ( TC ) ;
return TWREG ( TC ) ;
}
}
void timer_delay_clocks ( unsigned int clocks )
void timer_delay_clocks ( unsigned int clocks )
@ -145,17 +150,17 @@ void timer_delay_clocks(unsigned int clocks)
void timer_set_period ( unsigned int period )
void timer_set_period ( unsigned int period )
{
{
interrupt_register ( TIMER0 , timer_interrupt_handler ) ;
interrupt_register ( TIMER3 , timer_interrupt_handler ) ;
TWREG ( MR0 ) = period ;
T3 WREG ( MR0 ) = period ;
TWREG ( MCR ) = MR0I | MR0R ;
T3 WREG ( MCR ) = MR0I | MR0R ;
TWREG ( TC ) = 0 ;
T3 WREG ( TC ) = 0 ;
}
}
void __attribute__ ( ( interrupt ( " IRQ " ) ) ) timer_interrupt_handler ( void )
void __attribute__ ( ( interrupt ( " IRQ " ) ) ) timer_interrupt_handler ( void )
{
{
unsigned int ir ;
unsigned int ir ;
ir = TREG ( IR ) ;
ir = T3 REG ( IR ) ;
TREG ( IR ) = ir ;
T3 REG ( IR ) = ir ;
if ( ir & ( 1 < < 0 ) ) {
if ( ir & ( 1 < < 0 ) ) {
/* Match channel 0 */
/* Match channel 0 */
@ -165,57 +170,41 @@ void __attribute__((interrupt("IRQ"))) timer_interrupt_handler(void)
interrupt_clear ( ) ;
interrupt_clear ( ) ;
}
}
void __attribute__ ( ( interrupt ( " IRQ " ) ) ) timer1 _interrupt_handler ( void )
void __attribute__ ( ( interrupt ( " IRQ " ) ) ) timer0 _interrupt_handler ( void )
{
{
unsigned int ir ;
unsigned int ir ;
unsigned int gpio ;
unsigned int gpio ;
ir = T1 REG ( IR ) ;
ir = TREG ( IR ) ;
T1 REG ( IR ) = ir ;
TREG ( IR ) = ir ;
gpio = FP0XVAL ;
gpio = FP0XVAL ;
if ( ir & ( 1 < < 4 ) ) {
if ( ir & ( 1 < < 5 ) ) {
/* Capture channel 0 */
/* Capture channel 1 */
if ( gpio & ( 1 < < 10 ) ) {
if ( gpio & ( 1 < < 4 ) ) {
timer1 _rising [ 0 ] = T1 WREG ( CR0 ) ;
timer0 _rising [ 0 ] = TWREG ( CR1 ) ;
} else {
} else {
timer1 _width [ 0 ] = T1 WREG ( CR0 ) - timer1 _rising [ 0 ] ;
timer0 _width [ 0 ] = TWREG ( CR1 ) - timer0 _rising [ 0 ] ;
# ifdef TIMER_CPPM
# ifdef TIMER_CPPM
if ( timer1 _width [ 0 ] > TIMER_CPPM_SYNC ) {
if ( timer0 _width [ 0 ] > TIMER_CPPM_SYNC ) {
timer1 _cppm_chan = 0 ;
timer0 _cppm_chan = 0 ;
timer1_sync_timestamp = timer1 _rising [ 0 ] ;
timer0_sync_timestamp = timer0 _rising [ 0 ] ;
} else {
} else {
if ( timer1 _cppm_chan < 8 ) {
if ( timer0 _cppm_chan < 8 ) {
timer1_cppm [ timer1 _cppm_chan ] =
timer0_cppm [ timer0 _cppm_chan ] =
timer1 _width [ 0 ] ;
timer0 _width [ 0 ] ;
timer1 _cppm_chan + + ;
timer0 _cppm_chan + + ;
}
}
}
}
# endif
# endif
}
}
}
}
if ( ir & ( 1 < < 5 ) ) {
/* Capture channel 1 */
if ( gpio & ( 1 < < 11 ) ) {
timer1_rising [ 1 ] = T1WREG ( CR1 ) ;
} else {
timer1_width [ 1 ] = T1WREG ( CR1 ) - timer1_rising [ 1 ] ;
}
}
if ( ir & ( 1 < < 6 ) ) {
if ( ir & ( 1 < < 6 ) ) {
/* Capture channel 2 */
/* Capture channel 2 */
if ( gpio & ( 1 < < 17 ) ) {
if ( gpio & ( 1 < < 6 ) ) {
timer1_rising [ 2 ] = T1WREG ( CR2 ) ;
timer0_rising [ 1 ] = TWREG ( CR2 ) ;
} else {
timer1_width [ 2 ] = T1WREG ( CR2 ) - timer1_rising [ 2 ] ;
}
}
if ( ir & ( 1 < < 7 ) ) {
/* Capture channel 3 */
if ( gpio & ( 1 < < 18 ) ) {
timer1_rising [ 3 ] = T1WREG ( CR3 ) ;
} else {
} else {
timer1_width [ 3 ] = T1 WREG ( CR3 ) - timer1_rising [ 3 ] ;
timer0_width [ 1 ] = TWREG ( CR2 ) - timer0_rising [ 1 ] ;
}
}
}
}
@ -225,16 +214,16 @@ void __attribute__((interrupt("IRQ"))) timer1_interrupt_handler(void)
bool timer_valid ( int channel ) {
bool timer_valid ( int channel ) {
channel = TIMER_CH ( channel ) ;
channel = TIMER_CH ( channel ) ;
/* Be careful here to ensure that this can't be in the past */
/* Be careful here to ensure that this can't be in the past */
unsigned int chtime = timer1 _rising [ channel ] ; /* Atomic */
unsigned int chtime = timer0 _rising [ channel ] ; /* Atomic */
unsigned int time = T1 WREG ( TC ) ; /* Atomic */
unsigned int time = TWREG ( TC ) ; /* Atomic */
return ( time - chtime ) < TIMER_INPUT_TIMEOUT ;
return ( time - chtime ) < TIMER_INPUT_TIMEOUT ;
}
}
# ifdef TIMER_CPPM
# ifdef TIMER_CPPM
bool timer_allvalid ( void ) {
bool timer_allvalid ( void ) {
/* Be careful here to ensure that this can't be in the past */
/* Be careful here to ensure that this can't be in the past */
unsigned int chtime = timer1 _sync_timestamp ; /* Atomic */
unsigned int chtime = timer0 _sync_timestamp ; /* Atomic */
unsigned int time = T1 WREG ( TC ) ; /* Atomic */
unsigned int time = TWREG ( TC ) ; /* Atomic */
return ( time - chtime ) < TIMER_INPUT_TIMEOUT ;
return ( time - chtime ) < TIMER_INPUT_TIMEOUT ;
}
}
# else
# else
@ -244,8 +233,8 @@ bool timer_allvalid(void) {
int i ;
int i ;
/* Be careful here to ensure that this can't be in the past */
/* Be careful here to ensure that this can't be in the past */
for ( i = 0 ; i < 4 ; i + + )
for ( i = 0 ; i < 4 ; i + + )
chtime [ i ] = timer1 _rising [ i ] ;
chtime [ i ] = timer0 _rising [ i ] ;
time = T1 WREG ( TC ) ;
time = TWREG ( TC ) ;
for ( i = 0 ; i < 4 ; i + + )
for ( i = 0 ; i < 4 ; i + + )
if ( ( time - chtime [ i ] ) > = TIMER_INPUT_TIMEOUT )
if ( ( time - chtime [ i ] ) > = TIMER_INPUT_TIMEOUT )
return FALSE ;
return FALSE ;
@ -264,10 +253,10 @@ void timer_set_pwm_value(int channel, int value)
T2WREG ( MR0 ) = value ;
T2WREG ( MR0 ) = value ;
break ;
break ;
case 2 :
case 2 :
T3WREG ( MR3 ) = value ;
T1WREG ( MR0 ) = value ;
break ;
break ;
case 3 :
case 3 :
T3WREG ( MR0 ) = value ;
T1WREG ( MR1 ) = value ;
break ;
break ;
}
}
}
}
@ -283,10 +272,10 @@ void timer_set_pwm_invalid(int channel)
T2WREG ( MR0 ) = value ;
T2WREG ( MR0 ) = value ;
break ;
break ;
case 2 :
case 2 :
T3WREG ( MR3 ) = value ;
T1WREG ( MR0 ) = value ;
break ;
break ;
case 3 :
case 3 :
T3WREG ( MR0 ) = value ;
T1WREG ( MR1 ) = value ;
break ;
break ;
}
}
}
}