PCINT instead of INT0?

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
autorelease

PCINT instead of INT0?

Post by autorelease » Wed Mar 11, 2009 9:02 pm

Has anyone has success using with a pin-change interrupt instead of INT0? I'm using an ATmega168 (INT0 is PD2) and unfortunately I'm already using all of PORTD as an 8-bit output.

I've seen it mentioned that one of the PCINTs could be used with another pin, but I haven't found any concrete examples of this working. I'd like to use PB0 and PB1 (or vice versa) for the data lines if possible.

I'm using timer1 already, so I can't misuse input capture like USB2LPT does.

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: PCINT instead of INT0?

Post by christian » Sat Apr 11, 2009 7:05 pm

This does work, provided that you don't use the higher priority hardware interrupts and that you configure the interrupts correctly. See the end of usbconfig-prototype.h.

iphi
Rank 2
Rank 2
Posts: 68
Joined: Mon Jun 25, 2007 11:37 am

Re: PCINT instead of INT0?

Post by iphi » Sat Jul 03, 2010 11:35 am

Can somebody point me to an example project that uses a different interrupt than INT0, preferably a PCINT, please?

I have spent a couple of days but I seem too stupit to change the interrupt from INT0 to INT1 or a PCINT. INT0 works fine, but any other interrupt does not work for me. Currently I am experimenting with the template device.

Thanks, Tom

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: PCINT instead of INT0?

Post by christian » Mon Jul 05, 2010 6:02 pm


iphi
Rank 2
Rank 2
Posts: 68
Joined: Mon Jun 25, 2007 11:37 am

Re: PCINT instead of INT0?

Post by iphi » Thu Jul 08, 2010 12:24 pm

Hi Christian,

thank you very much for your hint. I could get it working on INT1 instead of INT0 on a Mega88.
I am still having trouble using the PCINT0 instead.

Here are my settings for PCINT0, which compile fine but refuse to work.
Can somebody point me to my error, please?

Code: Select all

                                     //commented values for INT1 work fine
#define USB_INTR_CFG            PCICR         //EICRA
#define USB_INTR_CFG_SET        (1 << PCIE0)     //((1 << ISC10) | (1 << ISC11))    //00,01 for INT0
//#define USB_INTR_CFG_CLR        0
#define USB_INTR_ENABLE         PCMSK0        //EIMSK
#define USB_INTR_ENABLE_BIT     PCINT0        //INT1
#define USB_INTR_PENDING        PCIFR         //EIFR
#define USB_INTR_PENDING_BIT    PCIF0         //INTF1
#define USB_INTR_VECTOR         SIG_PIN_CHANGE  //SIG_INTERRUPT1

frank26080115
Rank 2
Rank 2
Posts: 43
Joined: Fri Jun 19, 2009 4:43 pm

Re: PCINT instead of INT0?

Post by frank26080115 » Thu Jul 08, 2010 6:24 pm

it looks like if you use external interrupts (as in INT0, INT1, etc), the interrupt is generated on a rising edge signal. Pin change interrupts occur regardless of rising or falling edge. This may be one problem.

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: PCINT instead of INT0?

Post by christian » Thu Jul 08, 2010 6:53 pm

No, the driver works with all three, rising edge, falling edge and change triggered interrupt. You should verify whether the interrupt handler is actually called...

iphi
Rank 2
Rank 2
Posts: 68
Joined: Mon Jun 25, 2007 11:37 am

Re: PCINT instead of INT0?

Post by iphi » Thu Jul 08, 2010 9:11 pm

Hi Christian,

I have used the flooowing hook to check if the interrupt handler is called:

Code: Select all

#define USB_RX_USER_HOOK(data, len)  PORTC=~PORTC; 

Is this the correct way to check?

I have an LED connected to PORTC. With INT1 I see it toggeling a couple of times when I plug in the device.
Using PCINT0 I see no action whatsoever. Does this mean the interrupt handler is never called?

Where could I look to solve the problem?

Thanks, Tom

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: PCINT instead of INT0?

Post by christian » Fri Jul 09, 2010 5:35 pm

Yes, this means that the handler is never called. It seems that either the vector address is not correct (you can check this with a disassembler listing of the linked code) or the interrupt is not enabled. Don't know which steps are required to enable a PCINT, I would have to read the data sheet...

iphi
Rank 2
Rank 2
Posts: 68
Joined: Mon Jun 25, 2007 11:37 am

Re: PCINT instead of INT0?

Post by iphi » Sun Jul 11, 2010 8:34 pm

Hi Christian,

I have read the data sheet and written some test code. This is what it takes to enable a PCINT0 on a Mega88:

Code: Select all

sei();
PCICR=PCICR | (1 << PCIE0);
PCMSK0=PCMSK0 | (1 << PCINT0);


as compaared to enabling an INT0:

Code: Select all

sei();
EICRA=EICRA | ((1 << ISC00) | (1 << ISC01));   
EIMSK=EIMSK | (1 << INT0);


Still, V-USB doesn't run on PCINT0 on my Mega88 while my interrupt test code lets the interrupt happily trigger.
V-USB and INT0 or INT1 works fine.

Here are my V-USB settings again:

Code: Select all

#define USB_INTR_CFG            PCICR         
#define USB_INTR_CFG_SET        (1 << PCIE0)     
//#define USB_INTR_CFG_CLR        0
#define USB_INTR_ENABLE         PCMSK0        
#define USB_INTR_ENABLE_BIT     PCINT0        
#define USB_INTR_PENDING        PCIFR         
#define USB_INTR_PENDING_BIT    PCIF0         
#define USB_INTR_VECTOR         SIG_PIN_CHANGE 


Please help.

Thanks, Tom

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: PCINT instead of INT0?

Post by christian » Mon Jul 12, 2010 10:01 am

Have you verified the interrupt vector? If SIG_PIN_CHANGE is not defined, the interrupt handler will never be called and there's no compiler/linker warning or error. Please check main.elf with

avr-objdump -d main.elf

Then check the verctor address for pin change and see whether it contains the jump to your handler.

iphi
Rank 2
Rank 2
Posts: 68
Joined: Mon Jun 25, 2007 11:37 am

Re: PCINT instead of INT0?

Post by iphi » Mon Jul 12, 2010 10:27 am

Hi Christian,

thanks for the hint! I think we are getting closer. I did a simple test.
I added the lines

Code: Select all

#ifdef SIG_PIN_CHANGE
crash
#endif

to usbconfig.h and tried to compile. No error messages => SIG_PIN_CHANGE is undefined!
Replacing SIG_PIN_CHANGE by SIG_INTERRUPT1 will cause a compiler crash as expected if SIG_INTERRUPT1 is defined.

Where should SIG_PIN_CHANGE get defined and what should be its value?...

P.S.

... Ok, found and fixed it, hurray, it is working now!
Vectors are defined in <avr/interrupt.h>, see avrgcc manual.

SIG_PIN_CHANGE should read SIG_PIN_CHANGE0 (old) or better PCINT0_vect (new).
Also, I think in the usbconfig.h template SIG_INTERRUPT0 should be replaced by INT0_vect, as the former old name is not supported for all MCUs, e.g. not for Mega328P.

Thanks for pointing me in the right direction,
Tom

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: PCINT instead of INT0?

Post by christian » Mon Jul 12, 2010 11:36 am

Yes, INT0_vect is already there in the repository, it will be published with the next release.

Post Reply