Firmware changes to match rewired control board.

This is a bit more difficult than just reassigning pins as the usage
of the timers has changed to the point of using 16 bit timers where 32 bit
timers would have been ideal. This makes the use of the prescaler necessary,
and we need to cope with a different prescaler value being used on different
timers.
This commit is contained in:
2013-05-25 19:24:39 +00:00
parent b9c08d88b1
commit b482b85ffd
6 changed files with 98 additions and 100 deletions

157
timer.c
View File

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