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_I2C0 0
#define I_PRIORITY_UART0 1 #define I_PRIORITY_UART0 1
#define I_PRIORITY_TIMER0 2 #define I_PRIORITY_TIMER3 2
#define I_PRIORITY_TIMER1 3 #define I_PRIORITY_TIMER0 3
#define interrupt_clear() do { VICVectAddr = 0xff; } while (0) #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_set(led_next_state);
led_next_state = !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++; led_current_pointer++;
if (*led_current_pointer == 0) if (*led_current_pointer == 0)
led_current_pointer = led_current_pattern; led_current_pointer = led_current_pattern;

12
main.c

@ -22,12 +22,16 @@
void init_pins(void) 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.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.7 and P0.9 assigned to MAT2.[02] */
/* P0.10 and P0.11 assigned to CAP1.[01] */ /* P0.8 assigned to UART1 */
PINSEL1 = 0x20000828; /* P0.21 and P0.30 assigned to MAT3.[03] */ /* P0.12 and P0.13 assigned to MAT1.[01] */
/* P0.17 and P0.18 assigned to CAP1.[23] */ /* P0.14 assigned to SPI1 */
PINSEL1 = 0x00000540; /* P0.19 to P0.21 assigned to SPI1 */
SCS = 1; SCS = 1;
FP0XDIR = 0x04000000; /* P0.26 is an output */ FP0XDIR = 0x04000000; /* P0.26 is an output */
FP0XVAL = 0x0; FP0XVAL = 0x0;

157
timer.c

@ -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; T3REG(TCR) = TCR_ENABLE | TCR_RESET;
TREG(CTCR) = 0; /* Use PCLK */ T3REG(CTCR) = 0; /* Use PCLK */
TWREG(TC) = 0; T3WREG(TC) = 0;
TWREG(PR) = TIMER_PRESCALE ; T3WREG(PR) = TIMER_PRESCALE;
TWREG(PC) = 0; 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 */ TREG(CTCR) = 0; /* Use PCLK */
T1WREG(TC) = 0; TWREG(TC) = 0;
T1WREG(PR) = TIMER_PRESCALE ; TWREG(PR) = TIMER0_PRESCALE;
T1WREG(PC) = 0; TWREG(PC) = 0;
T1WREG(CCR) = 0x00000fff; TWREG(CCR) = 0x00000fff;
T1REG(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
T3REG(TCR) = TCR_ENABLE | TCR_RESET; T1REG(TCR) = TCR_ENABLE | TCR_RESET;
T3REG(CTCR) = 0; /* Use PCLK */ T1REG(CTCR) = 0; /* Use PCLK */
T3WREG(PR) = 0; // Prescaling T1WREG(PR) = 0; // Prescaling
T3WREG(PC) = 0; // Reset the prescale counter T1WREG(PC) = 0; // Reset the prescale counter
T3WREG(TC) = 0; // Reset the counter T1WREG(TC) = 0; // Reset the counter
T3WREG(MCR) = 0x0010; // Reset on MR1 match T1WREG(MCR) = 0x0400; // Reset on MR3 match
T3WREG(PWM) = 0x0000000b; // Enable PWMs 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. */ /* This is chosen to be an invalid output. */
T3WREG(MR3) = 1; // Pulse width T1WREG(MR1) = 1; // Pulse width
T3WREG(MR0) = 1; // Pulse width T1WREG(MR0) = 1; // Pulse width
T2REG(TCR) = TCR_ENABLE; T2REG(TCR) = TCR_ENABLE;
T3REG(TCR) = TCR_ENABLE; T1REG(TCR) = TCR_ENABLE;
} }
unsigned int timer_read(void) unsigned int timer_read(void)
{ {
return T1WREG(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; T3WREG(MR0) = period;
TWREG(MCR) = MR0I | MR0R; T3WREG(MCR) = MR0I | MR0R;
TWREG(TC) = 0; T3WREG(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 = T3REG(IR);
TREG(IR) = ir; T3REG(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 = T1REG(IR); ir = TREG(IR);
T1REG(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] = T1WREG(CR0); timer0_rising[0] = TWREG(CR1);
} else { } else {
timer1_width[0] = T1WREG(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] = 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) { 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 = T1WREG(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 = T1WREG(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 = T1WREG(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;
} }
} }

19
timer.h

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

4
watchdog.c

@ -13,13 +13,13 @@
* now, something's gone horribly wrong. * 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]; static unsigned int watchdog_last_seen[WATCHDOG_MODULES];
void watchdog_kick(unsigned int module) void watchdog_kick(unsigned int module)
{ {
if (module > WATCHDOG_MODULES) if (module >= WATCHDOG_MODULES)
return; return;
watchdog_last_seen[module] = timer_read(); watchdog_last_seen[module] = timer_read();
} }

Loading…
Cancel
Save