Pasting Macros

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've messed with this for more time than I care to admit and am still unable to get the desired result.  What I would like to do is define a macro that contains the name of a USART and define macros that will expand to the various interrupt vector names.

 

// I want to do something like this
#define MY_USART        USARTC0
#define DRE_VECT(u)     u##_DRE_vect
#define RXC_VECT(u)     u##_RXC_vect
#define TXC_VECT(u)     u##_TXC_vect

// so I can do this:
ISR(DRE_VECT(MY_USART))
{
    // ISR code
}

// and have it expand to this:
ISR(USARTC0_DRE_vect)
{
    // ISR code
}

// I've tried using the ASF token paste macro:
#define TPASTE2(a, b)   a##b

// and absolute token paste macro:
#define ATPASTE2(a, b)  TPASTE2(a, b)

What am I missing?

 

This topic has a solution.

Greg Muth

Portland, OR, US

Xplained/Pro/Mini Boards mostly

 

Make Xmega Great Again!

 

Last Edited: Wed. Nov 18, 2015 - 01:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

You define the concatenation macros but then never use them, why?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have used the *PASTE2 macros in every combination I can think of and have still not got the desired result.  I'm just not getting it.  HELP!

Greg Muth

Portland, OR, US

Xplained/Pro/Mini Boards mostly

 

Make Xmega Great Again!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html

 

#include <avr/io.h>
#include <avr/interrupt.h>

#define CONCATENATE(a, b) CONCATENATE_(a, b)
#define CONCATENATE_(a, b) a ## b

// I want to do something like this
#define MY_USART        USARTC0
#define DRE_VECT(u)     CONCATENATE(u, _DRE_vect)
#define RXC_VECT(u)     CONCATENATE(u, _RXC_vect)
#define TXC_VECT(u)     CONCATENATE(u, _TXC_vect)

// so I can do this:
ISR(DRE_VECT(MY_USART))
{
    // ISR code
}

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was helped here with exactly the same situation--making "generic" RS485 USART drivers, applicable to different USART instances and pin configurations (and buffer sizes). See the link below for full macro setup:

https://www.avrfreaks.net/comment...

 

david.prentice provided the MKPORT() which I adapted:

https://www.avrfreaks.net/forum/g...

 

An example of a macroed-up ISR in CodeVision-speak:

// UART Transmitter interrupt service routine
interrupt [VECT_TXC] void 	uart_tx_isr			(void)
{
if (tx_ctr)
   {
   RS485_TE();	// ensure that the MAX485 is transmit-enabled
   --tx_ctr;
   URD = tx_buffer[tx_rd_index];
   if (++tx_rd_index >= TX_BUFFER_SIZE) tx_rd_index=0;
   }
else
	{
	//  Use MPCM to wait for our address

	URA |= MPCM_MODE;

	RS485_RE();	// switch the MAX485 to receive mode
	}

}

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I do this:

 

92  #define MY_USART			USARTD0
93  #define CONCATENATE_(a, b)	a ## b
94  #define CONCATENATE(a, b)	CONCATENATE_(a, b)
95  #define DRE_VECT(u)			CONCATENATE(u, _DRE_vect)
96  #define RXC_VECT(u)			CONCATENATE(u, _RXC_vect)
97  #define TXC_VECT(u)			CONCATENATE(u, _TXC_vect)
98
99 ISR(DRE_VECT(MY_USART))
100 //ISR(USARTD0_DRE_vect)
101 {
    

The result is this:

Severity    Code    Description    Project    File    Line
Message        in expansion of macro 'MY_USART'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Error        pasting ")" and "_DRE_vect" does not give a valid preprocessing token    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    92
Error        expected ')' before '*' token    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    92
Error        expected ')' before numeric constant    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    92
Error        expected ')' before '*' token    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    92
Error        expected ')' before numeric constant    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    92
Message        in definition of macro 'CONCATENATE_'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    93
Message        in expansion of macro 'CONCATENATE_'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    94
Message        in expansion of macro 'CONCATENATE_'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    94
Message        in expansion of macro 'CONCATENATE_'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    94
Message        in expansion of macro 'CONCATENATE_'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    94
Message        in expansion of macro 'CONCATENATE'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    95
Message        in expansion of macro 'CONCATENATE'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    95
Message        in expansion of macro 'CONCATENATE'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    95
Message        in expansion of macro 'CONCATENATE'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    95
Message        in expansion of macro 'CONCATENATE'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    95
Message        in expansion of macro 'DRE_VECT'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Message        in expansion of macro 'DRE_VECT'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Message        in expansion of macro 'DRE_VECT'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Message        in expansion of macro 'DRE_VECT'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Message        in expansion of macro 'DRE_VECT'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Message        in expansion of macro 'MY_USART'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Message        in expansion of macro 'MY_USART'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Message        in expansion of macro 'MY_USART'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100
Message        in expansion of macro 'MY_USART'    XE5X non-ASF    C:\Users\Greg\Documents\Atmel Studio\7.0\XE5X non-ASF\XE5X non-ASF\src\cons.c    100

 

Greg Muth

Portland, OR, US

Xplained/Pro/Mini Boards mostly

 

Make Xmega Great Again!

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DOH!!!

 

This explains a lot (from iox32e5.h):

#define USARTD0 (*(USART_t *) 0x09C0) 

This works as desired:

#define CONCAT2_(a, b)		a ## b
#define CONCAT2(a, b)		CONCAT2_(a, b)
#define CONCAT3_(a, b, c)	a ## b ## c
#define CONCAT3(a, b, c)	CONCAT3_(a, b, c)

#define CONS_USART		D0
#define USART(u)		CONCAT2(USART, u)
#define DRE_VECT(u)		CONCAT3(USART, u, _DRE_vect)
#define RXC_VECT(u)		CONCAT3(USART, u, _RXC_vect)
#define TXC_VECT(u)		CONCAT3(USART, u, _TXC_vect)

ISR(RXC_VECT(CONS_USART))
{

    char c = USART(CONS_USART).DATA;
    .
    .
    .
    .
    .

}

 

Thanks for the help everyone!

 

blush

Greg Muth

Portland, OR, US

Xplained/Pro/Mini Boards mostly

 

Make Xmega Great Again!

 

Last Edited: Wed. Nov 18, 2015 - 01:57 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I hadn't recognised that you were working with Xmega, and that USARTC0 was a macro already defined by the device header.  The example I gave will work only if MY_USART is defined as something which does not itself expand, such as USART0 or USART1 in, for example, an ATmega2560.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didn't realize USARTC0 was a macro either, although the UPPERCASE name should have tipped me off.  As it turns out, that was the source of my problems.

 

Thanks for your help!

Greg Muth

Portland, OR, US

Xplained/Pro/Mini Boards mostly

 

Make Xmega Great Again!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My point was that in the mega/tiny families there is no such macro.  For example, the m1284p has two USARTs, >>referred<< to as USART0 and USART1, but there are no macros by those names.  The only macros which include those characters are the names of the interrupt vectors:

USART0_RX_vect
USART0_UDRE_vect
USART0_TX_vect
USART1_RX_vect
USART1_UDRE_vect
USART1_TX_vect

 

Your use of a macro called MY_USART and defined as USART0 or USART1 would work because there would be no further to expand.  In the case of the Xmega, those are actual macros, defined as structs living at the perpheral's base I/O address.  Since the concatenation macros are constructed such that the arguments are fully expanded before concatenation, this would fail.  Your solution seems a reasonable compromise.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Greg_Muth, you might be interested by HWA.

 

HWA : hardware abstraction for micro controllers, in pure standard C, without penalties.