SAME70 SPI CSAAT (Chip Select Active After Transfer) doesn't.

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

I'm working with the SAME70 that uses SPI0 to communicate with a graphics processor.   The GFX board has a typical sequence of "write a register address, then read or write one or more byte at that address".  The key point is that chip select needs to stay asserted across those two steps.  However, the GFX library writes the register address with one SPI xfer, and the subsequent data bytes with a second SPI xfer.

 

This seemed like a perfect use case for the SPI0.CSRn.CSAAT bit.  From the documentation:

To facilitate interfacing with [some SPI slave peripherals], the chip select registers [SPI_CSR0...SPI_CSR3] can be programmed with the Chip Select Active After Transfer (CSAAT) bit at 1. This allows the chip select lines to remain in their current state (low = active) until a transfer to another chip select is required. Even if SPI_TDR is not reloaded, the chip select remains active.

But for some reason, NPCS1 is not remaining active between transfers, even though there are no other devices trying to communicate on the SPI bus.  Here's the state of SPI.CSR1 just before performing two consecutive transfers:

 

SPI0.CSR1

 

Here's the code that selects NPCS1 then performs two consecutive transfers:

void write_slice(uint8_t *payload, size_t payload_size) {
  unsigned char preamble[] = {0x00, 0x04, 0x80};

  SPI0_ChipSelectSetup(SPI_CHIP_SELECT_NPCS1);
  SPI0_WriteRead((void *)preamble, sizeof(preamble), NULL, 0);
  SPI0_WriteRead((void *)payload,  payload_size , NULL, 0);
}

And here's the resulting 'scope trace.  Top trace is NPCS1 (chip select, low true), subsequent traces are SCK, MISO, MOSI.  As you can see, NPCS1 de-asserts between the two transfers:

SPI0 transaction

 

I cannot see any particular reason that NPCS1 is de-asserting between transfers.  Does anyone have experience with this?  What am I missing?

 

This topic has a solution.

- rdp

 

Last Edited: Wed. Apr 20, 2022 - 01:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you using the standard SPI function ? Is this hardware SPI or software?

 

Maybe just sending the data in one line instead of two if the gfx doesn’t have to wait. 
I don’t remember now but it usually goes that you need to set the CS and reset after transfer. That I was using the hardware SPI.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> Are you using the standard SPI function ? Is this hardware SPI or software?

 

I'm using the hardware chip select feature.  But I hope I understand your question correctly: CSAAT is only applicable if you are using hardware chip select.

 

But my intrepid Microchip FAE solved the mystery (but uncovered a second): the driver code sets LASTXFER at the end of a transfer, which causes CS to be de-asserted as soon as the last byte (of that transfer) is shipped out.

 

The mystery is: why would the library code go to the trouble to set CSAAT and explicitly negate its effect by setting LASTXFER?  I would opine that either it shouldn't set CSAAT in the first, place, or else it should not set LASTXFER.  I'd prefer the latter, since CSAAT does confer benefits that are harder to duplicate in code. 

 

> Maybe just sending the data in one line instead of two if the gfx doesn’t have to wait. 

 

In my case, I have two buffers of data: a preamble followed by a large block of binary data.  The gfx peripheral needs to get everything in a single transfer -- de-asserting CS resets its internal state.  So CSAAT would be a perfect solution.  Rather than modify the driver code (which I try hard to avoid), my workaround is to memcpy everything into a single buffer -- it works, but with the SPI clock running at 30 MHz (!), this certainly slows things down.

 

Maybe I can convince Microchip to remove the LASTXFER bit...

 

- rdp