Search code examples
cmacrosargumentsexpected-exception

C macro not working as expected


I am trying to adapt some code I have downloaded from here (supposedly correct) for making it work with my setup and CPU, but my compiler doesn't seem happy with it. I am using Keil v5 with an nrf51422 (Cortex M0 core), the code I have downloaded should be optimized for IAR.

I have a header file dap.h in which some macros for setting/clearing pins are declared:

#define SWDIO_SET_INPUT() NRF_GPIO->DIRCLR = (1 << SWDIO_PIN)
#define SWDIO_SET_OUTPUT() NRF_GPIO->DIRSET = (1 << SWDIO_PIN)

#define SWDIO_SET() NRF_GPIO->OUTSET = (1 << SWDIO_PIN)
#define SWDIO_CLR() NRF_GPIO->OUTCLR = (1 << SWDIO_PIN)
#define SWCLK_SET() NRF_GPIO->OUTSET = (1 << SWCLK_PIN)
#define SWCLK_CLR() NRF_GPIO->OUTCLR = (1 << SWCLK_PIN)

#define SWDIO_OUT(bit) {if ( bit ) SWDIO_SET(); else SWDIO_CLR();}
#define SWDIO_IN() (NRF_GPIO->IN >> SWDIO_PIN) & 0x1)

#define SWCLK_CYCLE()   \
  SWCLK_CLR();          \
  SWCLK_SET()

#define SWDIO_CYCLE()   \
  SWDIO_SET();          \
  SWDIO_CLR()

#define WRITE_BIT(bit)  \
  SWDIO_OUT(bit);        \
  SWCLK_CLR();          \
  SWCLK_SET()          

#define READ_BIT(bit)   \
  SWCLK_CLR();          \
  bit = SWDIO_IN();     \
  SWCLK_SET()

Then I have the file dap.c, which includes dap.h, which calls the macros:

 /* Send request */
  WRITE_BIT(1);
  WRITE_BIT(_ap);
  WRITE_BIT(_read);
  WRITE_BIT(A2);
  WRITE_BIT(A3);
  WRITE_BIT(parity);
  WRITE_BIT(0);
  WRITE_BIT(1);

  /* Turnaround */
  SWDIO_SET_INPUT();
  SWCLK_CYCLE();

  /* Read ACK */
  for ( i=0; i<3; i++ ) {
    READ_BIT(b);
    ack |= b << i;
  }

  /* Verify that ACK is OK */
  if ( ack == ACK_OK ) {

    for ( i=0; i<32; i++ ) 
    {
      /* Read bit */
      READ_BIT(b);
      *data |= b << i;

      /* Keep track of expected parity */
      if ( b ) cb = !cb;
    }

    /* Read parity bit */
    READ_BIT(parity);

At compile time, every instance of READ_BIT(b) generates the error

error: 65:  expected a ";"

If I pass over with the mouse a pop-up message tells me "error: extraneous ')' before ';'". The semicolons in the macros seem ok to me, and the WRITE_BIT(bit) is compiled without trouble.

Using a macro with an argument for returning a value seems a little weird to me, I could easily convert them in functions, but maybe there's another reason for that and it's worth to learn it.


Solution

  • There are unbalanced parentheses in the macro:

    #define SWDIO_IN() (NRF_GPIO->IN >> SWDIO_PIN) & 0x1)
    

    Presumably, you need a second open parenthesis at the start.