Compiler error expanding macro ENABLE

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

Hello,

 

I am using Atmel Studio and the samd21 explained board to try and build a state machine for class. I am using ASF, but I haven't added any additional modules to the project.

 

I know I can use the form [peripheral]->something.something.bit.something to access specific registers or bits, like the count registers for a timer. 

 

For example:

 

TC3->COUNT16.COUNT.reg = 0;

but how come when I try to use this with the enable bit on TC3 I get a compiler error? The code I was trying looked like this:

 

TC3->COUNT16.CTRLA.bit.ENABLE == false;

The error I get is "expected identifier before numeric constant in expansion of macro 'ENABLE';

 

I understand that  I can just set the bit using 

 

REG_TC3_CTRLA &= ~TC_CTRLA_ENABLE;

 

I guess I'm just curious, since I feel the first method is easier to read than the one I ended up using. The class I'm taking is using the MSP430, but I'm trying to reproduce all the projects on the xplained board to teach myself ARM.

This topic has a solution.
Last Edited: Sun. Apr 8, 2018 - 03:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cbc02009 wrote:
how come when I try to use this with the enable bit on TC3 I get a compiler error?

Look at the definition of ENABLE.

 

Does that make sense when expanded in

TC3->COUNT16.CTRLA.bit.ENABLE == false;

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

cbc02009 wrote:
how come when I try to use this with the enable bit on TC3 I get a compiler error?

Look at the definition of ENABLE.

 

Does that make sense when expanded in

TC3->COUNT16.CTRLA.bit.ENABLE == false;

 

Hi awneil, 

 

Thanks for replying. I asked my professor about it, since it's clear I didn't know enough to even understand how to ask what I want to know, so please let me rephrase the question. Enable is defined in compiler.h as 1, but it is also defined in TC.h as a uint_16 within the structure TC_CTRLA_type. How does the compiler decide which definition of ENABLE to use? Why does it pick the one in compiler.h over the one that is directly related to the structure I'm trying to access? Is there a way to change this behavior without renaming ENABLE in TC_CTRLA_type? Also, I should note that in my code I have:

 

#define false 0
#define true  1

so if the compiler was using the definition of ENABLE that I would like it to, the above statement 

TC3->COUNT16.CTRLA.bit.ENABLE == false;

 

should be syntactically correct, to the best of my knowledge.

 

again, thank you for your response. If you need any additional information please let me know. I'm really enjoying trying to figure all this stuff out.

Last Edited: Thu. Apr 5, 2018 - 12:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is really rather obvious.  Do you know what = and == mean, what they do, how, and when they are used?  Time to brush up on your basic knowledge of C.

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

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

larryvc wrote:

It is really rather obvious.  Do you know what = and == mean, what they do, how, and when they are used?  Time to brush up on your basic knowledge of C.

 

I'm sorry, I don't see how the difference between = and == matters to the question at hand. I use 

while (TC3->COUNT16.STATUS.bit.SYNCBUSY == 1){} //wait for TC3 to be enabled

to check to see if the timer-counter is done being written to, and I'm trying to understand why I can't use the same syntax to see if the counter is enabled or not, such as

if(TC3->COUNT16.CTRLA.bit.ENABLE == false){
    start_tc3();
}

 

or, even if, as you suggest, that I had made a typo when writing the code to the forum post, I should still be able to use 

TC3->COUNT16.CTRLA.bit.ENABLE = false;

to turn off the timer, right? which is why I don't see how = and == make any difference to my question.

Last Edited: Wed. Apr 4, 2018 - 10:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Enable is defined in compiler.h as 1, but it is also defined in TC.h as a uint_16 within the structure TC_CTRLA_type. How does the compiler decide which definition of ENABLE to use?

 

That's very unfortunate.

The #define in compiler.h will be executed by the C pre-processer (and thus the ENABLE in your source is changed to "1"), long before the compiler gets around to even looking at structure definitions.

What is compiler.h used for?  (And where does it come from?)  The one I found in my toolchain(s) seemed specific to an arduino bootloader, but I may be a couple of versions behind.

If the includes are distinct in your source, you could do something like:

#include <compiler.h>
#undef ENABLE
#undef DISABLE
#include <sam.h>

 

Hmm.  I'm not quite sure how you wouldn't get an error in TC.h, long before you actually USE "ENABLE" in this scenario.  So maybe I've got it wrong.

Or... If the include files are the other way around, I guess you should be able to do the #undef anytime before you actually use ENABLE in your code.

 

Last Edited: Thu. Apr 5, 2018 - 01:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cbc02009 wrote:

larryvc wrote:

 

It is really rather obvious.  Do you know what = and == mean, what they do, how, and when they are used?  Time to brush up on your basic knowledge of C.

 

I'm sorry, I don't see how the difference between = and == matters to the question at hand. I use

If that is the case, then why the hell didn't you post how you were using it in the first place instead of wasting our time with your imaginary code that you showed us in your first post!

 

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Thu. Apr 5, 2018 - 06:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

Enable is defined in compiler.h as 1, but it is also defined in TC.h as a uint_16 within the structure TC_CTRLA_type. How does the compiler decide which definition of ENABLE to use?

 

That's very unfortunate.

The #define in compiler.h will be executed by the C pre-processer (and thus the ENABLE in your source is changed to "1"), long before the compiler gets around to even looking at structure definitions.

What is compiler.h used for?  (And where does it come from?)  The one I found in my toolchain(s) seemed specific to an arduino bootloader, but I may be a couple of versions behind.

If the includes are distinct in your source, you could do something like:

#include <compiler.h>
#undef ENABLE
#undef DISABLE
#include <sam.h>

 

Hmm.  I'm not quite sure how you wouldn't get an error in TC.h, long before you actually USE "ENABLE" in this scenario.  So maybe I've got it wrong.

Or... If the include files are the other way around, I guess you should be able to do the #undef anytime before you actually use ENABLE in your code.

 

 

Thank you for your reply. Last night i used 

TC3->COUNT16.CTRLA.bit.ENABLE = true

in a blank project and it compiled just fine, so the issue must be with ASF, correct?

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

larryvc wrote:

cbc02009 wrote:

larryvc wrote:

 

It is really rather obvious.  Do you know what = and == mean, what they do, how, and when they are used?  Time to brush up on your basic knowledge of C.

 

I'm sorry, I don't see how the difference between = and == matters to the question at hand. I use

If that is the case, then why the hell didn't you post how you were using it in the first place instead of wasting our time with your imaginary code that you showed us in your first post!

 

 

I'm sorry, you're right. I should have posted the context my code was in, and I did get myself mixed up between the two examples in my first post. I thought I was much clearer what I was looking for help with in my second post, since I had a little more background to explain what I was looking for.

 

I am creating a state machine that reads out of a ring buffer, and once it verifies it's gotten the correct sequence (using a checksum) it waits in that state for about a second before outputting that data to a final destination.

 

Here's the code I was trying to use the statement in: 

	case DATA_WRITE:
		
		if(TC3->COUNT16.CTRLA.bit.ENABLE == false) {
		    REG_TC3_CTRLA |= TC_CTRLA_ENABLE; //turn on delay timer only if 
		}                                     //it's not already on
		
		if (receive_delay_FLAG) {
			
			finalbyte1 = tempbyte1;
			finalbyte2 = tempbyte2;
			finalbyte3 = tempbyte3;
			finalbyte4 = tempbyte4;
			
			REG_TC3_CTRLA &= ~TC_CTRLA_ENABLE; //disable timer
			while(TC3->COUNT16.STATUS.bit.SYNCBUSY == 1) {} //can't change TC until it's done syncing
			receive_delay_FLAG = 0;
			
			Rx_state = SOM;
		}
		else {
			Rx_state = DATA_WRITE;

 

receive_delay_FLAG comes from the MC0 interrupt for TC3: 

void TC3_Handler() {
	if(TC3->COUNT16.INTFLAG.bit.MC0 == 1) {
		receive_delay_FLAG = true;
		REG_TC3_INTFLAG = TC_INTFLAG_MC0;
		TC3->COUNT16.COUNT.bit.COUNT = 0;
	}
}

 

Again, thank you for your patience.

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

I liked larryvc's answers. It reminds me of a comment by a former colleague, who was also a part time Computer Science lecturer. He said some of his students felt themselves to be qualified to study computer science because they could push a mouse

Jerry

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

Okay westfw actually caught what is happening, sorry I did not see his post before, your statements are fine, the problem is definitely with compiler.h.  Can you post that header file here.  Also please explain when and why that file is used, is it required?

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

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

larryvc wrote:

Okay westfw actually caught what is happening, sorry I did not see his post before, your statements are fine, the problem is definitely with compiler.h.  Can you post that header file here.  Also please explain when and why that file is used, is it required?

 

Thank you! compiler.h seems to be a part of ASF (though I don't really know what it does), as it's called (is that the right term?) in asf.h:


#ifndef ASF_H
#define ASF_H

/*
 * This file includes all API header files for the selected drivers from ASF.
 * Note: There might be duplicate includes required by more than one driver.
 *
 * The file is automatically generated and will be re-written when
 * running the ASF driver selector tool. Any changes will be discarded.
 */

// From module: Common SAM0 compiler driver
#include <compiler.h>
#include <status_codes.h>

// From module: Generic board support
#include <board.h>

// From module: Interrupt management - SAM implementation
#include <interrupt.h>

// From module: PORT - GPIO Pin Control
#include <port.h>

// From module: Part identification macros
#include <parts.h>

// From module: SYSTEM - Clock Management for SAMD21/R21/DA/HA
#include <clock.h>
#include <gclk.h>

// From module: SYSTEM - Core System Driver
#include <system.h>

// From module: SYSTEM - I/O Pin Multiplexer
#include <pinmux.h>

// From module: SYSTEM - Interrupt Driver
#include <system_interrupt.h>

// From module: SYSTEM - Power Management for SAM D20/D21/R21/D09/D10/D11/DA/HA
#include <power.h>

// From module: SYSTEM - Reset Management for SAM D20/D21/R21/D09/D10/D11/DA/HA
#include <reset.h>

// From module: WDT - Watchdog Timer (Callback APIs)
#include <wdt.h>
#include <wdt_callback.h>

#endif // ASF_H

 

compiler.h is over 1000 lines long, so i'm adding it as an attachment instead of putting it in the post. ENABLE is defined on line 366.

 

If it's any help, the file is located in the project directory under /project_directory/src/ASF/sam0/utils/compiler.h.

Attachment(s): 

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

This is a huge mistake on the part of the ASF team to define these in compiler.h and a support ticket should be written based on my findings below.

/** \name Usual Constants
 * @{ */
#define DISABLE   0
#define ENABLE    1

I built an ASF test program for the SAM D21 Xplained Pro using ASF 3.38.0 and searched for ENABLE and DISABLE actually being used as a constant in any Solution files, including all of the ASF dependency files. DISABLE is not used anywhere, ENABLE is not used anywhere other than as a bit position in structures.  They should be removed from compiler.h.

 

As a workaround add westfw's suggested fix of

#undef ENABLE
#undef DISABLE

after the #include <asf.h> in your code or immediately after the #include <compiler.h> in asf.h.

 

A better option that I have found is that ASF4 in START does not have this problem, you may want to give it a try instead.  I have had very good project results with START and ARM.

 

Good luck!
 

 

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Fri. Apr 6, 2018 - 07:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

larryvc wrote:

This is a huge mistake on the part of the ASF team to define these in compiler.h and a support ticket should be written based on my findings below.

/** \name Usual Constants
 * @{ */
#define DISABLE   0
#define ENABLE    1

I built an ASF test program for the SAM D21 Xplained Pro using ASF 3.38.0 and searched for ENABLE and DISABLE actually being used as a constant in any Solution files, including all of the ASF dependency files. DISABLE is not used anywhere, ENABLE is not used anywhere other than as a bit position in structures.  They should be removed from compiler.h.

 

As a workaround add westfw's suggested fix of

#undef ENABLE
#undef DISABLE

after the #include <asf.h> in your code or immediately after the #include <compiler.h> in asf.h.

 

A better option that I have found is that ASF4 in START does not have this problem, you may want to give it a try instead.  I have had very good project results with START and ARM.

 

Good luck!
 

 

 

I will give both of both of those a try. Thank you so much for your help!

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

larryvc wrote:

This is a huge mistake on the part of the ASF team to define these in compiler.h and a support ticket should be written based on my findings below.

/** \name Usual Constants
 * @{ */
#define DISABLE   0
#define ENABLE    1

I built an ASF test program for the SAM D21 Xplained Pro using ASF 3.38.0 and searched for ENABLE and DISABLE actually being used as a constant in any Solution files, including all of the ASF dependency files. DISABLE is not used anywhere, ENABLE is not used anywhere other than as a bit position in structures.  They should be removed from compiler.h.

 

As a workaround add westfw's suggested fix of

#undef ENABLE
#undef DISABLE

after the #include <asf.h> in your code or immediately after the #include <compiler.h> in asf.h.

 

A better option that I have found is that ASF4 in START does not have this problem, you may want to give it a try instead.  I have had very good project results with START and ARM.

 

Good luck!
 

 

 

So after looking at START, it is well beyond my current understanding of pretty much everything. The #undef solution works very well though.