SAM3S USART SPI slave mode

Discussion around product based on ARM Cortex M3 core.

Moderators: nferre, ncollot

kshysio
Posts: 25
Joined: Thu Nov 03, 2011 11:17 am

SAM3S USART SPI slave mode

Sat Feb 14, 2015 11:00 pm

hi,
in my project I'm trying to use USART in SPI slave mode. The problem is, that some output values from slave have MSB set to '1'.
for example: I am writing to US_THR register values:
[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A ... ]
and what master reads is:
[0x80, 0x01, 0x82, 0x03, 0x84, 0x05, 0x86, 0x07, 0x88, 0x09, 0x8A ... ]
I've look signals on the osciloscope - TXD line (MISO) and SCK - so there is no mistake with master readings... it's look like MSB of next byte is a copy of LSB a previous one. It may be a USART bug? or maybe some mysterious configuration bits should be set?
Some words about master: SCK is set to 3MHz, (slave MCLK runs at 64 MHz), there is enough delay between consecutive transfers. CPOL and CPHA checked.
my slave code is below, data received from master without problems.
please help...

Code: Select all

volatile uint8_t buff_slave_tx[64];
volatile uint8_t buff_slave_rx[64];

void SLAVE_SPI_init(void)
{
// configure uart pins
PMC->PMC_PCER0 = (1<<ID_USART1); // power on usart
PIOA->PIO_PDR = (CRACK_MOSI | CRACK_SCK | CRACK_MISO | CRACK_CS); // disable pioa
PIOA->PIO_ABCDSR[0] &= ~(CRACK_MOSI | CRACK_SCK | CRACK_MISO | CRACK_CS); // peripheral A
PIOA->PIO_ABCDSR[1] &= ~(CRACK_MOSI | CRACK_SCK | CRACK_MISO | CRACK_CS); // peripheral A
USART1->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS | US_CR_RSTSTA;
USART1->US_MR = US_MR_USART_MODE_SPI_SLAVE | US_MR_USCLKS_SCK | US_MR_CHRL_8_BIT | US_MR_CPHA |US_MR_CHMODE_NORMAL | US_MR_PAR_NO;
USART1->US_IDR = 0xFFFFFFFF; // disable all irq
USART1->US_IER = US_IER_CTSIC ; // CS change irq
uint8_t i=0;
while (i<64)
  {
  buff_slave_tx[i] = i; // msg to send
  buff_slave_rx[i] = 0; // clr rx buffer
  i++;
  }
NVIC_EnableIRQ(USART1_IRQn); 
}

Code: Select all

void USART1_Handler(void)
{
uint32_t status;
status = USART1->US_CSR; // read register
if(status & US_CSR_CTS) // do only if chip select not active
 {
 if(status & US_CSR_ENDRX) // transmission completed
  {
  USART1->US_IDR = US_IDR_ENDRX;
  // here I can read buffers.
  }
 if(status & US_CSR_CTSIC) // prepare PDC to be ready when master start transmission
  {
  USART1->US_CR = US_CR_RSTRX | US_CR_RSTSTA | US_CR_RSTTX;
  USART1->US_CR = US_CR_TXEN | US_CR_RXEN;
  USART1->US_RPR = (uint32_t)&buff_slave_rx;
  USART1->US_TPR = (uint32_t)&buff_slave_tx;
  USART1->US_RCR = 64;  
  USART1->US_TCR = 64;  
  USART1->US_PTCR = US_PTCR_TXTEN | US_PTCR_RXTEN;
  USART1->US_IER = US_IER_ENDRX;
  }
}
else
 {
 }
}
kshysio
Posts: 25
Joined: Thu Nov 03, 2011 11:17 am

Re: SAM3S USART SPI slave mode

Wed Feb 18, 2015 9:58 pm

so, my temporary solution is:
change transmission to 9 bit and ignore MSB. The bad thing is that before sending buffer it must be rewritten into 16-bit length (the master inversely rewrites to 8bit length).
it works, but it's not a good one, because I'm wasting time to rewriting, and sending additional one clock pulse...
best regards
Kshysio

Return to “SAM3 Cortex-M3 MCU”

Who is online

Users browsing this forum: No registered users and 2 guests