Pages: [1]   Go Down
Author Topic: Input capture - what am I doing wrong here?  (Read 944 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Device is a Mega2560.

I'm working on interfacing to a GPS, and capturing the "1 pulse per second" signal that it outputs. Today I got things wired up and running, but I'm not having any luck with input capture. Partial code:

Code:
void timer_init() {
  pinMode(48, INPUT);
  pinMode(2, INPUT);
//  TCCR4A = _BV(COM4A1) | _BV(COM4A0);
  TCCR4A = 0;
  TCCR4B = _BV(CS41) | _BV(WGM42) | _BV(ICES4);
  TIMSK4 = _BV(OCIE4A) | _BV(ICIE4) | _BV(TOIE4);
  timer_set_interval(DEF_TIMER_VAL);
  timer_ready = 1;
  attachInterrupt(0, int4, RISING);
}

void timer_set_interval(unsigned short top) {
  OCR4A = top;
}

ISR(TIMER4_CAPT_vec) {
  Serial.print("PPS!\n");
}

void int4() {
  Serial.print("INT4 ");
  Serial.print(time_get_ns());
  Serial.print("\n");
}

timer_init() is called on startup, and there's an ISR(TIMER4_COMPA_vect) that does some timekeeping code that I didn't include -- it works just fine. I'm also running a mainloop that copies data from the GPS serial port (Serial1, pins 18/19) to the USB, which is also working alright.

The PPS line is normally 0V, but goes to 3V for a 1-microsecond pulse. If I wire it to pin 2, I can get the INT4 interrupt to fire, but if I wire it to pin 48 I get nothing. I was thinking that maybe the level or duration was too small for the input capture pin, so I also tried momentarily shorting pin 48 to the 3V3 and 5V lines, and still not a peep out of the interrupt handler, which leads me back to software. Do I have any obvious bugs? smiley
Logged

Italy
Offline Offline
Full Member
***
Karma: 3
Posts: 142
jayduino rox
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Device is a Mega2560.

  pinMode(48, INPUT);

  attachInterrupt(0, int4, RISING);

isn't int4 connected to pin 19 by default?
Logged

Juergen

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pin 2 (it's what Arduino calls "interrupt 0" and Atmel calls INT4). Anyway, that one is working without any trouble.

Full code is now online @ http://cleverdomain.org/git/arduino/HEAD/tree
Logged

Italy
Offline Offline
Full Member
***
Karma: 3
Posts: 142
jayduino rox
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hm, ok, I try again.
PL1, which is pin 48, is also ICP5, hence Timer 5.
I think you should use pin49 (PL0->ICP4), or am I missing something?
Logged

Juergen

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That's certainly a good call -- unfortunately it's not doing anything on pin 49 either. I'm getting good results using pin 2, and I've started writing my PLL using that -- but I'd still like to get input capture working and not worry about how many microseconds I'm losing on the way into the ISR smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After several days of ditching the problem and working on other parts of the code, I finally found out what was wrong with input capture, and I hate to say it, but it was a typo. Documenting it here in case anyone else ever has a similar problem and needs to google it.

If you define ISR(TIMER4_CAPT_vect), it gets macro-expanded into a function __vector_8 with flags that convince the linker to install it into the interrupt table. But if you define ISR(TIMER4_CAPT_vec), without the t it turns into a function ISR_CAPT_vec which silently does absolutely nothing.
Logged

Pages: [1]   Go Up
Jump to: