Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

SPI slave code

Altera_Forum
Honored Contributor II
1,528 Views

Hi,  

 

I'm using the QSYS SPI module as a slave. The SPI slave is supposed to receive sequences of bytes/characters.  

 

In order to make this happen, I'm using some SW code that reads the status register and checks that the RRDY (receive ready) bit is set. When the RRDY is set, I read from the rxdata register and store the byte in a array. 

 

The problem that I'm having is that I'm only reading a single byte/character at a time. I would like to fill up the array with the whole sequence being transmitted from the external SPI master.  

 

What's happening is that after reading the first byte (reading from the rxdata register clears the RRDY bit), I' getting stuck waiting for the RRDY bit to be asserted for the next byte/character.  

 

If I try to re-send the command sequence, the RRDY bit triggers, but again I'm only reading a single byte, and the same thing happens. 

 

The SW code I'm using: 

 

IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE); 

for ( ;; ){  

printf("\n================================================\n");  

printf("Wait until the RRDY bit in the status register triggers \n");  

do 

{ status = IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE); } 

while ((status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0); 

 

if ((status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) != 0)  

{  

 

alt_u32 rxdata = IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE); //Reading the rxdata register clears the RRDY bit in the status reg

*read_data++ = (char)rxdata;//Store the received bytes 

 

if ((char)rxdata == '(') //end of command byte 

{  

*read_data++ = '\0'; 

break

}  

}
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
455 Views

The Altera spi core has no rx buffer; data would be overwritten if you don't read it before the next byte arrives. 

Check also the receive overrun (ROE) bit in status register.
0 Kudos
Altera_Forum
Honored Contributor II
455 Views

Yes, I want to read the data before the next byte arrives, what should the NiosII SW code look like?  

 

I'm now able to receive and collect bytes when the SPI master is sending a single byte at a time. This makes sense from reading: 

 

"After a word is received by the slave, the master must de-assert the ss_n signal and reasserts the signal again when the next word is ready to be sent."  

(I'm assuming a "word" means a byte (8 bits) in my case). 

 

I guess the SPI master only asserted the ss_n once when sending a sequence of bytes/characters, but I'll check this using SignalTap. 

 

The problem I'm facing now is that the bytes being received on the SPI slave side have a tendency to alternate, I can observe this when the SPI master sends the same byte 4-5 times in a row.  

 

Also, from reading the status register, the receive overrun (ROE) bit is not being asserted.
0 Kudos
Altera_Forum
Honored Contributor II
455 Views

 

--- Quote Start ---  

Yes, I want to read the data before the next byte arrives 

--- Quote End ---  

 

You must read the data before the next byte arrives. 

What's the spi baudrate? You must make sure your Nios is fast enough to keep up with incoming data. 

Otherwise you need to use dma or move to a buffered spi core
0 Kudos
Altera_Forum
Honored Contributor II
455 Views

The SPI master is using 1MHz as the baudrate, while the NiosII is running much faster at 50MHz, so I should be able to read the rxdata before the next byte arrives. Any code sample would be helpfull, since I'm not really a SW developer.

0 Kudos
Altera_Forum
Honored Contributor II
455 Views

I'w started to look into the Qsys SPI in the slave mode again since the issue with inconsistent rx data still hasn't been solved. From using SignalTap, it seems that the data being received/sampled in the SPI shift_reg is quite inconsistent. 

 

It looks like the content of the shift_reg isnt always changing with the falling edge of the spi_clk, which I'm assuming it should. 

 

From the attachment showing SignalTap on the SPI slave rx_holding_reg and shift_reg it can be seen that a single byte (0xBC hex value) is being sent from the external SPI master and the tendency it has to not be sampled correctly in the SPI shift_reg. 

 

At the moment the SPI slave is running on a 75MHz clock, the SPI spi_clk is running @ 1Mhz and the SPI timing is set so that the Clock polarity = 1 and the Clock phase = 1. The Data register width = 8 bits. 

 

Any pointers would be appreciated.
0 Kudos
Altera_Forum
Honored Contributor II
455 Views

Looks like I was able to solve this issue by using the "Synchronizer Stages" option for the SPI component. 

 

By checking the "Insert Synchronizers" and adding a Depth of 2, the data being received is now consistent.
0 Kudos
Reply