This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Differences between "msp430.h" and "io430.h"?

Other Parts Discussed in Thread: MSP430F2274, MSP430F5529

Hi,

 

Which is better? Are you using msp430.h or io430.h?

 

10x

  • Hi BasePointer,

    these are generic header files. I always recomend using the device specific ones (i.e. in case of the MSP430F2274 use msp430f2274.h; in case of MSp430F5529 use msp430f5529.h, and so on).

    Nevertheless, you can use the genereic ones if you want too.

    Rgds
    aBUGSworstnightmare

  •  

    Well then my question is what are the differences between msp430f5529.h and io430f5529.h ?

  • I prefer "msp430.h" over "io430.h". But that is just personal preference. The one you prefer to use is the better one for you.

    BTW, aBUGSworstnightmare,

    "io430.h' and "msp430.h" are not generic header files. They automatically find the device specific header file that matches the target device you picked in the project.

    For example, you use "msp430.h" in your source code and set up the project with MSP430F2274 as the target. When you build, it will automatically use "MSP430F2274.h". And if you change the target to MSP430F5529 (without changing the include "msp430.h" in the source code), it will automatically use "MSP430F5529.h".

    Likewise, "io430.h" will automatically use "IO430x22x4.h" or "IO430x552x.h" respectively according to the target device in the project.

    Where as if you specify "MSP430F2274.h" in your source code but change to MSPF5529 as you target in the project, you will get no error or warning msg, but crazy object code.

     

     

  • old_cow_yellow said:

    "io430.h' and "msp430.h" are not generic header files. They automatically find the device specific header file that matches the target device you picked in the project.

    This is correct. About 6 months ago IAR did a release in which the msp430.h header file was changed to link to the specific header file of your processor. So a MSP430F5529 would link to msp430f5529.h instead of msp430f552x.h. So what it links to will depend on the version of IAR you are using.

     

    BasePointer said:
    Well then my question is what are the differences between msp430f5529.h and io430f5529.h ?

    The msp430*****.h files are the Texas Instruments version and the io430*****.h files are the IAR version according to IAR support. I don' t know exactly WHY there are two different versions, but my guess is its a legacy support issue. My guess is that they just make io430 to be equivalent to msp430, since that is the version made by TI.  IAR supports so many different processors and vendors I doubt they put much into the maintenance of the header files themselves. While they are supposed to be the same files, sometimes they differ. Because of this, I always prefer the msp430 variant.

    My stance is similar to aBUGSworstnightmare. I always copy the header file I need from the IAR library directory to my local directory and reference it specifically. Sometimes the header files have mistakes in them that need to be fixed. If you have to fix problems in the header file, it is better just to edit your local copy then to mess with the one in the library. If you screw up the library copy, you would have to reinstall IAR to get the correct copy!

    Before you start a new project you should always do a code diff between the two for the processor you are using. For example, if you are using a MSP430F5529, you would compare msp430F5529.h and io430f5529.h. You should also do a code diff whenever IAR releases a new update.

     

  • this is from msp430.h:

    /********************************************************************

    *

    * Standard register and bit definitions for the Texas Instruments

    * MSP430 microcontroller.

    *

    * This file supports assembler and C development for

    * MSP430x471x6 devices.

    *

    * Texas Instruments, Version 1.0

    *

    * Rev. 1.0, First Release

    *

    *

    ********************************************************************/

     

     

     

    and this is from io430.h:

    /********************************************************************

     *

     * Standard register and bit definitions for the Texas Instruments

     * MSP430 microcontroller.

     *

     * This file supports assembler and C/EC++ development for

     * MSP430x47x6 devices.

     *

     * Copyright (C) 1996-2009 IAR Systems AB.

     *

     * $Revision: 1.4

     ********************************************************************/

     

     

    io430.h header provides structural access to SFRs. For example, instead of masking I can directly set or reset ports with P5OUT_bit.P5OUT_0 = 1; Or I can use if(P5IN_bit.P5IN_0 == 1) ..

    I found io430.h is more readable, but I also faced some problem at compile time such as it says P5OUT_0 is not a member of structure when I try to use it. (not exactly for this register but for some others that I don’t remember now). Then I switched back to msp430.h.

     

    I wonder there is anyone who has used io430.h for a complete project?

     

    Regards,

    BP.

     

  • BP,

    What you said is part of the reason that I prefer msp430.h over io430.h

    Those "structural access" to individual bits looks "more readable", but sometimes generate very bad and inefficient object code. (The object code has to use mask -- that is, BIT, BIS or BIC instructions.) I choose to use something reliable and efficient over something that just looks "more readable". But as I said, this is only my personal preference. Both io430.h and mos430.h are there. What you prefer is the always better one for you.

    --OCY

  • Well, the includes are hierarchical.

    On the mspgcc compiler, you usually include io.h.
    Depending on the processor you selected in the project settings/makefile, io.h will include the proper MSP430Fxxx.h

    This allows writing of somewhat generic sourcecode (provided the hardware you address in it is the same) without the need of changing the include when the processor changes.

    Of course you can also directly include the proper MSP430Fxxx.h file.

    On IAR or CCS, maybe this global file is called msp430.h instead.

    Are there separate IO430fxxx.h files? Or rather: are there both types of files installed with your compiler? It would surprise me. if you mix compilers and their include paths, you may end up with both and probably none of them will actually work as expected. :)

     

  • Hi BasePointer,

    About two years ago I was on a similar decission point. io430.h and msp430.h do not fit together. You need to decide either io or msp.

    I decided for msp430.h and so far it went good. I even switched form IAR to CCE now CCS and still use msp430.h.

    Some nice things are that msp430.h (and its chain) defines the bit masks and you can create more readable code like:

    P1OUT |= BIT6; //set P1.6 true

    which is easier to read than:

    P1OUT |= 0x40; //set P1.6 true

    Regards

    Guenther

  • Hi,

    if you want to use macros to ease your programming you can simply define the standard bits and then define your macros for I/O or register access.

    // STANDARD BITS

    #define BIT0                   (0x0001)
    #define BIT1                   (0x0002)
    #define BIT2                   (0x0004)
    #define BIT3                   (0x0008)
    #define BIT4                   (0x0010)
    #define BIT5                   (0x0020)
    #define BIT6                   (0x0040)
    #define BIT7                   (0x0080)
    #define BIT8                   (0x0100)
    #define BIT9                   (0x0200)
    #define BITA                   (0x0400)
    #define BITB                   (0x0800)
    #define BITC                   (0x1000)
    #define BITD                   (0x2000)
    #define BITE                   (0x4000)
    #define BITF                   (0x8000)

    i.e. if you have a LED connected to Port P1.1 which you're using for visual status feedback you can now define your macros as:

    // LED_2
    // P1.1
    #define CONFIG_LED_2    P1DIR |= BIT1        // configures P1.1 for operation
                                                                               // P1.1 is switched to output mode, 1   

    #define LED_2_ON          P1OUT |= BIT1       // output HIGH --> switch on LED_2 (true)
    #define LED_2_OFF         P1OUT &= ~BIT1      // output LOW --> switch off LED_2 (false)
                                                                  
    #define LED_2_TOGGLE      P1OUT ^= BIT1       // toggles P1.1

    You don't need a specific header for that.

    You now use your macros for dealing with the I/O connected to LED_2, and the best of all: if you will have to use a different pin you only need to change your macros and not your entire code!

    Code snippet example:
    // configure LED_2
    CONFIG_LED_2;



    // switch LED_2 on
    LED_2_ON;

    // toggle state
    LED_2_TOGGLE;
    ...

    Rgds
    aBUGSworstnightmare

  • old_cow_yellow said:
    Those "structural access" to individual bits looks "more readable", but sometimes generate very bad and inefficient object code. (The object code has to use mask -- that is, BIT, BIS or BIC instructions.)

    Do you have some specific examples?  IMO, a compiler OUGHT to be able to generate identical code for either "REG |= BIT6;" or "REG.BIT6 = 1;"  I thought that MOST modern compilers had reached the point where there were very few "this obvious construct produces really inefficient code compared to this other syntax that does the same thing" (except perhaps for certain pathological architectures where a compiler writer has specifically optimized one syntax.)

     

  • westfw said:
    IMO, a compiler OUGHT to be able to generate identical code for either "REG |= BIT6;" or "REG.BIT6 = 1;" 

    For this example, it should.

    But

    REG|=BIT6|BIT5 is different from REG.BIT6=1;REG.BIT5=1; - the first one is a single instruction, the second one must be two write instructions because REG is volatile. The compiler cannot know that in his case teh two write can be grouped together.

  • io430.h seems to be IAR-only ?  I don't see it anywhere in my ccs4 install...

    That would seem to be a reason to prefer msp430.h to me.  Portability between different compilers is important.

     

  • westfw said:
    Portability between different compilers is important.

    This is very difficult.
    Every compiler for the MSP has some things which are not or not easily portable.
    Teh __delay_cycles() or __even_in_range() intrinsics ar enot available on mspgcc, the mspgcc has the excellent inline assembly support as well as the support for long long (64 bit) integers, the handling of interrupt funcitons is different (#pragma preprocessor commands on the IAR, __attribute__ function attributes on the mspgcc) and, and, and...

     plain C file is eaily compiled on all of them, but as soon as things are added which are somewhat outside the scope of the C language (such as dealing with status register bits such as GIE, defining interrupt functions etc.), there is not much portability. Even worse, things like the #pragma for interrupt functions cannot be made portable by defining proper header files, as preprocessor directives cannot be defined inside portability macros. They have to be placed into the source code directly.
    And intrinsics are often impossible to port.

  • Hi BP,

     

    I am trying to work out a simple example from Davis' book MCU basics.

     

    The program titled timrled1.c flashes the LEDs with a frequency of roughly 1 Hz by polling free-running.

     

    I understand the program as it is, but whenever I am trying to run it in CCS v4, the error is shown that the io430.h header is not known. After reading this post, I understand CCS does not have that header. I was wondering how would one rework the following code to fit in to msp header. The msp header recognizes everything but the structural reference. I tried to use the masking, but I get errors.

    #include <io430x11x1.h>        // Specific device

    // Pins for LEDs
    #define    LED1    BIT3
    #define    LED2    BIT4

    void main (void)
    {
        WDTCTL = WDTPW|WDTHOLD;                // Stop watchdog timer
        P2OUT = ~LED1;                        // Preload LED1 on, LED2 off
        P2DIR = LED1|LED2;                    // Set pins for LED1,2 to output
        TACTL = MC_2|ID_3|TASSEL_2|TACLR;    // Set up and start Timer A
    // Continuous up mode, divide clock by 8, clock from SMCLK, clear timer
        for (;;) {                            // Loop forever
            while (TACTL_bit.TAIFG == 0) {    // Wait for overflow
            }                                //   doing nothing
            TACTL_bit.TAIFG = 0;            // Clear overflow flag
            P2OUT ^= LED1|LED2;                // Toggle LEDs
        }                                    // Back around infinite loop
    }


  •         while ( (TACTL & TAIFG) == 0) {    // Wait for overflow
            }                                //   doing nothing
            TACTL &= ~TAIFG;            // Clear overflow flag

  • Hi OCY,

    Thanks for the reply. I am a newbie on the MCU world. It has been barely 3 weeks. Could you explain the code you wrote so that I can get a general sense?

    So, you changed the first instance with a mask and the AND operation (this is the bit operator, right?). I think I get that. But can you elaborate on the 2nd modification? It seems like you are resetting the Interrupt Flag (but negating it--so it was high initially?). Timers are really confusing to me. Hence, if you can direct me to a source, which is readable for a newbie, that will be awesome!

     

    Thanks again,

    UE

  • Also, does any know whether one can "import" the io430.h into Code Composer studio or if there is an equivalency chart to convert some codes written for the IAR to the CCS? Moreover, where can one download header files and add them to the current project? I wanted to add the header file to my current project and get around the coding issues, but was afraid whether calling both msp430.h and io430.h will cause some conflict.

     

    Thanks,

    UE

  • All the following statements mean the same thing.

    TACTL &= ~TAIFG;

    TACTL =  TACTL & ~TAIFG;

    TACTL =  TACTL & ~0x0001;

    TACTL =  TACTL & 0xFFFE;

    It clears BIT-0 (TAIFG) and leaves all other bits unchanged.

  • Thanks for the clarification. It makes more sense now. By "Leaving all other bits unchanged", you mean setting them as high, right? This is because, ~0x0001 would entail 0x1110--this will set the rest high, but clear the first bit.

  • Hello Upol,

    I realized that msp430.h and io430.h did not like each other. Some definitions use the same name.

    However as you have full source code you might transit io430.h code to CCS. In my mind it makes no sense as msp430.h contains all of io430.h (and has more features).

    One thing you should not forget in CCS (different to IAR): you need to define MCU type by hand e.g. __MSP340F2274__, prefereable in the project build properties:

    I'm transit from io430.h to msp430.h some years ago and didn't regret.

    Regards

    Guenther

  • Upol Ehs said:

    .... By "Leaving all other bits unchanged", you mean setting them as high, right? ...

    No. What I meant was:

    (a) If any of those other bits was a "1" before that statement is executed, it will still be "1" after that statement is executed.

    (b) If any of those other bits was a "0" before that statement is executed, it will still be "0" after that statement is executed.

    This is the nature of the "&" operator. It is a "bit by bit AND operation"

  •  

    Hi OCY,

     

    Thanks for keeping up with my questions.

    Oh I see. I guess I am a little confused now. I do not understand HEX pretty well so I will try a 8bit binary sequence.

     

    BIT0= 0b00000001

    ~BIT0= 0b11111110

    Does negating it flip all the other ones? OR did I understand it wrong? If my given scenario is the case, then how can negating the TAIF still leave the 0's as 0's and 1's as 1's?

  • Hello Guenther,

     

    Thanks for stopping by. I am trying to stick to the msp430x11x1.h as much as I can, but sometimes I feel the io430.h has some user-friendly features like the individual bit accessibility w/o masking.

     

    When you transitioned to msp430.h, how did you adjust to such changes. I am new to both C++ and CCS. Hence, it has been difficult for me to translate the syntax back and forth between the two programs.

    Thanks

    UE

  • Hello Guenther,

     

    Thanks for stopping by. I am trying to stick to the msp430x11x1.h as much as I can, but sometimes I feel the io430.h has some user-friendly features like the individual bit accessibility w/o masking.

     

    When you transitioned to msp430.h, how did you adjust to such changes. I am new to both C++ and CCS. Hence, it has been difficult for me to translate the syntax back and forth between the two programs.

    Thanks

    UE

  • Hi Upol,

    Yes, I adjusted my code a little bit. Using the bit structure is nice on single bit operation but creates overhead if you like to set multiple bits. It is even dangerous as the setting is split in multiple code lines as an interrupt may happen in between.

    Here some examples ( I hope I can do it as good as yellow cow ;-):

    io430.h: TACTL_bit.TAIFG = 0;

    msp430.h: TACTL &= ~TAIFG

    Both lines clear TAIFG bit only.

    If you need to do multiple bits then:

    io430.h:

      P1DIR_bit.p4 = 1;

      P1DIR_bit.p5 = 1;

    msp430.h

      P1DIR |= (BIT4 + BIT5);

     

    If you look on the disassembled code then the difference is even more obvious.

    An easy guide is:

    Clear:

    port &= ~(BITx + BITy + ...)

    Set:

    port |= (BITx + BITy + ...)

    Toggle:

    port ^= (BITx + BITy + ...)

    Query:

    if(port & BITx) ...

    Regards

    Guenther

  • Upol Ehs said:
    io430.h has some user-friendly features like the individual bit accessibility w/o masking

    THis convenience is paid for by getting slower and bigger code.
    If you only want to change a single bit/bitfield in  aregister, the result should be the same. However, you cannot group several bit manipulations to the same register. For the compiler, teh destination register is volatile, that means, for every appearance in teh source code there needs to be one access to the register.
    If you use the more generic bit masking method, you can group all accesses to the register into a single operation.

    Upol Ehs said:
    BIT0= 0b00000001
    ~BIT0= 0b11111110
    Does negating it flip all the other ones?


    Negating it fips ALL bits. It is an implicit exclusive-or operation with 0xffff.

    What you missed with the operation above was that there was an AND operation included.

    And AND keeps all bits set which are set in both parameters, and clear all bits which are clear in at least one of the two parameters. So & is used to clear bits. The inversion (it is not a negation, a negation is !x, which refers to the whole byte/word value and is either 0 or != 0) is required, as you need the bits set in the second parameter which shall stay unchanged in the first, and need the bits clear in teh second parameter which shall be cleared in the first (where 'first' and 'second' are exchangeable).

    That's the inversion of an OR operation ("|"), which sets (or keeps set) all bits which are set in one of the two and keeps clear which wasn't set in any of the two.

    See the logic table (for one bit, as the binary operations are bit by bit):

    X & 0 = 0 (AND operation)
    X & 1 = X
    X | 0 = X (OR operation)
    X | 1 = 1
    X ^ 0 = X
    X ^ 1 = 1-X (eXclusive OR operation = inversion)
    ~x == x ^ 1

     

  • Hi Guenther,

     

    Thanks a lot for the table. If you don't mind, I will copy and print out this format.

     

    UE

  • Upol Ehs said:
    If you don't mind, I will copy and print out this format.

    You'r ewelcome.

    Basically, it hasn't changed since the days of the very first TTL logic chips and can be found in any TTL book. However, it might prove difficult to find a TTL book today. :)

  • Hi Upol,
    You're welcome to do so. As Jens-Michael already said, old TTL stuff but always useful.
    Regards
    Guenther

**Attention** This is a public forum