Jump to content

gpio interrupts

Recommended Posts

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)
$1 = 0xffdd
(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

Using the specific gdb for the architecture you are using make a handy bit and hex calculator that you can just type into.



cool use case for gdb Rick ! I still prefer javascript though . . . toString(base) is pretty handy.

Link to post
Share on other sites

The problem with using javascript it it doesn't know that your target environment is limited to 16 bit.  Try a different example, add 0xffff + 0x0001 .. 

$ cat testme.js 
"use strict";

(function() {
        var BIT0 = 0x0001;
        var BIT5 = 0xffff;

        var test = (BIT0) + (BIT5);

        process.stdout.write('0x' +test.toString(16) + '\n');

$ node testme.js 

Now try it with msp430-elf-gdb:

$ msp430-elf-gdb -q
(gdb) print/x 0xffff+0x0001
$1 = 0x0

So the answer with javascript is '0x10000' and the answer with msp430-elf-gdb is '0'. However for the msp430g2553 0 is the right answer.


msp430-elf-gdb knows about C math and it knows about the size of integers on an msp430. Which when you start moving up the chain of msp430 parts it changes. The results also change depending on which compiler mode you are using, 16 bit for small model and 20 bits for large. 


As long as you keep in mind that you have to turn the javascript results into 16 bit math you will be ok. But it is yet another thing to remember.



Link to post
Share on other sites

More fun with gdb, try this with an MSP-EXP430G2 launchpad


o Open 2 xterm or 2 command windows that have msp430-elf-gdb and mspdebug in your path


o In the first xterm run: 

 $ mspdebug rf2500 'gdb'

o In the second xterm run an msp430-elf-gdb session

$ msp430-elf-gdb -q -ex 'target remote :2000' 
Remote debugging using :2000
0x0000ffff in ?? ()
(gdb) printf "create convenience variables\n"
create convenience variables
(gdb) set $P1OUT=(unsigned char *)0x21
(gdb) set $P1DIR=(unsigned char *)0x22
(gdb) printf "set all the P1 pins low\n"
set all the P1 pins low
(gdb) set *$P1OUT=0
(gdb) printf "set all the P1 pins into output\n"
set all the P1 pins into output
(gdb) set *$P1DIR=0xff
(gdb) printf "TURN on both LED pins (BIT0 and BIT6)\n"           
TURN on both LED pins (BIT0 and BIT6)
(gdb) set *$P1OUT=((1<<0)|(1<<6))       
(gdb) printf "TURN off the RED LED pin\n" 
TURN off the RED LED pin
(gdb) set *$P1OUT=~((1<<0))              
(gdb) printf "TURN on the RED LED and turn off the GREEN LED pin\n"
TURN on the RED LED and turn off the GREEN LED pin
(gdb) set *$P1OUT=((1<<0) | ~(1<<6))         
(gdb) quit 
msp430-elf-gdb lets you read and write the Special function varialbles that control the ports. Using it interactively like this I'm not sure we even need a programming language :) All you need is a connection to mspdebug through msp430-elf-gdb (CCS supplied) or msp430-gdb (Energia supplied)


Link to post
Share on other sites

The standard Windows calculator in Programmer mode (Alt+3) is quite handy too...

Yes, thats the calculator I use. So now, that I actually know what the registers do, I will start doing something like:


P1DIR = 0x21;


Instead of wracking my brain to try and remember everything while attempting to do binary in my head. When I should really be focusing on the program flow. In the past I just copied stuff I did not fully understand. But now that I've spent a good amount of time in the datasheet, I get "it".

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.

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...