Jump to content
43oh

gpio interrupts


Recommended Posts

Is it possible for an interrupt on one GPIO pin to affect the output on another pin ? I am toggling P1.5 externally, and some how it is affecting the output of another pin ( P2.1 ). How I know this is fact, as P2.1 is hooked up the the RESET pin on another processor, and that processor immediately resets. Even though the code does not act on anything right now.

 

Below is literally all I have, except for pin setup. The code compiles fine, and uploads onto hte launchpadd v1.5(g2553) just fine.

int main(void)
{
        WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer

        setup();

        __enable_interrupt();

        // Main loop
        while(1){
                // Pet the dog.
                WDTCTL = WDTPW | WDTCNTCL;

        }
        return 0;
}
__attribute__( (interrupt (TIMER1_A0_VECTOR)) )
void TIMER1_A0_ISR(void)
{

        if (counter++ > 100){                     // ~1 Second
                counter = 1;
                //seconds++;

        }
}

__attribute__( (interrupt (PORT1_VECTOR)) )
void PORT1_ISR(void)
{

        if(P1IFG & BIT0){
                flags |= HALT;
                P1IFG &= (~BIT0);
        }

        if(P1IFG & BIT5){

                if(flags & ENABLED){            // We've been enabled by the host.
                     
                }
                else{                           // Not yet enabled by the host.
             
                }

                P1IFG &= (~BIT5);
        }
}
Link to post
Share on other sites

@@spirilis thanks for the response. I could, but i think we've isolated the problem to our internally designed board. The board we're hooked up to is a beaglebone black. The board between the two is a custom controller board that I can not talk much about.

 

But the problem lies with a chip that is a bi directional gate( bi-directional transistor ) which is a newly designed chip that my buddy obviously has never had experience with. So, with the MSP430 off our custom board, toggling P9.27 on the beaglebone triggers( somehow ) RESETn. But with the beaglebone off the custom board too, this does not happen. There are no direct shorts between these pin on the beaglebone. So me being the non electronic engineer guy assumed there had to be some glitch in my software that I was unaware of.

 

So I misspoke earlier. I did not know for a fact that P1.5 was effecting P2.1. I simply meant that on the other side of the isolation the pins were somehow toggling one another.

Link to post
Share on other sites


void setup(void)

{

        DCOCTL = 0;

        DCOCTL = CALDCO_1MHZ;

        BCSCTL1 = CALBC1_1MHZ;

        BCSCTL2 = DIVS_0;

 

        /* Timer1 A0*/

        TA1CCR0 = 1250;                         // Count overflow frequency

        TA1CTL = TASSEL_2 + ID_3 + MC_1;        // SMCLK/8  upmode

                                                // ( 1000000 / 8 ) / 1250 == 10ms tick

        TA1CCTL0 = CCIE;

 

        P1SEL &= (~BIT0 + BIT5);                // Set P1.0 and P1.5 SEL as GPIO

        P1DIR &= (~BIT0 + BIT5);                // Set P1.0 and P1.5 SEL as Input

        P1IES |= (BIT0) + (BIT5);               // Falling Edge 1 -> 0

        P1IFG &= (~BIT0 + BIT5);                // Clear interrupt flag for P1.5

        P1IE |=  (BIT0) + (BIT5);               // Enable interrupt for P1.5

 

        P2DIR |= BIT1 + BIT3;

        P2OUT |= BIT1;                          // Beaglebone RESET_N active low - Normal high

        P2OUT &= (~BIT3);                       // Beaglebone battery connection active low - Disconnected high

}

Link to post
Share on other sites

So, this chip, the bi direction gate. Has 2 channels. A and B. Then each channel has two sides, 1, and 2. From the table in the pin description, the wording makes it sound as though the channels work together. When in fact, the pins 1, and 1 complete the circuit when the enable pin is toggled. So toggling A1 from one side, will toggle B1 the same on the other side. Where the datasheet made it seem as A1, and A2 was the relation. . . So with our design as it stood, I was toggling RESETn directly from P9.27 on the beagleobne . . . managed to corrupt the image I had on the sdcard too :/

 

Anyway, we had to use this specific chip for our design as regular opti-couplers were not working correctly in the original design. And the Beaglebone's pins have to be isolated at system up.

Link to post
Share on other sites

Sounds like a level shifter, like a TXB0102 or similar?  I've had some experience with those.  Yeah the whole idea is A1 & B1 talk together, A2 & B2 talk together.  If it's a bidirectional "sensing" type of chip like the TXB, on top of that you have to acknowledge that the drive strength on the outputs are limited, e.g. they don't recommend using pullups or pulldowns lower than 50K ohms in value on any of the pins intended to receive output from one of the channels...

 

Where I've used the TXB is to power down the A-side voltage (on the TXB at least, VccA must be <= VccB, also the EN pin is attached to the Vcc(A) net.  The host MCU turns off a PFET supplying Vcc(A) so that the TXB shuts down, and all the hardware on the A-side shuts down so it uses no power (think MAX31855 thermocouple chip... has no native way to shut itself off so it just keeps drinking current nonstop unless you surround it with a mousetrap like this).

Link to post
Share on other sites

Yeah, I think that's it @@spirilis. I think it's definately at least a TXB part. But 3 of us all fairly smart people could not make heads nor tails of the datasheet table that describes the pin functions.

 

So right now, I'm experiencing another issue in my code. I'm trying to setup a pulse counter on one of the gpio's and it's not working the way I'd expect. These g2553's only have edge detection on interrupt right ? So like if my external pin in always low, and I'm clearing the interrupt flag on a falling edge interrupt. It wont count multiple interrupts. Will it ?

 

EDIT:

 

By the way, the way we figured out how the part works. My buddy soldered resistors to all the pins, just to have something to get a scope probe attached to. Then we just starting feeding 3v3 into each side of each channel and observed what was going on . . .

Link to post
Share on other sites

I'm curious about this snippet of code. Your use of brackets is confusing to me. Particularly these 3 lines.

 

...
        P1SEL &= (~BIT0 + BIT5);                // Set P1.0 and P1.5 SEL as GPIO
        P1DIR &= (~BIT0 + BIT5);                // Set P1.0 and P1.5 SEL as Input
        P1IFG &= (~BIT0 + BIT5);                // Clear interrupt flag for P1.5
...

 

To me this feels like it will be performing function A. Which results in an overflow. Is this your intent?


A. (~BIT0 + BIT5) == (~0x01 + 0x20) == (0xFE + 0x20) == (0x11E) == 0x1E <- After it's put into a 8bit register

B. ~(BIT0 + BIT5) == ~(0x01 + 0x20) == ~(0x21) == 0xDE

Doesn't look related to your issue. But still looks like a bug.

Link to post
Share on other sites

I'm curious about this snippet of code. Your use of brackets is confusing to me. Particularly these 3 lines.

 

 

To me this feels like it will be performing function A. Which results in an overflow. Is this your intent?


A. (~BIT0 + BIT5) == (~0x01 + 0x20) == (0xFE + 0x20) == (0x11E) == 0x1E <- After it's put into a 8bit register

B. ~(BIT0 + BIT5) == ~(0x01 + 0x20) == ~(0x21) == 0xDE

Doesn't look related to your issue. But still looks like a bug.

Yeah that was wrong. I fixed that earlier.

Link to post
Share on other sites

@@greeeg

 

My fix was actually slightly different though. I mention this in case it may help new players understand things better. I keep the ~ bit operator inside of brackets for the sake of operator seperation. Like so.

        P1SEL &= (~BIT0) + (~BIT5);             // Set P1.0 and P1.5 SEL as GPIO
        P1DIR &= (~BIT0) + (~BIT5);             // Set P1.0 and P1.5 SEL as Input
        P1IES |= BIT0 + BIT5;                   // Falling Edge 1 -> 0
        P1IFG &= (~BIT0) + (~BIT5);             // Clear interrupt flag for P1.5
        P1IE |=  BIT0 + BIT5;                   // Enable interrupt for P1.5
Link to post
Share on other sites

 

@@greeeg

 

My fix was actually slightly different though. I mention this in case it may help new players understand things better. I keep the ~ bit operator inside of brackets for the sake of operator seperation. Like so.

        P1SEL &= (~BIT0) + (~BIT5);             // Set P1.0 and P1.5 SEL as GPIO
        P1DIR &= (~BIT0) + (~BIT5);             // Set P1.0 and P1.5 SEL as Input
        P1IES |= BIT0 + BIT5;                   // Falling Edge 1 -> 0
        P1IFG &= (~BIT0) + (~BIT5);             // Clear interrupt flag for P1.5
        P1IE |=  BIT0 + BIT5;                   // Enable interrupt for P1.5

 

Isn't this still producing the wrong result??

 

After negating , if you add you'll get an overflow....

(~BIT0) + (~BIT5) == (~0x01) + (~0x20) == (0xFE) + (0xDF) == (0x1DD)

If you insist on negating within brackets then you should be using AND operations to receive the required result, not ADD.

(~BIT0) & (~BIT5) == (~0x01) & (~0x20) == (0xFE) & (0xDF) == (0xDE)
Link to post
Share on other sites

 

Isn't this still producing the wrong result??

 

After negating , if you add you'll get an overflow....

(~BIT0) + (~BIT5) == (~0x01) + (~0x20) == (0xFE) + (0xDF) == (0x1DD)

If you insist on negating within brackets then you should be using AND operations to receive the required result, not ADD.

(~BIT0) & (~BIT5) == (~0x01) & (~0x20) == (0xFE) & (0xDF) == (0xDE)

According to my calculator. Your example, and mine both are wrong. Except while my way while wrong still overflows while giving me BIT0 set to 1. -34 versus -35 in decimal.

 

Either way, I think I'm done trying to configure bits as such. And I'll start using hard coded values i know are correct. LOGICAL BITWISE OR, also overflows ( - 1 ).

Link to post
Share on other sites


"use strict";

 

(function() {

        var BIT0 = 0x0001;

        var BIT5 = 0x0020;

 

        var test = (~BIT0) & (~BIT5);

 

        process.stdout.write(test + '\n');

 

})();

 

william@beaglebone:~/dev/javascript$ node wd.js

-34


"use strict";

 

(function() {

        var BIT0 = 0x0001;

        var BIT5 = 0x0020;

 

        var test = (~BIT0) + (~BIT5);

 

        process.stdout.write(test + '\n');

 

})();

 

william@beaglebone:~/dev/javascript$ node wd.js

-35


"use strict";

 

(function() {

        var BIT0 = 0x0001;

        var BIT5 = 0x0020;

 

        var test = (~BIT0) + (~BIT5);

 

        process.stdout.write(test.toString(2) + '\n');

 

})();

 

william@beaglebone:~/dev/javascript$ node wd.js

-100011

Link to post
Share on other sites

The best interactive calculator to do architecture specific math is gdb.  For example:
 

$ msp430-elf-gdb -q
(gdb) set $BIT0=(1<<0)
(gdb) set $BIT5=(1<<5)
(gdb) print/x (~$BIT0) + (~$BIT5)
$1 = 0xffdd
(gdb) p/t (unsigned char)0xffdd
$12 = 11011101
(gdb) p/t (unsigned char)~0xffdd
$11 = 100010

 
In the msp430-elf-gdb session above I created a couple of convience variables ($BIT0 and $BIT5). You could also just use (1<<n) for any BITN.  The print command will output decimal by default. However, you can change the base by providing  /x (hex), or  /d (decimal), or /t (binary).  To perform any calculation you just just type the c code. (~(1<<0) + ~(1<<5) and you get the result.
 
So the result using incorrect bit flipping is 0xFFDE. However, P1DIR is only 8 bits on the msp430g2553 so it only uses the LSB (0xDE). However that result is wrong. That would targeting BIT1 instead of BIT0
 
You want to add all the BITs together before flipping them

$ msp430-elf-gdb -q
(gdb) set $BIT0=(1<<0)
(gdb) set $BIT5=(1<<5)
(gdb) print/x ~($BIT0|$BIT5)         
$2 = 0xffde
(gdb) print/x (unsigned char)0xffde
$3 = 0xde
(gdb) print/t (unsigned char)0xffde
$4 = 11011110
(gdb) print/t (unsigned char)~0xffde
$5 = 100001

So the right answer is 0xFFDE which turns out to be just 0xDE when used to set P1DIR.

 

Using the print/t binary output you can easily see which bits are on and which bits are off. (BIT5 and BIT0) 0b100001

 

You also have to remember that any number that isn't qualified in code with a size is going to default to size of int. If I run this code using the gdb that comes with my linux 64 bit machine. You see it defaults to the x86 normal size int.  In the case below it becomes 0xffffffde

$ gdb -q
(gdb) p/x ~((1<<0)|(1<<5))
$1 = 0xffffffde
(gdb)

Using the architecture specifc gdb, makes a handy bit and hex calculator that you can just type into.

 

-rick

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...