UART interrupt Arduino Due ?

dear all

help me code example with UART interrupt
my application need use interrupt uart , but i don't how work ?

thanks

Serial does it already.

Or you can do something like that with an interrupt enable on reception:

volatile uint8_t data;

void UART_Handler (void) __attribute__ ((weak));
void UART_Handler(void) {
 
  if (UART->UART_SR & UART_SR_RXRDY) {

    data = UART->UART_RHR;
  }
}

void setup() {
   PMC->PMC_PCER0 = PMC_PCER0_PID8;  // UART power ON

  // Reset and disable receiver & transmitter
  UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;

  // Set the baudrate to 250000
  UART->UART_BRGR = 21; // 84 000 000 / 16 * x = BaudRate (write x into UART_BRGR)

  // No Parity
  UART->UART_MR = UART_MR_PAR_NO;

  // Disable PDC channel requests
  UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;

  // Disable / Enable interrupts on end of receive
  UART->UART_IDR = 0xFFFFFFFF;
  UART->UART_IER = UART_IER_RXRDY;
  NVIC_EnableIRQ((IRQn_Type) ID_UART);

  // Enable receiver and transmitter
  UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;

}

void loop() {

}

Oh Thanks you

i don't understand register in arm core ( arduino Due )

now , i want received data by UART3, BaudRate = 38400

can you send to me code example modify ?

thanks

Hi Ard_newbie

i build this code you support but not run,

#define LED_BUILTIN 13
volatile uint8_t data;
char TXBUFFER[64]; // UART PDC Transmit buffer
void UART_Handler (void) __attribute__ ((weak));
void UART0_Handler(void) {
 
  if (UART->UART_SR & UART_SR_RXRDY) {
    data = UART->UART_RHR;
   if(data == 49) digitalWrite(LED_BUILTIN, LOW); 
   else if(data == 50) digitalWrite(LED_BUILTIN, HIGH); 
  }
  

}

void setup() {
   
    
   PMC->PMC_PCER0 = PMC_PCER0_PID8;  // UART power ON

  // Reset and disable receiver & transmitter
  UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;

  // Set the baudrate to 250000
  UART->UART_BRGR = 21; // 84 000 000 / 16 * x = BaudRate (write x into UART_BRGR)

  // No Parity
  UART->UART_MR = UART_MR_PAR_NO;

  // Disable PDC channel requests
  UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;

  // Disable / Enable interrupts on end of receive
  UART->UART_IDR = 0xFFFFFFFF;
  UART->UART_IER = UART_IER_RXRDY;
  NVIC_EnableIRQ((IRQn_Type) ID_UART);

  // Enable receiver and transmitter
  UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;


   pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH); 
  
}

void loop() {

}

i don't understand

You could look at the source code that the Due Core libraries use to handle interrupts on the UART and USARTs:

Thanks westfw

now , I temporarily receive data from the timer interrupt

affter, i will try to to follow your link support .It is very detailed

thanks

Hi everybody,

Can Please somebody show me some interrupt that is working for Serial3? I have multiple communications but i need Serial3 on interrups. If i have check for serial3 available in main loop its slow and i have many communication timeouts. But find it how to do it with RX interrupt look like nightmare for me. Everywhere i found example, people are using just serial0. Im not sure how to modify it to channel 3. Thaks for any help.

Serial3 is not slow if you select a correct baud rate.

See this example sketch (and of course hook jumpers between RX1/TX3 and between TX1/RX3):

char c = 0;
void setup() {
 
  Serial.begin(250000);
  Serial1.begin(1000000);
  Serial3.begin(1000000);

  Serial3.print("Hello");
}


void loop() {
  String s;
  s = "";

  while (Serial1.available() > 0) {
    c = Serial1.read();
    s += c;

  }
  if (s.length() > 0) {
    Serial.println(s);
    Serial3.print(s);
  }
  delay(1000);
}

Hi, i understand what you want to say to me but my problem is not the speed of uart but general speed of "checking" rx buffer with serial3.available in main loop. Baud rate is not very fast 250000 and about 150 messages in one swcond. My program is dc servo drive that have interrups for encoder, timer interrupt for pid calculations and communication with interpolator (master due). Problem is that i have random timeouts of communication messages. I think that should be executed with rx interrupt becauce if some other inetreupt occurs the main loop will continue after everything else is finished.

Do you have a recent version of the arduino ide? The github history says that serial on due was made interrupt-driven in December 2014...

westfw:
The github history says that serial on due was made interrupt-driven in December 2014...

Yes and...no. Inside the interrupt function, Serialx.available is updated, BUT, Serialx.available is tested Inside Loop().

If you want a 100% USART3 received buffer interrupt driven, you will have to write your own interrupt function with :

void USART3_Handler(void) { ...}

Hi,

im using ide 1.8.5

I tried to put my communication function in void USART3_Handler(void) { ...} but i have compilation error:
...variant.cpp:351: multiple definition of `USART3_Handler'
... ervo_slave_42.ino:840: first defined here
collect2.exe: error: ld returned 1 exit status

Am I doing it wrong way? thanx

At the beginning of your sketch, you will write:

void USART3_Handler(void) __attribute__ ((weak));
void USART3_Handler(void) {...}

Sorry, You are right i moved it before setup and compilaton is ok. But is not interrupting at all. Serial buffer became full but it doesnt run USART3_Handler function.

Writting your own version of USART3 interrupt, e.g. with a PDC DMA, requires several steps.

Program a simple sketch with all the necessary steps and post your code.

ard_newbie:
At the beginning of your sketch, you will write:

void USART3_Handler(void) __attribute__ ((weak));

void USART3_Handler(void) {...}

No. What you wrote would cause the OP's sketch to have a weak function. When there are two weak functions which one is used is essentially undefined. The linker could use either one. However, even worse here, USART3_Handler is NOT declared weak in the Arduino core so you cannot override it in a sketch. Further complicating this fun is that the interrupt handler for serial does nothing but acknowledge the interrupt and store the incoming character into a buffer. There is no hook to grab to get this character immediately in your sketch. So, this is a dead end unless you feel like modifying the Arduino core.

The potential solution is to make the loop function execute more rapidly. Perhaps this would involve moving some functionality from loop into a timer interrupt or something.

Well these modifications are really out of my knowledge. In attachement is communication part of my code. If its possible for other USART i dont have problem to use it instead of USART3

due_slave.ino (9.06 KB)

Hi AdderD,

Will interrupt work if I use Serial1 or Serial2? Like:

void USART1_Handler(void) attribute ((weak));
void USART1_Handler(void) {...}

Thanx

joker691:
Hi AdderD,

Will interrupt work if I use Serial1 or Serial2? Like:

void USART1_Handler(void) attribute ((weak));
void USART1_Handler(void) {...}

Thanx

As soon as you declare your function as weak it's game over. You need a strong function to be able to override a weak function. Unfortunately, none of the USART handlers are declared weak so they're also strong. You cannot override a strong function in C code. So, you're just plain stuck.

But, you can feel free to modify the Arduino core to make the interrupt handlers weak. Then you can declare your own strong version and your version will get linked in place of the weak version in the core.

The USART interrupts are in variant.cpp found at /AppData/local/Arduino15/packages/arduino/hardware/sam/1.6.11/variants/arduino_due_x

Add the
void USART1_Handler(void) attribute ((weak));
line to the interrupt handler you need to be able to override.

The actual implementation of the interrupt handler is found in UARTClass.cpp in sam/1.6.11/cores/arduino
You'll want to copy that implementation to your own code. You will not be able to put the character into the buffer in the UART class like the original handler did. You'll have to create your own buffer.

Thanks for really detailed answer. I checked Arduino core and i think i am the weak part for modifing it.
I will need to think about something else. Thanks again