AVR, polling INT0 IRQ bit - help?

I'm porting some old code that uses a pin-change interrupt flag as an edge detector. The new target micro is an AVR (ATmega169). I'm having real trouble getting the INT0 logic to work like I think it should.

I set DDRD = 0xe5 (INT0 is on bit 1 of port D), PORTD = 0x20, and EICRA = EICRA | ISC00_MASK | ISC01_MASK to look for positive edges.

I see the input pin wiggling away, but (EIFR & (1

Reply to
larwe
Loading thread data ...

Interesting, I am porting the same code from 169 to 6502.

As far as I know, pin change interrupts are on port B and E only. Please check the spec.

Reply to
linnix

Not familiar with the ATMega169, but what about setting INT0 in EIMSK?

Quoting:

formatting link

"External Interrupt Mask Register - EIMSK

[...]

Bit 0 - INT0: External Interrupt Request 0 Enable

When the INT0 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), the external pin interrupt is enabled. The Interrupt Sense Control0 bits 1/0 (ISC01 and ISC00) in the External Interrupt Control Register A (EICRA) define whether the external interrupt is activated on rising and/or falling edge of the INT0 pin or level sensed. [...]"

Regards, Gilles.

Reply to
Gilles Kohl

.

PCINT is on B and E, but INT0 is a dedicated, polarity-programmable interrupt on PD1.

Well, I solved my problem - it turns out very simply the pin on the IC wasn't soldered properly. My scope probe was on the trace, not the actual pin - when I probed the pin I saw it wasn't actually changing. A drop of solder fixed the problem.

However, do you have the port B PCINTs working in your application? I am now trying to get the same sort of functionality working on

Note that I don't want to actually fire the interrupt - I just need to poll the pin-change IRQ bit for one of the pins of port B.

Reply to
larwe

I don't want the interrupt to fire. As it turns out my problem was a silly one... see my other posting. But thanks for the reply.

Reply to
larwe

OK

Yes, I use four pins (E3 to E0) for buttons. Any button changes wake up the processor, which was put to sleep after a few minutes of idleing.

I do need interrupt to get the uC out of sleep mode.

Reply to
linnix

I have used the port change interrupt to read an optical encoder. IIRC it had 3 bits of output, A, B, and index. PCINT was the best available option as all other resources were allocated.

A minor problem with PCINT is that there is not a register indicating which pin changed to fire the interrupt. By the time you get around to reading it it may be unchanged (due to bouncing). So it helps to keep a copy of the prior values laying around to XOR the current values against.

If (as in my case with the optical encoder) the value has to be stable for a bit to be valid, be prepared to exit the interrupt handler having done nothing.

Unless the shaft was turning fast my optical encoder bounced a lot when it was making changes. The solution was once phase A or B changed to disable that pin change interrupt and enable the other. When one was changing the other was stable.

Reply to
David Kelly

I'm not permitted to use interrupts in this code. I am simply trying to use the IRQ bit as an edge detector - which isn't working at all : ( I'm pretty baffled and wondering if this feature actually works. No response from Atmel FAE yet.

Reply to
larwe

Sorry to come in late on this one. But it should be possible to do what you want.

Let's say for example that you want to get a signal from a pin change on PB7. Then you need to do the following:

Set DDRB bit 7 Set PORTB bit 7 to enable the internal pull-up on PB7 Clear the PUD bit in MCUCR to enable internal pull-ups globally Set PCMSK1 bit 7 (PCINT15 bit) Set EIMSK bit 7 (PCIE1 bit) Clear SREG bit 7 (I bit)

Now any change on PINB7 should set bit 7 in EIFR (PCIF1). Note that in order to clear this bit, you must write a 1 to it when it is set,

HTH

--
John B
Reply to
John B

Set? That makes it an output.

Is it necessary to set PCIE1 if you do not actually want the IRQ to fire? I want/need to poll this bit in mainline code, I can't let an ISR grab it. (Having said this, the IRQ wouldn't fire when I tried it the normal way, with PCIE1 set, anyway).

Reply to
larwe

Yes, this enables the Pin Change Interrupt block 1.

Fine as long as you disable the global interrupt mask.

I assume you are polling PC!F1.

It does work for me in normal interrupt mode.

Reply to
linnix

Oops, sorry I originally wrote "Set DDRB bit 7 to 0" and then edited it incorrectly.

Yes, as Linnix says the PCIE1 bit enables the pin change block for PC15 through to PC8 to function. That will allow the PCIE1 flag to be set. Clearing the I bit in SREG stops that flag propagating through to the interrupt mechanism.

--
John B
Reply to
John B

This isn't how I understood it - as I understood it, yes you have to set PCMSKxxx to enable the specific pin, but then the PCINT8..15 interrupt, PCIE1, is ANDED with PCIF1 and it's the result of this that is then gated with the global interrupt flag to determine if the core gets an interrupt. However, the point is moot - even when I set PCIE1 and disable global interrupts, the request flag is STILL not being set.

Atmel claims that my exact same code works on their hardware, so I'm baffled. I can physically see the pin changing state (and I've even verified that the micro is seeing that change of state). Beyond mysterious.

Reply to
larwe

. . .

Well that certainly does sound strange. I've used the pin-change flag on a mega2561 in exactly the same way as you are trying to. It's possible that the mega169 uses a different block but I would think that's unlikely as they would have to rewrite and test the Verilog.

Maybe Ulf will come along soon and give us a definitive answer.

--
John B
Reply to
John B

Of course the problem turns out to be my fault (well, someone else in my team originally, but my fault for not spotting it). Our circuit can use the 169/329/649 but initial bring-up was done on the 169. Someone forgot or ignored my advice to include avr.h and instead included mega169.h

MOST of the registers are the same between 169 and 32/649 but not all of them. The PCINT bit assignments in particular are different!

Also, it is not necessary to set the interrupt mask for PCIE1 in order to see PCIF1 toggling.

Reply to
larwe

BTW, many small problems like that is one of the reasons for not using AVRs.

Vladimir Vassilevsky DSP and Mixed Signal Design Consultant

formatting link

Reply to
Vladimir Vassilevsky

Rs.

I can't blame Atmel for this - we were using the wrong header file. We should have included avr.h and let the compiler pick the correct chip- specific header based on the project settings.

I agree this would be an issue if we needed binary compatibility, but in practice we don't (the administrative requirements of changing micros are massive and the cost of SWQA for a recompile-to-new-chip operation is negligible).

Reply to
larwe

I agree. We can blame Atmel for many other faults, but not for product migrations. If we force them to be binary compatible, then we end up with a static uC architecture.

We are moving off the 169 purely for cost reason. Our new uC (6502) is 75% off, but it's difficult to port the hardware/software. The 169 fits so well in the original project, if only they have lower cost solution.

By the way, our new uC will be die-bounded Chip-On-Board One-Time- Programmable. Atmel is certainly capable of providing COG and OTP, but unwilling to do so.

Reply to
linnix

. .

Yep, been there as well!! I use Imagecraft ICCAVR and there is a similar system in place of allowing the compiler to pick the correct header file.

Always a problem of an ever expanding product range. At least the series (eg m640, m1280, m2560, m5120??) match one another.

Ah, I must revisit my 2561 application and check. I found the PCIE0 bit had to be set, but I guess there may have been other reasons.

--
John B
Reply to
John B

Energy metering project? (That's what the mega169/329/649 were designed for). Are you using one of the 6502 variants e.g. from Sunplus, intended for toy use? Just out of interest, what's your cost target? We moved to the mega169 because it's significantly under $1.

I can't see that an OTP version of the mega169 would really be cheaper

- since it's not a standard part, there would be big NREs.

Reply to
larwe

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.