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++
12590 Discussions

Cyclone V SPI master releases chip select when TX FIFO runs empty. HOW TO PREVENT???

Altera_Forum
Honored Contributor II
2,926 Views

Hi, I have noticed that the Cyclone V SPI master releases chip select when TX FIFO runs empty.  

 

I use Linux kernel 4.1, but the spi-dw driver is pretty much the same as in the latest kernel.  

The SPI controller pull chip select low and starts transferring immediately after the first byte is written to the TX FIFO. Chip select is released when all data from the TX FIFO is transmitted. Usually this works fine, except when an interrupt occurs before all data is written to the TX FIFO and the TX FIFO runs out of data. Chip select is then released and the message is aborted from the slave device's point of view. The chip select is again pulled down when the writing to the TX FIFO resumes after returning from the interrupt, which can be taken for a valid command by the slave device...  

 

I have found a workaround, which is disabling of all interrupts during SPI transmission, but I would definitely prefer something less dramatic. 

 

Note, this problem is present both for interrupt and polled mode. 

 

Is there any way to stop the SPI controller from releasing the chip select when the TX FIFO runs empty? To me, it looks like an major SPI controller bug, unless this is a desired feature...
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
1,740 Views
0 Kudos
Altera_Forum
Honored Contributor II
1,740 Views

Thanks for the replay sunshine! 

I have seen that trick, but it does not solve my problem. By testing that workaround, it looked like Altera defines a transaction as transmitting all bytes in the FIFO until it runs empty. Which is exactly my problem. The default, without the workaround is toggling CS for every byte... 

I found a solution which is not only working for Cyclone V, but is also supported by the generic part of the SPI driver in Linux.  

It's as simple as using GPIO as CS.  

I simply pull down GPIO CS giving me all the time in the world to enable the HW SPI master, fill upp the FIFO. Finally select a CS controlled by the SPI Master, which is either an unused HPS pin or is terminated in the FPGA. 

The SPI FIFO can run empty many times, while I decide when to release the GPIO CS.
0 Kudos
Altera_Forum
Honored Contributor II
1,740 Views

That is a nice workaround you have there :) Do you need to change anything in the driver to achieve this?

0 Kudos
Altera_Forum
Honored Contributor II
1,740 Views

I did. The SPI clock (at least in my case) was initially low causing the first transfer to fail. So I added sending of one byte without the GPIO CS enable in the driver setup function. From then on the clock is always high prior to a transaction. 

 

I also made a modification of the spi_transfer_one_message function and added it to the spi-dw.c driver. I simply merged the two spi transfers (write and read) into a single transfer. This require that drivers such as m25p80 has to be modified, but this is outside the scope of this issue. It is purely for optimization.
0 Kudos
Altera_Forum
Honored Contributor II
1,740 Views

Thanks for sharing. I imagine that there must be others who faced the same issue as well.

0 Kudos
Altera_Forum
Honored Contributor II
1,740 Views

Hi Both, 

 

I am facing similar issue with Arria10 HPS SPI. I have posted it here : https://alteraforum.com/forum/showthread.php?t=58518&p=237972#post237972  

 

Any suggestion on this ? Thanks in advance.
0 Kudos
Altera_Forum
Honored Contributor II
1,740 Views

The CS getting de-selected when the TX FIFO becomes empty is as expected. 

In the Cyclone V Handbook Vol# 3, SPI section (19) in the "Master SPI and SSI transfer" sub-section: 

 

when the transfer mode is “transmit and receive” or “transmit only” (tmod = 0 or 

tmod = 1, respectively), transfers are terminated by the shift control logic when the 

transmit fifo buffer is empty. for continuous data transfers, you must ensure that the 

transmit fifo buffer does not become empty before all the data have been 

transmitted. 

 

The only real "work-around" is: 

you must ensure that the transmit fifo buffer does not become empty before all the data have been transmitted.
0 Kudos
Altera_Forum
Honored Contributor II
1,740 Views

 

--- Quote Start ---  

The CS getting de-selected when the TX FIFO becomes empty is as expected. 

In the Cyclone V Handbook Vol# 3, SPI section (19) in the "Master SPI and SSI transfer" sub-section: 

 

when the transfer mode is “transmit and receive” or “transmit only” (tmod = 0 or 

tmod = 1, respectively), transfers are terminated by the shift control logic when the 

transmit fifo buffer is empty. for continuous data transfers, you must ensure that the 

transmit fifo buffer does not become empty before all the data have been 

transmitted. 

 

The only real "work-around" is: 

you must ensure that the transmit fifo buffer does not become empty before all the data have been transmitted. 

--- Quote End ---  

 

 

Hi Eric, thanks for the reply. I tried, polling method. Filled the TX FIFO with 32 bytes and then enabled the chip select. But still I am seeing chip select to toggle after each byte in cscope. I am using Arria10 and linux kernel.  

 

 

I would like to transfer a byte and read two bytes in the same transfer. I also tried filling TX FIFO, while reading RX data. TX FIFO level remained non-zero, but still CS toggled in scope.
0 Kudos
Altera_Forum
Honored Contributor II
1,740 Views

I am not sure what you mean by enabling the CS because there is no such control in the SPI. 

Do you mean setting the slave to select in the SER register? 

If so, this does not directly lower the CS. 

It's the controller that will drive the 4 CS lines with the inverse of the SER register when the transfer is started. 

 

The CS goes low When the first frame is written in the TX FIFO and stays low until the FIFO is empty. 

 

It's explained in the handbook (SPI master section / data transfer subsection: 

 

The SPI master starts data transfers when all the following conditions are met: 

■ The SPI master is enabled 

■ There is at least one valid entry in the transmit FIFO buffer 

■ A slave device is selected 

 

What are you checking when polling? 

The FIFO level, or the status register bit indicating the TX FIFO empty, or the one indicating the TX FIFO full? 

 

If you are sending less than 256 frames there are no needs to do any check. 

Do non-stop writes, the FIFO will absorb all the data.
0 Kudos
rcc
Beginner
1,704 Views

I would like to dust off this thread and provide some observations I have made over the past couple of days of troubleshooting.

I am using the HPS SPI master to communicate with a slave device that requires the chip select to remain asserted during the entirety of a read or write transaction.  I too came across the issue of the SPI controller de-asserting the chip select after each byte.  A transaction with the slave device occurs as follows, one byte of opcode is sent by the master to tell the slave device what address is being accessed, as well as if the transaction is a read or write, then 2 bytes of data are sent.  All of this happens while the chip select is asserted.

I have found that at higher baud rates the SPI controller is unable to keep the chip select asserted if anything other than a 16-bit transfer is selected.  In the Intel Cyclone V HPS tech reference (page 20-18) it states that there are 2 SPI modes that support continuous transfer.  The mode with SCPH = 1 and SCPOL = 1 asserts the slave select for the duration of the transfer.  Again, at higher bit rates this does not appear to work for transfers that are not 16-bits.

I have attached logic analyzer screen captures showing the SPI interface running with an SCK of 5MHz and 10MHz, 8-bit and 16-bit transfers.  You can see that at 10MHz the chip select is de-asserted for an 8-bit transfer, but held asserted for 16-bits.  At 5MHz the chip select remains asserted for the entire transfer.  This is fine for my application, I can deal with the lower bit rate.  And I don't have to substitute a GPIO to accomplish the same thing. 

I hope this information is helpful.  If someone can verify this and reply that would be great.

0 Kudos
Reply