Browse Source

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.
master
Gavan Fantom 12 years ago
parent
commit
b482b85ffd
  1. 4
      interrupt.h
  2. 2
      led.c
  3. 12
      main.c
  4. 157
      timer.c
  5. 19
      timer.h
  6. 4
      watchdog.c

4
interrupt.h

@ -34,8 +34,8 @@
#define I_PRIORITY_I2C0 0
#define I_PRIORITY_UART0 1
#define I_PRIORITY_TIMER0 2
#define I_PRIORITY_TIMER1 3
#define I_PRIORITY_TIMER3 2
#define I_PRIORITY_TIMER0 3
#define interrupt_clear() do { VICVectAddr = 0xff; } while (0)

2
led.c

@ -36,7 +36,7 @@ void led_update(void)
led_set(led_next_state);
led_next_state = !led_next_state;
led_next_time += *led_current_pointer * TIMER_MS;
led_next_time += *led_current_pointer * TIMER0_MS;
led_current_pointer++;
if (*led_current_pointer == 0)
led_current_pointer = led_current_pattern;

12
main.c

@ -22,12 +22,16 @@
void init_pins(void)
{
PINSEL0 = 0x00a88055; /* P0.0 and P0.1 assigned to UART */
PINSEL0 = 0x2a09a255; /* P0.0 and P0.1 assigned to UART */
/* P0.2 and P0.3 assigned to I2C */
/* P0.4 and P0.6 assigned to CAP0.[12] */
/* P0.7 and P0.9 assigned to MAT2.[02] */
/* P0.10 and P0.11 assigned to CAP1.[01] */
PINSEL1 = 0x20000828; /* P0.21 and P0.30 assigned to MAT3.[03] */
/* P0.17 and P0.18 assigned to CAP1.[23] */
/* P0.8 assigned to UART1 */
/* P0.12 and P0.13 assigned to MAT1.[01] */
/* P0.14 assigned to SPI1 */
PINSEL1 = 0x00000540; /* P0.19 to P0.21 assigned to SPI1 */
SCS = 1;
FP0XDIR = 0x04000000; /* P0.26 is an output */
FP0XVAL = 0x0;

157
timer.c

@ -58,45 +58,50 @@
#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)
{
TREG(TCR) = TCR_ENABLE | TCR_RESET;
T3REG(TCR) = TCR_ENABLE | TCR_RESET;
TREG(CTCR) = 0; /* Use PCLK */
TWREG(TC) = 0;
TWREG(PR) = TIMER_PRESCALE ;
TWREG(PC) = 0;
T3REG(CTCR) = 0; /* Use PCLK */
T3WREG(TC) = 0;
T3WREG(PR) = TIMER_PRESCALE;
T3WREG(PC) = 0;
TREG(TCR) = TCR_ENABLE;
T3REG(TCR) = TCR_ENABLE;
interrupt_register(TIMER1, timer1_interrupt_handler);
interrupt_register(TIMER0, timer0_interrupt_handler);
T1REG(TCR) = TCR_ENABLE | TCR_RESET;
TREG(TCR) = TCR_ENABLE | TCR_RESET;
T1REG(CTCR) = 0; /* Use PCLK */
T1WREG(TC) = 0;
T1WREG(PR) = TIMER_PRESCALE ;
T1WREG(PC) = 0;
TREG(CTCR) = 0; /* Use PCLK */
TWREG(TC) = 0;
TWREG(PR) = TIMER0_PRESCALE;
TWREG(PC) = 0;
T1WREG(CCR) = 0x00000fff;
TWREG(CCR) = 0x00000fff;
T1REG(TCR) = TCR_ENABLE;
TREG(TCR) = TCR_ENABLE;
T2REG(TCR) = TCR_ENABLE | TCR_RESET;
T2REG(CTCR) = 0; /* Use PCLK */
@ -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);
} 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);
if (gpio & (1<<6)) {
timer0_rising[1] = TWREG(CR2);
} 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;
}
}

19
timer.h

@ -4,12 +4,17 @@
#include "types.h"
#define TIMER_PCLK 14745600
#define TIMER_PRESCALE 0
#define TIMER_PRESCALE 9215
#define TIMER0_PRESCALE 0
#define TIMER_SECOND (TIMER_PCLK/(TIMER_PRESCALE+1))
#define TIMER_MS (TIMER_SECOND/1000)
#define TIMER_US (TIMER_SECOND/1000000)
#define TIMER0_SECOND (TIMER_PCLK/(TIMER0_PRESCALE+1))
#define TIMER0_MS (TIMER0_SECOND/1000)
#define TIMER0_US (TIMER0_SECOND/1000000)
#define PWM_MAX 14745
#if 0
#define PWM_PERIOD 58980
@ -21,8 +26,8 @@
#define TIMER_CH(x) (timer_map[x])
extern volatile unsigned int timer1_width[];
extern volatile unsigned int timer1_cppm[];
extern volatile unsigned int timer0_width[];
extern volatile unsigned int timer0_cppm[];
extern unsigned int timer_map[];
void init_timer(void);
@ -34,12 +39,12 @@ void timer_set_pwm_invalid(int channel);
bool timer_valid(int channel);
bool timer_allvalid(void);
#define timer_delay_us(x) timer_delay_clocks((x)*TIMER_US)
#define timer_delay_ms(x) timer_delay_clocks((x)*TIMER_MS)
#define timer_delay_us(x) timer_delay_clocks((x)*TIMER0_US)
#define timer_delay_ms(x) timer_delay_clocks((x)*TIMER0_MS)
#ifdef TIMER_CPPM
#define timer_input(ch) (timer1_cppm[TIMER_CH(ch)])
#define timer_input(ch) (timer0_cppm[TIMER_CH(ch)])
#else
#define timer_input(ch) (timer1_width[TIMER_CH(ch)])
#define timer_input(ch) (timer0_width[TIMER_CH(ch)])
#endif
#endif /* __TIMER_H */

4
watchdog.c

@ -13,13 +13,13 @@
* now, something's gone horribly wrong.
*/
#define WATCHDOG_TIMEOUT (100 * TIMER_MS)
#define WATCHDOG_TIMEOUT (100 * TIMER0_MS)
static unsigned int watchdog_last_seen[WATCHDOG_MODULES];
void watchdog_kick(unsigned int module)
{
if (module > WATCHDOG_MODULES)
if (module >= WATCHDOG_MODULES)
return;
watchdog_last_seen[module] = timer_read();
}

Loading…
Cancel
Save