# [SOLVED]Msp430-Problem with understanding the macros

Status
Not open for further replies.

#### lunatic_sh

##### Newbie level 1
(Not soved)Msp430-Problem with understanding the macros

I am working on MSP 430.
I am problem understanding following macros.

#define POUT_(Pn) Pn##OUT
#define IN_(p,b) (PIN_(p)&(1<<b))
#define USEIO_(p,b) unused_##p&=~(1<<(b))
#define USEIO(name) USEIO_(name)

How do these macros work and help in the code.

Last edited:

#### doraemon

##### Super Moderator
Staff member
Hello!

As for the first part of the question:
If you use A##B in a macro, then it will be translated to AB.
In this case, you have POUT_(Pn) defined as Pn##OUT
Then in your code, if you write POUT_(P1), it will be translated to P1OUT

Now at the second line, you define IN_(p, b) by PIN_( p ) but the problem is that PIN_( p ) is not defined. Well, I suppose that similarily PIN_(p ) is
probably defined as P##IN.

Next, at the 3 rd line, you use the term unused_ which is also not defined. USEIO_(1, 1) would give you unused_1 &= 0x02.
Or maybe unused_ is defined somewhere in the msp430 headers?

Now I think one should be careful with macros. It does not necessarily clarify
the code. For instance if you look at Windows programming interface, you may
find some "ATOM" types. Now ATOM is a WORD, WORD is an unsigned int.
What is the purpose of ATOM? Devil knows.

Back to MSP430. I don't think it will improve your code to write POUT_(P1) instead of P1OUT. One particular case where I use macros is to define
functions that are very recurrent. For instance, on a F5438 device, you can
have 8 different SPI ports. But their initialization is always the same:
- Perform the pin selection (PxSEL = 0xnn)
- Disable the device: UC(A|B)(0|1|2|3)CTL1 |= UCSWRST;
- Set UC..CTL0
- Set UC..CTL1
- Set bit rate
- Enable device UC(A|B)(0|1|2|3)CTL1 &= ~UCSWRST;

So you can declare everything in a macro, called DeclareSPIInit(AB, N0123)
and then instead of defining an init function (for example SPIA3Init), you
just say:
DeclareSPIInit(A, 3);

Then you have to do the same for all the functions like SPIA0SendByte,
SPIA0RecvByte, SPIA0SendBuffer, SPIA0RecvBuffer, SPIA0SetRate, etc…

If you want to fully define the functionality of a SPI port, then you will need
about 10 functions. But if you want to predefine all the ports by hand,
10 functions x 8 ports = 80 functions. Instead of that, you can fully define
the 10 functions of a port with a macro for each of the functions.
Now you can summarize the whole port definition like this:

#define USE_SPI(AB, which) \
DeclareSPIInit(AB, which); \
DeclareSPISendByte(AB, which); \
etc…
DeclareSPIRecvBuffer(AB, which)

Then you "instantiate" what you use by uncommenting the proper lines,
for instance A1 and B3 like this:

#USE_SPI(A, 0);
USE_SPI(A, 1);
#USE_SPI(A, 2);
#USE_SPI(A, 3);
#USE_SPI(B, 0);
#USE_SPI(B, 1);
#USE_SPI(B, 2);
USE_SPI(B, 3);

The advantage is that you will not compile anything for the unused ports,
and all the ports you need will be fully defined by simply removing a single
character (#).

Drawback: if you use macros heavily, it becomes more difficult to debug
step by step.

Dora.

lunatic_sh

### lunatic_sh

Points: 2
Status
Not open for further replies.