[SOLVED] Arduino DUE + "variable Serial Config"

Hi all,

I’m attempting to create a menu ( with LCD screen ans push buttons ), to setup a serial ports with DUE.

My sketch works fine on Arduino MICRO, and I try to make it work on a DUE board.

To be simple, I use 3 arrays, to make choice-lists. One for all baudrates supported:

unsigned long baudRate[10] = { 300 , 600 , 1200 , 2400 , 4800 , 9600 ,  19200 , 38400 , 57600 , 115200};

and two arrays for the confs supported (one for display to the user, one for serial config, as they share the same index):

char serialConfig[24] = { 0x00 , 0x02 , 0x04 , 0x06 , 0x08 , 0x0A , 0x0C , 0x0E , 0x20 , 0x22 , 0x24 , 0x26 ,
             0x28 , 0x2A , 0x2C , 0x2E , 0x30 , 0x32 , 0x34 , 0x36 , 0x38 , 0x3A , 0x3C , 0x3E};

char* serialConfigString[24] = { "5N1" , "6N1" , "7N1" , "8N1" , "5N2" , "6N2" , "7N2" , "8N2" , "5E1" , "6E1" , "7E1" , "8E1" , 
                "5E2" , "6E2" , "7E2" , "8E2" , "5O1" , "6O1" , "7O1" , "8O1" , "5O2" , "6O2" , "7O2" , "8O2"};

I store index for baudrate and config in this variables:

int baudRateChoice , serialConfigChoice;

Later, after the user has chosen his desired conf, I initiate the serial1 as follows:

Serial1.begin( baudRate[baudRateChoice] , serialConfig[serialConfigChoice] );

When I compile the sketch, I get an error message with the above line that I didn’t get with Micro:

C:\Users\electronic\AppData\Roaming\Arduino15\packages\arduino\hardware\sam\1.6.4\cores\arduino/USARTClass.h:112:10: note: no known conversion for argument 2 from ‘char’ to ‘UARTClass::UARTModes’
call of overloaded ‘begin(long unsigned int&, char&)’ is ambiguous

I don’t really understand the meaning of this … and why what is OK with a board, fails with another …

I guess there’s some fundamental differences between AVR et SAM core, that my understanding and my skills :confused: cannot explain …

Does anyone know how can I solve this issue (or force the compiler choice ) ?

Perhaps a beginning of answer …

in USARTClass.cpp:

void USARTClass::begin(const uint32_t dwBaudRate, const USARTModes config)
{
  uint32_t modeReg = static_cast<uint32_t>(config);
  modeReg |= US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHMODE_NORMAL;
  init(dwBaudRate, modeReg);

and in USARTClass.h:

// Define config for Serial.begin(baud, config);
#define SERIAL_5N1 USARTClass::Mode_5N1
#define SERIAL_6N1 USARTClass::Mode_6N1
#define SERIAL_7N1 USARTClass::Mode_7N1
#define SERIAL_5N2 USARTClass::Mode_5N2
#define SERIAL_6N2 USARTClass::Mode_6N2
#define SERIAL_7N2 USARTClass::Mode_7N2
#define SERIAL_8N2 USARTClass::Mode_8N2
#define SERIAL_5E1 USARTClass::Mode_5E1
#define SERIAL_6E1 USARTClass::Mode_6E1
#define SERIAL_7E1 USARTClass::Mode_7E1
#define SERIAL_5E2 USARTClass::Mode_5E2
#define SERIAL_6E2 USARTClass::Mode_6E2
#define SERIAL_7E2 USARTClass::Mode_7E2
#define SERIAL_8E2 USARTClass::Mode_8E2
#define SERIAL_5O1 USARTClass::Mode_5O1
#define SERIAL_6O1 USARTClass::Mode_6O1
#define SERIAL_7O1 USARTClass::Mode_7O1
#define SERIAL_5O2 USARTClass::Mode_5O2
#define SERIAL_6O2 USARTClass::Mode_6O2
#define SERIAL_7O2 USARTClass::Mode_7O2
#define SERIAL_8O2 USARTClass::Mode_8O2
#define SERIAL_5M1 USARTClass::Mode_5M1
#define SERIAL_6M1 USARTClass::Mode_6M1
#define SERIAL_7M1 USARTClass::Mode_7M1
#define SERIAL_5M2 USARTClass::Mode_5M2
#define SERIAL_6M2 USARTClass::Mode_6M2
#define SERIAL_7M2 USARTClass::Mode_7M2
#define SERIAL_8M2 USARTClass::Mode_8M2
#define SERIAL_5S1 USARTClass::Mode_5S1
#define SERIAL_6S1 USARTClass::Mode_6S1
#define SERIAL_7S1 USARTClass::Mode_7S1
#define SERIAL_5S2 USARTClass::Mode_5S2
#define SERIAL_6S2 USARTClass::Mode_6S2
#define SERIAL_7S2 USARTClass::Mode_7S2
#define SERIAL_8S2 USARTClass::Mode_8S2


class USARTClass : public UARTClass
{
  public:
    // 8x1 bit modes are inherited from UARTClass
    enum USARTModes {
      Mode_5N1 = US_MR_CHRL_5_BIT | US_MR_PAR_NO    | US_MR_NBSTOP_1_BIT,
      Mode_6N1 = US_MR_CHRL_6_BIT | US_MR_PAR_NO    | US_MR_NBSTOP_1_BIT,
      Mode_7N1 = US_MR_CHRL_7_BIT | US_MR_PAR_NO    | US_MR_NBSTOP_1_BIT,
      Mode_5N2 = US_MR_CHRL_5_BIT | US_MR_PAR_NO    | US_MR_NBSTOP_2_BIT,
      Mode_6N2 = US_MR_CHRL_6_BIT | US_MR_PAR_NO    | US_MR_NBSTOP_2_BIT,
      Mode_7N2 = US_MR_CHRL_7_BIT | US_MR_PAR_NO    | US_MR_NBSTOP_2_BIT,
      Mode_8N2 = US_MR_CHRL_8_BIT | US_MR_PAR_NO    | US_MR_NBSTOP_2_BIT,
      Mode_5E1 = US_MR_CHRL_5_BIT | US_MR_PAR_EVEN  | US_MR_NBSTOP_1_BIT,
      Mode_6E1 = US_MR_CHRL_6_BIT | US_MR_PAR_EVEN  | US_MR_NBSTOP_1_BIT,
      Mode_7E1 = US_MR_CHRL_7_BIT | US_MR_PAR_EVEN  | US_MR_NBSTOP_1_BIT,
      Mode_5E2 = US_MR_CHRL_5_BIT | US_MR_PAR_EVEN  | US_MR_NBSTOP_2_BIT,
      Mode_6E2 = US_MR_CHRL_6_BIT | US_MR_PAR_EVEN  | US_MR_NBSTOP_2_BIT,
      Mode_7E2 = US_MR_CHRL_7_BIT | US_MR_PAR_EVEN  | US_MR_NBSTOP_2_BIT,
      Mode_8E2 = US_MR_CHRL_8_BIT | US_MR_PAR_EVEN  | US_MR_NBSTOP_2_BIT,
      Mode_5O1 = US_MR_CHRL_5_BIT | US_MR_PAR_ODD   | US_MR_NBSTOP_1_BIT,
      Mode_6O1 = US_MR_CHRL_6_BIT | US_MR_PAR_ODD   | US_MR_NBSTOP_1_BIT,
      Mode_7O1 = US_MR_CHRL_7_BIT | US_MR_PAR_ODD   | US_MR_NBSTOP_1_BIT,
      Mode_5O2 = US_MR_CHRL_5_BIT | US_MR_PAR_ODD   | US_MR_NBSTOP_2_BIT,
      Mode_6O2 = US_MR_CHRL_6_BIT | US_MR_PAR_ODD   | US_MR_NBSTOP_2_BIT,
      Mode_7O2 = US_MR_CHRL_7_BIT | US_MR_PAR_ODD   | US_MR_NBSTOP_2_BIT,
      Mode_8O2 = US_MR_CHRL_8_BIT | US_MR_PAR_ODD   | US_MR_NBSTOP_2_BIT,
      Mode_5M1 = US_MR_CHRL_5_BIT | US_MR_PAR_MARK  | US_MR_NBSTOP_1_BIT,
      Mode_6M1 = US_MR_CHRL_6_BIT | US_MR_PAR_MARK  | US_MR_NBSTOP_1_BIT,
      Mode_7M1 = US_MR_CHRL_7_BIT | US_MR_PAR_MARK  | US_MR_NBSTOP_1_BIT,
      Mode_5M2 = US_MR_CHRL_5_BIT | US_MR_PAR_MARK  | US_MR_NBSTOP_2_BIT,
      Mode_6M2 = US_MR_CHRL_6_BIT | US_MR_PAR_MARK  | US_MR_NBSTOP_2_BIT,
      Mode_7M2 = US_MR_CHRL_7_BIT | US_MR_PAR_MARK  | US_MR_NBSTOP_2_BIT,
      Mode_8M2 = US_MR_CHRL_8_BIT | US_MR_PAR_MARK  | US_MR_NBSTOP_2_BIT,
      Mode_5S1 = US_MR_CHRL_5_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_1_BIT,
      Mode_6S1 = US_MR_CHRL_6_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_1_BIT,
      Mode_7S1 = US_MR_CHRL_7_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_1_BIT,
      Mode_5S2 = US_MR_CHRL_5_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_2_BIT,
      Mode_6S2 = US_MR_CHRL_6_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_2_BIT,
      Mode_7S2 = US_MR_CHRL_7_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_2_BIT,
      Mode_8S2 = US_MR_CHRL_8_BIT | US_MR_PAR_SPACE | US_MR_NBSTOP_2_BIT,
    };

    USARTClass(Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer);

    void begin(const uint32_t dwBaudRate);
    void begin(const uint32_t dwBaudRate, const USARTModes config);
    void begin(const uint32_t dwBaudRate, const UARTModes config);

For the satndard AVR Library, HardwareSerial.h:

#define SERIAL_5N1 0x00
#define SERIAL_6N1 0x02
#define SERIAL_7N1 0x04
#define SERIAL_8N1 0x06
#define SERIAL_5N2 0x08
#define SERIAL_6N2 0x0A
#define SERIAL_7N2 0x0C
#define SERIAL_8N2 0x0E
#define SERIAL_5E1 0x20
#define SERIAL_6E1 0x22
#define SERIAL_7E1 0x24
#define SERIAL_8E1 0x26
#define SERIAL_5E2 0x28
#define SERIAL_6E2 0x2A
#define SERIAL_7E2 0x2C
#define SERIAL_8E2 0x2E
#define SERIAL_5O1 0x30
#define SERIAL_6O1 0x32
#define SERIAL_7O1 0x34
#define SERIAL_8O1 0x36
#define SERIAL_5O2 0x38
#define SERIAL_6O2 0x3A
#define SERIAL_7O2 0x3C
#define SERIAL_8O2 0x3E

That’s why that is working on DUE, I pass a byte as parameter in Serial.begin()

Now, how can I do to pass such a (USARTClass ?) parameter to Serial.begin on a DUE ?

OK.

I found a workaround, consisting of making the init function in UARTClass public. So it is possible to use it in Arduino IDE, and, as it's dealing with integers, it's easier for me for to achieve my aim ;)

Hi ramtron666 I'm trying to configure the Serial Ports almost equal as you already did it (Awesome!!!). I'm very new in Arduino, and I'm confused in how you achieved the fixing. You said:

"I found a workaround, consisting of making the init function in UARTClass public."

but I do not really know what you mean. Could you please explain more? Or indicate what you did and where? TXS a lot for your valuable help.

lmarinesm (Sorry about my poor English)

Hi,

So sorry for the delay ... I usually use the french forum ....

Anyway, I'll try to answer. (I didn't touch an Arduino board since august ... so I will answer from memories)

You'll have to explore the UARTClass library (UARTClass.h) See how it's made:

  • some methods are public (which meam you can call them from your sketch, like begin)
  • some others are protected (like init) Protected methods are a kind of "system" tool, and can't be called directly (ie you can't call Serial1.init)

Have a look at UARTClass.cpp: You'll see that the begin method is using the init method.

If you change the method init to be in the public section, then you'll be able to call it from your sketch.

That's it.

But, even if exploring libraries is very instructive, to see what's behind a method, modify them must be done very carefully.