Reading Two Successive Bytes In USART SPI Mode

Hey all,

I have two Arduino Dues set up right now, one acting as a transmitter and one as a receiver. Using the SPI mode of USART, the transmitting Due is transmitting a 16 bit word (two bytes back to back). This has been verified with a scope. With the receiving Due, I am attempting to read the incoming bytes and print them on the Serial monitor. I tried simply polling the status register's RXRDY bit and reading the contents of the receive hold register, however the data stream I observed was the correct bytes mixed in with junk values; the correct values would print, then start repeating, and then random values would print repeatedly until changing. Repeatedly pressing the reset button on the receiving Due would eventually get the right values to temporarily show up again, interestingly enough. I tried using Serial1.read() instead (the serial line connected to USART0), but had the exact same issue. I figured that it must be a timing issue, and set out to write an ISR.

Finding documentation was hard, but I managed to scrap together some code. However, when I run it, it only prints out zeroes. I'd appreciate any help!

(I'm posting this at 2 A.M., so apologies for any dumb mistakes!)

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial1.begin(9600); //initialize USART0;
 
  USART0->US_WPMR = 0x55534100; //Disables write protect for mode reg
  USART0->US_MR |= 0x409CE; //Set to SPI Master, 8 bit transfer, CPHA = 1, CPOL = 0, CLK0 = 1
  USART0->US_CR |= 0x50;  //Enable TX and RX
  USART0->US_BRGR |= 0xFFFF;  //Divides MCLK by FF (pg. 843)

 
  PIOA->PIO_WPMR = 0x50494F00; //Disables PIOA write protect
  PIOB->PIO_WPMR = 0x50494F00; //Disables PIOB write protect


  //Set up MOSI
  PIOA->PIO_ABSR |= (0u << 11); //Assigns PA11 to Peripheral A function
  PIOA->PIO_PDR  |= (1u << 11); //Enables peripheral control for PA11
  
  //Set up MISO
  PIOA->PIO_ABSR |= (0u << 10); //Assigns PA10 to Peripheral A function
  PIOA->PIO_PDR  |= (1u << 10); //Enables peripheral control for PA10
  
  //Set up SCK
  PIOA->PIO_ABSR |= (1u << 17); //Assigns PA17 to Peripheral B function
  PIOA->PIO_PDR |= (1u << 17);  //Enables peripheral control for PA17
  
  //Set up chip select line
  PIOB->PIO_ABSR |= (0u << 25); //Assigns PB26 to Peripheral A function (pg. 656)  
  PIOB->PIO_PDR |= (1u << 25); //Enables peripheral control for PB26 (pg. 634) 

  USART0->US_IDR = 0xFFFFFFFF; //Disable interrupts
  USART0->US_IER |= 0x01u;  //Enable RXRDY interrupt flag
  NVIC_EnableIRQ(USART0_IRQn); //Enable USART0 interrupts

}

volatile uint8_t data;

void USART0_Handler (void) __attribute__ ((weak));
void USART0_Handler(void) {
   
  if ((USART0->US_CSR & 0x01u)) {
    data = USART0->US_RHR;
  }
}

void loop() {
USART0->US_THR = 0x00; //send a dummy byte
Serial.println(data, HEX);
}

Read the USART SPI section of Sam3x datasheet to understand this code:

https://forum.arduino.cc/index.php?topic=283766.0

Hi Ard_Newbie,

I understand the code, I wrote it myself and even referenced Dlloyd's comments on that thread. My issue is with getting a functional ISR that allows me to read both bytes, i.e. the whole 16 bit word.

To write your own USARTx interrupt Handler, you will have first alter variant.h.

See this thread, reply #5:

https://forum.arduino.cc/index.php?topic=470005.0

From this thread (reply #2), I thought I could do something like

void USART1_Handler(void) attribute((weak));
void USART1_Handler(void)
{
/Serial2.IrqHandler();/
// your code here
}

instead of messing with variant.h

Page 774 of the SAM3X datasheet says "Using the USART interrupt requires the Interrupt Controller to be programmed first." Could this be it?