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:
157
timer.c
157
timer.c
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user