SAM3X8E USART in SPI mode (Transmission)

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I am working on utilising the USART as SPI on Arduino Due. Tested 8-bit communication and is working as expected. Now working on 16-bit data transfer so what are the changes to be done and which are the register bits need to be monitored/altered. 

 

The Arduino code is as below.

 

unsigned long previousMicros = 0, interval = 50;

void setup() {
  Serial.begin(9600);   // diagnostics
  Serial1.begin(9600);  // pre-initialize USART0
  USART0config();       // setup mode, clock and pins
  USART0status();
}

void loop() {
  // Sends 8-bit data every 50us
  if (micros() - previousMicros >= interval) {
    previousMicros = micros();
    USART0->US_THR = 0xAA; // Sends 8-bit data
  }
}

void USART0config() {
  USART0->US_WPMR = 0x55534100;   // Unlock the USART Mode register
  USART0->US_MR |= 0x408CE;       // Set Mode to CLK0=1, 8_BIT, SPI_MASTER
  USART0->US_BRGR = 21;           // Clock Divider (SCK = 4MHz)

  PIOA->PIO_WPMR = 0x50494F00;    // Unlock PIOA Write Protect Mode Register
  PIOB->PIO_WPMR = 0x50494F00;    // Unlock PIOB Write Protect Mode Register
  PIOB->PIO_ABSR |= (0u << 25);   // CS: Assign A14 I/O to the Peripheral A function
  PIOB->PIO_PDR |= (1u << 25);    // CS: Disable PIO control, enable peripheral control
  PIOA->PIO_ABSR |= (1u << 17);   // SCK: Assign A16 I/O to the Peripheral B function
  PIOA->PIO_PDR |= (1u << 17);    // SCK: Disable PIO control, enable peripheral control
  PIOA->PIO_ABSR |= (0u << 10);   // MOSI: Assign PA13 I/O to the Peripheral A function
  PIOA->PIO_PDR |= (1u << 10);    // MOSI: Disable PIO control, enable peripheral control
  PIOA->PIO_ABSR |= (0u << 11);   // MISO: Assign A12 I/O to the Peripheral A function
  PIOA->PIO_PDR |= (1u << 11);    // MISO: Disable PIO control, enable peripheral control
}

void USART0status() {
  Serial.print("PIOA_ABSR \t");
  Serial.println(PIOA->PIO_ABSR, HEX);
  Serial.print("PIOB_ABSR \t");
  Serial.println(PIOB->PIO_ABSR, HEX);
  Serial.print("US_MR   \t");
  Serial.println(USART0->US_MR, HEX);
  Serial.print("US_CSR  \t");
  Serial.println(USART0->US_CSR, HEX);
  Serial.print("US_BRGR (DEC)\t");
  Serial.println(USART0->US_BRGR, DEC);
  Serial.print("US_RTOR \t");
  Serial.println(USART0->US_RTOR, HEX);
  Serial.print("US_TTGR \t");
  Serial.println(USART0->US_TTGR, HEX);
  Serial.print("US_FIDI \t");
  Serial.println(USART0->US_FIDI, HEX);
  Serial.print("US_NER  \t");
  Serial.println(USART0->US_NER, HEX);
  Serial.print("US_IF   \t");
  Serial.println(USART0->US_IF, HEX);
  Serial.print("US_MAN  \t");
  Serial.println(USART0->US_MAN, HEX);
  Serial.print("US_LINMR \t");
  Serial.println(USART0->US_LINMR, HEX);
  Serial.print("US_LINIR \t");
  Serial.println(USART0->US_LINIR, HEX);
  Serial.print("US_WPSR \t");
  Serial.println(USART0->US_WPSR, HEX);
}

 

Last Edited: Wed. Mar 30, 2022 - 10:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

16 bits SPI appears not to be supported with the USART. But is there a problem sending 2 x 8 bits?

35.7.7.3 Data Transfer Up to 9 data bits are successively shifted out on the TXD pin at each rising or falling edge (depending of CPOL and CPHA) of the programmed serial clock. There is no Start bit, no Parity bit and no Stop bit. The number of data bits is selected by the CHRL field and the MODE 9 bit in the Mode Register (US_MR). The 9 bits are selected by setting the MODE 9 bit regardless of the CHRL field. The MSB data bit is always sent first in SPI Mode (Master or Slave).

 /Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tried sending 2 x 8-bit data but every time the second most data will only appear, saw them on a oscilloscope. Added a delay of some micro seconds between each byte and verified both the bytes are appearing on MOSI line. But there was a logical shift of CS (Chip Select) line between two bytes it should be low but it was going high and then low for second byte. It was observed on oscilloscope that on native SPI with 16-bit data CS line remains low till transmission of the second byte (Attachment 3) as compared to that of native SPI (Attachment 4). Solved it by tweaking the US_CR register RTSEN and RTSDIS bit. Now working on data reception part on MISO line. Please find the attachment.

 

In the USART based SPI (Attachment 2) although the MOSI line is low when idle (between two consecutive bytes) the signal at the clock edge is same for second byte on both USART SPI and native SPI. So for USART based SPI will that affect the communication by any means?

 

In attachment

Signal in blue is SCK

Signal in green is MOSI

Signal in pink is CS

 

All attachments follow the same colour for signals.

Attachment(s): 

Last Edited: Wed. Mar 30, 2022 - 11:01 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No that's ok, the data line needs to be correct on the clock edge only.

/Lars

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Lars, thanks for clarification.