bajtec
bajtec

Reputation: 155

Is there a way to define macro for pins in AVR gcc so i can access those as variables?

I'm trying to write definitions for AVR C code so that i can access pins by simmple macro like

STATUS_LED_OUT =1; 

in GENET_HW_DEF.h file, included to main C file. You can reproduce this bug by including this file into any C project. I'm using avr studio 6.2 and 7 - both give the same result. I cannot compile getting werid macro unfold message like below. (CPU ATMega1284p)

D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(19,49): error: expected ')' before '&' token
         #define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt
                                                         ^
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(42,25): info: in expansion of macro 'REGISTER_BIT'
          #define STATUS_LED_OUT REGISTER_BIT(PORTB,7)
                                 ^
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(46,2): info: in expansion of macro 'STATUS_LED_OUT'
          STATUS_LED_OUT=1;
          ^

Interesting enough, copied to fresh project with just only one or two declarations compiles fine, until one makes any changes in the declarations - like adding another macro reference. Then it becomes stuck again.

Also - if i comment all macro usages like

STATUS_LED_DIR=1;
STATUS_LED_OUT=1; 

then I'm able to compile project and then after uncommenting usage lines it still compiles fine.. untill clean is executed. I'm probably messing with macro quirks but I have no idea where.

typedef struct
{
    unsigned int bit0:1;
    unsigned int bit1:1;
    unsigned int bit2:1;
    unsigned int bit3:1;
    unsigned int bit4:1;
    unsigned int bit5:1;
    unsigned int bit6:1;
    unsigned int bit7:1;
} _io_reg;

#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt

#ifndef GENET_HW_DEF
#define GENET_HW_DEF

// define functionalities and flags - comment/uncomment apropriate lines
#define GENET_USART_0 256
#define GENET_USART_1 256
#define F_CPU 20000000UL
#define STATUS_LED 7
#define ERROR_LED 4
#define ADC_GLOBAL_ENABLE A
#define ADC_CHANNEL_0 0
#define ADC_CHANNEL_1 4
#define ADC_CHANNEL_2 2
#define ADC_CHANNEL_3 3
#define ADC_CHANNEL_4 1
#define ADC_CHANNEL_5 5
#define ADC_CHANNEL_6 6
#define ADC_CHANNEL_7 7

// actual definitions and initialization
#ifdef STATUS_LED
    #define STATUS_LED_OUT REGISTER_BIT(PORTB,STATUS_LED)
    #define STATUS_LED_DIR REGISTER_BIT(DDRB,STATUS_LED)
    #define STATUS_LED_PIN REGISTER_BIT(PINB,STATUS_LED)
    STATUS_LED_DIR=1;
    STATUS_LED_OUT=1;
#endif

#ifdef ERROR_LED
    #define ERROR_LED_OUT REGISTER_BIT(PORTC,ERROR_LED)
    #define ERROR_LED_DIR REGISTER_BIT(DDRC,ERROR_LED)
    ERROR_LED_DIR=1;
    ERROR_LED_OUT=1;
#endif

#ifdef GENET_USART_0
    #define USART0_ENABLED
    #define UART_RX0_BUFFER_SIZE GENET_USART_0
    #define UART_TX0_BUFFER_SIZE GENET_USART_0
#endif

#ifdef GENET_USART_1
    #define USART1_ENABLED
    #define UART_RX1_BUFFER_SIZE GENET_USART_1
    #define UART_TX1_BUFFER_SIZE GENET_USART_1
#endif

#endif

Upvotes: 1

Views: 725

Answers (1)

Julien
Julien

Reputation: 1910

I reproduced your problem. You cannot call STATUS_LED_DIR=1; outside code execution flow. This must be inside a function (for example main()). Now you will end with other compilation errors but this was the main mistake.

Second correction, you need 2 level for concatenation

#define CONCAT(bt)  bit##bt 
#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->CONCAT(bt)

Upvotes: 1

Related Questions