[Solved] Arduino Due UART with 500kbps

I'm facing a trouble with Arduino Due UART. I need to work with 500kbps. With this speed the error is 5%, which don't allows the Due communicate with other device. The way that I see to solve this is to change the MCLK to 80MHz, but there is no API to do this, I need to change the core Arduino source code.
The code that I'm writing is to be released as a library thus I can't simply change it, because the user "won't" do this modification.
Any suggestion to solve this?

Can you switch to USART? There is an extract from DS:

36.7.1.2
Fractional Baud Rate in Asynchronous Mode
The Baud Rate generator previously defined is subject to the following limitation: the output fre-
quency changes by only integer multiples of the reference frequency. An approach to this
problem is to integrate a fractional N clock generator that has a high resolution. The generator
architecture is modified to obtain Baud Rate changes by a fraction of the reference source clock.
This fractional part is programmed with the FP field in the Baud Rate Generator Register
(US_BRGR). If FP is not 0, the fractional part is activated. The resolution is one eighth of the
clock divider. This feature is only available when using USART normal mode. The fractional
Baud Rate is calculated using the following formula:
SelectedClock
Baudrate = ----------------------------------------------------------------

? 8 ( 2 – Over ) ? CD + FP
------- ? ?
?
?
8 ? ?

Looks like 16 x 10.5 (FP = 4/8) is what you need

AFAIK the code for USART setup in the relevant begin() method doesn't use
the enhanced baudrate selection hardware, its code common to all UASRTs
and UART.

By the way the USART peripherals control Serial1/Serial2/Serial3 but not Serial
which is on the single UART peripheral.

I can't use USART, the library is done to be used along with a shield that must work for both, Uno and Due Arduino. We use the same shield for these Arduino's, so the only common pins for both is the UART.
The other way that I see is to use software uart, but I really wouldn't like do that. :slight_smile:

No, software serial has no 500 k option:

  //  baud    rxcenter   rxintra    rxstop    tx
  { 115200,   1,         17,        17,       12,    },
  { 57600,    10,        37,        37,       33,    },
  { 38400,    25,        57,        57,       54,    },
  { 31250,    31,        70,        70,       68,    },
  { 28800,    34,        77,        77,       74,    },
  { 19200,    54,        117,       117,      114,   },
  { 14400,    74,        156,       156,      153,   },
  { 9600,     114,       236,       236,      233,   },
  { 4800,     233,       474,       474,      471,   },
  { 2400,     471,       950,       950,      947,   },
  { 1200,     947,       1902,      1902,     1899,  },
  { 600,      1902,      3804,      3804,     3800,  },
  { 300,      3804,      7617,      7617,     7614,  },

I tried to change the MCLK configuration to check if UART would work fine. It didn't.

In the system_sam3xa.c file I decrease the CKGR_PLLAR_MULA(0xdUL) to CKGR_PLLAR_MULA(0xbUL) in SYS_BOARD_PLLAR define, also I did SystemCoreClock = 72000000 in SystemInit function.
Using 72MHz the UART should work with zero error, but it didn't. I checked with oscilloscope and the frequency is between 523.6kHz and 526.3kHz. That is practically the same value that I get using the default values, I mean not change anything.

Am I modifying the right file and the right values?

I solved the problem changing the system core clock.

#define SYS_BOARD_PLLAR     (CKGR_PLLAR_ONE \
                            | CKGR_PLLAR_MULA(39) \
                            | CKGR_PLLAR_PLLACOUNT(100) \
                            | CKGR_PLLAR_DIVA(3))
// ...
#ifdef __SAM3X8E__
    // change and update system core clock

    // Configure PLLA
    PMC->CKGR_PLLAR = SYS_BOARD_PLLAR;
    while (!(PMC->PMC_SR & PMC_SR_LOCKA));

    SystemCoreClockUpdate();
#endif

This give me SystemCoreClock = 80MHz, that is a perfect value to UART work with 500kbps and 1Mbps.