ATmega328p - Expected unqualified-id before 'volatile'

414 Views Asked by At

I'm working on a custom bootloader for OTA updates for my ATmega328p. I'm taking help from the Optiboot bootloader's code from Arduino and for the USART part, I have written a custom header file for handling USART comm. part. Here's is the code (check code basically to test the logic)-

bootuart.h

#ifndef _BOOT_UART_H
    #define _BOOT_UART_H
#include <avr/io.h>

#if (SOFT_UART == 0)
  #if (UART == 0)
    #if defined(UDR0)
      #define UART_SRA UCSR0A
      #define UART_SRB UCSR0B
      #define UART_SRC UCSR0C
      #define UART_SRL UBRR0L
      #define UART_UDR UDR0
    #elif defined(UDR)
      #define UART_SRA UCSRA
      #define UART_SRB UCSRB
      #define UART_SRC UCSRC
      #define UART_SRL UBRRL
      #define UART_UDR UDR
    #elif defined(LINDAT)
      #error UART == 0, but no LINDAT support in prog
    #else
      #error UART == 0, but no UART0 on device
    #endif
  #elif (UART == 1)
    #if !defined(UDR1)
      #error UART == 1, but no UART1 on device
    #endif
    #define UART_SRA UCSR1A
    #define UART_SRB UCSR1B
    #define UART_SRC UCSR1C
    #define UART_SRL UBRR1L
    #define UART_UDR UDR1
  #elif (UART == 2)
    #if !defined(UDR2)
      #error UART == 2, but no UART2 on device
    #endif
    #define UART_SRA UCSR2A
    #define UART_SRB UCSR2B
    #define UART_SRC UCSR2C
    #define UART_SRL UBRR2L
    #define UART_UDR UDR2
  #elif (UART == 3)
    #if !defined(UDR3)
      #error UART == 3, but no UART3 on device
    #endif
    #define UART_SRA UCSR3A
    #define UART_SRB UCSR3B
    #define UART_SRC UCSR3C
    #define UART_SRL UBRR3L
    #define UART_UDR UDR3
  #endif
#endif

#ifdef __cplusplus
extern "C" {
#endif
    void writeUSART(uint8_t);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
    uint8_t readUSART(void);
#ifdef __cplusplus
}
#endif

#endif

bootuart.c

#include <avr/io.h>
#include "bootuart.h"

void writeUSART(uint8_t ch) {
    #if (SOFTUART == 0)
        #ifndef LINUART
            while (!(UART_SRA & _BV(UDRE0)));
        #endif
    UART_UDR = ch;
    #endif
}

uint8_t readUSART(void) {
  uint8_t ch;
  #if (SOFTUART == 0)
    #ifndef LINUART
        while(!(UART_SRA & _BV(RXC0)));
    #endif
    ch = UART_UDR;
    #endif
  return ch;
}

check.ino

#if !defined(SOFTUART)
    #define SOFTUART 0
#endif
#if !defined(UART)
    #define UART 0
#endif
#if !defined(SINGLESPEED)
    #define SINGLESPEED 0
#endif

#include <avr/io.h>
#include "bootuart.h"

#ifndef BAUD_RATE
    #if F_CPU >= 8000000L
        #define BAUD_RATE   115200L     // Highest rate Avrdude win32 can support
    #elif F_CPU >= 1000000L
        #define BAUD_RATE   9600L       // 19200 also supported, but with significant error
    #elif F_CPU >= 128000L
        #define BAUD_RATE   4800L       // Good for 128kHz internal RC
    #else
        #define BAUD_RATE 1200L         // Good even at 32768Hz
    #endif
#endif

#if (SOFTUART == 0)
    #if SINGLESPEED
        /* Single speed option */
        #define BAUD_SETTING (( (F_CPU + BAUD_RATE * 8L) / ((BAUD_RATE * 16L))) - 1 )
        #define BAUD_ACTUAL (F_CPU/(16 * ((BAUD_SETTING)+1)))
    #else
        /* Normal U2X usage */
        #define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 )
        #define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1)))
    #endif
    #if BAUD_ACTUAL <= BAUD_RATE
        #define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE)
        #if BAUD_ERROR >= 5
            #error BAUD_RATE off by greater than -5%
        #elif BAUD_ERROR >= 2  && !defined(PRODUCTION)
            #warning BAUD_RATE off by greater than -2%
        #endif
    #else
        #define BAUD_ERROR (( 100*(BAUD_ACTUAL - BAUD_RATE) ) / BAUD_RATE)
        #if BAUD_ERROR >= 5
            #error BAUD_RATE off by greater than 5%
        #elif BAUD_ERROR >= 2  && !defined(PRODUCTION)
            #warning BAUD_RATE off by greater than 2%
        #endif
    #endif
    #if BAUD_SETTING > 250
        #error Unachievable baud rate (too slow) BAUD_RATE 
    #endif // baud rate slow check
    #if (BAUD_SETTING - 1) < 3
        #if BAUD_ERROR != 0 // permit high bitrates (ie 1Mbps@16MHz) if error is zero
            #error Unachievable baud rate (too fast) BAUD_RATE 
        #endif
    #endif // baud rate fast check
#endif // SOFTUART

#if (SOFTUART == 0)
    #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega8515__) || \
        defined (__AVR_ATmega8535__) || defined (__AVR_ATmega16__) ||   \
        defined (__AVR_ATmega32__)
        #if (SINGLESPEED == 0)
            UCSRA = _BV(U2X); //Double speed mode USART
        #endif //singlespeed
        UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
        UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
        UBRRL = (uint8_t)BAUD_SETTING;
    #else // mega8/etc
        #ifdef LINUART
            //DDRB|=3;
            LINCR = (1 << LSWRES); 
            //LINBRRL = (((F_CPU * 10L / 32L / BAUD_RATE) + 5L) / 10L) - 1; 
            LINBRRL=(uint8_t)BAUD_SETTING;
            LINBTR = (1 << LDISR) | (8 << LBT0); 
            LINCR = _BV(LENA) | _BV(LCMD2) | _BV(LCMD1) | _BV(LCMD0); 
            LINDAT=0;
        #else
            #if (SINGLESPEED == 0)
                UART_SRA = _BV(U2X0); //Double speed mode USART0
            #endif
            UART_SRB = _BV(RXEN0) | _BV(TXEN0);
            UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
            UART_SRL = (uint8_t)BAUD_SETTING;
        #endif // LINUART
    #endif // mega8/etc
#endif // softUART

int main(void)
{ 
  while(1){
   writeUSART(readUSART());
  }
  return 0;
}

Problem: Now, the problem is whenever I compile the code, I get the errors as follows:-

bootuart.h:8:24: error: expected unqualified-id before 'volatile'

       #define UART_SRA UCSR0A

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:82:5: note: in expansion of macro 'UART_SRA'

     UART_SRA = _BV(U2X0); //Double speed mode USART0

     ^~~~~~~~

bootuart.h:8:24: error: expected ')' before 'volatile'

       #define UART_SRA UCSR0A

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:82:5: note: in expansion of macro 'UART_SRA'

     UART_SRA = _BV(U2X0); //Double speed mode USART0

     ^~~~~~~~

bootuart.h:8:24: error: expected ')' before 'volatile'

       #define UART_SRA UCSR0A

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:82:5: note: in expansion of macro 'UART_SRA'

     UART_SRA = _BV(U2X0); //Double speed mode USART0

     ^~~~~~~~

bootuart.h:9:24: error: expected unqualified-id before 'volatile'

       #define UART_SRB UCSR0B

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:84:4: note: in expansion of macro 'UART_SRB'

    UART_SRB = _BV(RXEN0) | _BV(TXEN0);

    ^~~~~~~~

bootuart.h:9:24: error: expected ')' before 'volatile'

       #define UART_SRB UCSR0B

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:84:4: note: in expansion of macro 'UART_SRB'

    UART_SRB = _BV(RXEN0) | _BV(TXEN0);

    ^~~~~~~~

bootuart.h:9:24: error: expected ')' before 'volatile'

       #define UART_SRB UCSR0B

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:84:4: note: in expansion of macro 'UART_SRB'

    UART_SRB = _BV(RXEN0) | _BV(TXEN0);

    ^~~~~~~~

bootuart.h:10:24: error: expected unqualified-id before 'volatile'

       #define UART_SRC UCSR0C

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:85:4: note: in expansion of macro 'UART_SRC'

    UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);

    ^~~~~~~~

bootuart.h:10:24: error: expected ')' before 'volatile'

       #define UART_SRC UCSR0C

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:85:4: note: in expansion of macro 'UART_SRC'

    UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);

    ^~~~~~~~

bootuart.h:10:24: error: expected ')' before 'volatile'

       #define UART_SRC UCSR0C

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:85:4: note: in expansion of macro 'UART_SRC'

    UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);

    ^~~~~~~~

bootuart.h:11:24: error: expected unqualified-id before 'volatile'

       #define UART_SRL UBRR0L

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:86:4: note: in expansion of macro 'UART_SRL'

    UART_SRL = (uint8_t)BAUD_SETTING;

    ^~~~~~~~

bootuart.h:11:24: error: expected ')' before 'volatile'

       #define UART_SRL UBRR0L

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:86:4: note: in expansion of macro 'UART_SRL'

    UART_SRL = (uint8_t)BAUD_SETTING;

    ^~~~~~~~

bootuart.h:11:24: error: expected ')' before 'volatile'

       #define UART_SRL UBRR0L

                        ^

E:\SPIDER\OTA_Programming_Module\Misc\check\check.ino:86:4: note: in expansion of macro 'UART_SRL'

    UART_SRL = (uint8_t)BAUD_SETTING;

    ^~~~~~~~

exit status 1
expected unqualified-id before 'volatile'

I have checked many other links somewhere around this issue but none of them helped. For 1 question in StackOverflow - Question, as per the answer, I have checked that none of my #define matches with any other identifiers in the libs files being included in my code. But still, the problem persists.

P.S: I have even tried with changing the #define identifiers name to some other identifier name but in vain. Also, I have tried the code with the ATMEL studio. No benefits.

Can anyone point, what is wrong with my code? Cause if it's working in Optiboot, then it should work here too, this is what I feel.

Any help will be appreciated. Thanks in advance.

1

There are 1 best solutions below

2
On BEST ANSWER

After some replacements (not all of them) you'll get this:

#if !defined(SOFTUART)
    #define SOFTUART 0
#endif
#if !defined(UART)
    #define UART 0
#endif
#if !defined(SINGLESPEED)
    #define SINGLESPEED 0
#endif

#include <avr/io.h>
#include "bootuart.h"


UART_SRA = _BV(U2X0); //Double speed mode USART0
UART_SRB = _BV(RXEN0) | _BV(TXEN0);
UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
UART_SRL = (uint8_t)BAUD_SETTING;

int main(void)
{ 
  while(1){
   writeUSART(readUSART());
  }
  return 0;
}

And as you might know, you can't do anything outside of functions. You'll have to put it into the main block, or make it setup function that's called in main function:

void setup() {

    #if (SOFTUART == 0)
        #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega8515__) || \
            defined (__AVR_ATmega8535__) || defined (__AVR_ATmega16__) ||   \
            defined (__AVR_ATmega32__)
            #if (SINGLESPEED == 0)
                UCSRA = _BV(U2X); //Double speed mode USART
            #endif //singlespeed
            UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
            UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
            UBRRL = (uint8_t)BAUD_SETTING;
        #else // mega8/etc
            #ifdef LINUART
                //DDRB|=3;
                LINCR = (1 << LSWRES); 
                //LINBRRL = (((F_CPU * 10L / 32L / BAUD_RATE) + 5L) / 10L) - 1; 
                LINBRRL=(uint8_t)BAUD_SETTING;
                LINBTR = (1 << LDISR) | (8 << LBT0); 
                LINCR = _BV(LENA) | _BV(LCMD2) | _BV(LCMD1) | _BV(LCMD0); 
                LINDAT=0;
            #else
                #if (SINGLESPEED == 0)
                    UART_SRA = _BV(U2X0); //Double speed mode USART0
                #endif
                UART_SRB = _BV(RXEN0) | _BV(TXEN0);
                UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
                UART_SRL = (uint8_t)BAUD_SETTING;
            #endif // LINUART
        #endif // mega8/etc
    #endif // softUART

} // setup()

int main() {
  setup();
  while (1) {


  } // while
} // main()

BTW: optiboot has a slight little difference - it's inside of the main function