0

I cannot understand the macros logic and the way they work...so I can make a mcp2515_init() function. If someone can explain I would be glad to listen,thanks for your time.

#define true    1
#define false   0

#define True    1
#define False   0

typedef _Bool bool;



#define RESET(x)        _XRS(x)
#define SET(x)          _XS(x)
#define TOGGLE(x)       _XT(x)
#define SET_OUTPUT(x)   _XSO(x)
#define SET_INPUT(x)    _XSI(x)
#define IS_SET(x)       _XR(x)

#define PORT(x)         _port2(x)
#define DDR(x)          _ddr2(x)
#define PIN(x)          _pin2(x)

#define _XRS(x,y)   PORT(x) &= ~(1<<y)
#define _XS(x,y)    PORT(x) |= (1<<y)
#define _XT(x,y)    PORT(x) ^= (1<<y)

#define _XSO(x,y)   DDR(x) |= (1<<y)
#define _XSI(x,y)   DDR(x) &= ~(1<<y)

#define _XR(x,y)    ((PIN(x) & (1<<y)) != 0)

#define _port2(x)   PORT ## x
#define _ddr2(x)    DDR ## x
#define _pin2(x)    PIN ## x
Simson
  • 3,373
  • 2
  • 24
  • 38

1 Answers1

0

I will try to break it down, what you have is a set of bit manipulating macros flipping/setting/clearing one bit on a port they are a generic kind of macros and not specific to the SPI driver.

bit clear (reset)

#define _XRS(x,y)   PORT(x) &= ~(1<<y)

AND port with every bit expect bit y on port x.

bit set

#define _XS(x,y)    PORT(x) |= (1<<y)

OR port with only bit y set. This will set bit y and leave other unaffected.

toggle

#define _XT(x,y)    PORT(x) ^= (1<<y)

XOR a bit with 1 will toggle its value 0 will keep its state.

This list of macros only take one argument

#define RESET(x)        _XRS(x)
#define SET(x)          _XS(x)
#define TOGGLE(x)       _XT(x)
#define SET_OUTPUT(x)   _XSO(x)
#define SET_INPUT(x)    _XSI(x)
#define IS_SET(x)       _XR(x)

so these macros does not look compatible with the as they take one parameter instead of two, but with the magic of macros it is possible to create an output of x,y for instance

#define GPIO1_PIN4 1,4
#define POWER_LED GPIO0,PIN2

will make SET(POWER_LED); a legal assignment.

The # and ## macros

#define _port2(x)   PORT ## x

Are used to concatenate outputs from macros to create new structures read more here

So using all the macros _XT(2,15); will expand to

PORT2 = PORT2 ^ (1<<15)

I am personally not a fan of this kind of macros as it breaks how plain vanilla C works by hiding the assignments inside the macros, for instance this style cannot set multiple bits on the same port with single write. However it is legal C and it is common among some embedded systems development environments.

It would probably be easier to ignore the above macros and just write the configuration and data directly to the registers word by word.

Simson
  • 3,373
  • 2
  • 24
  • 38