Long transfers on SPI peripheral

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Long transfers on SPI peripheral

2,353 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MindBender on Mon Jul 20 06:53:03 MST 2015
We need to interface the LPC1785 I selected as a slave to an existing SPI bus. We're not doing anything special: The SPI master activates our SSEL line by lowering it, clocks out a frame of data, and deactivates our SSEL line afterwared.

However, while studying the User Manual to see how we can achieve this, I have noticed something odd: The SPI peripheral supports multiple frame types, and frame sizes from 4...16 bits. I kind'a assumed that the term frame here was used to define the number of data bits, configuring we're always transmitting a multiple of 8 bits.

But now I'm looking at the illustrations, it seems that frame refers to all data between activating and deactivating SSEL. This would not only mean that the frame length needs to be known in advance, but also that we cannot transfer more than 16 bits at a time. Or am I reading this incorrectly?

The SPI bus on our existing application transfers frames of many bytes long, where activating SSEL designates the beginning of a frame. Nothing uncommon in my opinion, but if I understood the manual correctly, this is something I cannot implement with the LPC1785, or am I missing something?
Labels (1)
0 Kudos
9 Replies

1,617 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MindBender on Sat Jul 25 01:20:15 MST 2015

Quote: rocketdawg
I do not think that is necessarily true.  The Master may use SSEL as a message separation mechanism.  The slave must then be aware the use of SSEL as a message separation mechanism.  If they agree, then it can be done.

Many dumb slave devices use their SSEL input to separate messages; An SSEL activation is regarded as the start of a message. But the LPC slave hardware doesn't seem to offer a mechanism to communicate this event to software. To software it's just an endless stream of bytes coming in and going out, without message separation. Of coarse this could be simply fixed by adding a gpio pin in parallel to the SSEL input and perhaps that's what the designers had in mind.


Quote: rocketdawg
I am a little worried about your soft addressing scheme.

Me too, but it was decided before my time and now all of our instruments use it. So for backwards compatibility reasons, we have to keep it in and implement it in our of our slaves. But all of our SPI slaves are CPUs, so it's not that bad.


Quote: rocketdawg
Remember that SPI is just a shift register mechanism.  All slaves that are selected will attempt to shift out a bit on their output when they receive a bit on their input.

That's why I need to keep MISO tri-stated until I have read and verified the address byte. Fortunately MISO can be tri-stated explicitly, so that's no problem.

On my earlier question if SSEL is simply enabling listening, I can confirm that it is NOT. The CPOL/CPHA combinations that require SSEL to go inactive between frames in master mode, also require this in slave mode. Without that, the last bit won't be clocked in.

1,617 Views
bmcdonnell_ionx
Contributor III

MindBender‌,

What did you wind up doing for this? Bit banging?

0 Kudos

1,617 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rocketdawg on Wed Jul 22 12:55:57 MST 2015

Quote: MindBender
So if I understand you correctly, in slave mode SSEL simply enables listening? And there's no way I can use it for message separation? I'd better put an interrupt capable GPIO line in parallel then.



I do not think that is necessarily true.  The Master may use SSEL as a message separation mechanism.  The slave must then be aware the use of SSEL as a message separation mechanism.  If they agree, then it can be done.

I am a little worried about your soft addressing scheme.  Remember that SPI is just a shift register mechanism.  All slaves that are selected will attempt to shift out a bit on their output when they receive a bit on their input.  So you have multiple slaves trying to control the MISO for that first addressing byte.  (unless you put it into 3 wire mode, then switch to 4 wire mode and have no glitches).  So all the slaves must output the same value for that first byte, probably 0x00, otherwise you have different devices trying to drive the buss to different states.  After that first byte, each non selected slave SPI must be disabled and pins set to inputs, so that it will not try to talk on the bus.  Then each slave has to enable the SPI after SSEL goes high to be able to see the next soft address message.

Maybe it will work if you have total control of the slave programming.
0 Kudos

1,617 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MindBender on Wed Jul 22 05:45:51 MST 2015

Quote: wmues
Setting up DMA if SSEL is activated is too late, I assume. (I don't know your data rate).

I'm afraid I cannot use DMA anyway; Due to a shortage of CS lines, we started to share CS lines together with proprietary soft-addressing: If our slave's SSEL is inactive, we should ignore any data. But if it's active, the first byte after activation is a soft-address byte, which we need to match with our own soft-address. If it doesn't match, we should ignore the message, but if it does the message is for us and we can must MISO out or tri-state.

Quote: wmues
In slave mode, SSEL is simple a qualifier for data transfer.

So if I understand you correctly, in slave mode SSEL simply enables listening? And there's no way I can use it for message separation? I'd better put an interrupt capable GPIO line in parallel then.
0 Kudos

1,617 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wmues on Tue Jul 21 08:55:16 MST 2015

Setting up DMA if SSEL is activated is too late, I assume. (I don't know your data rate).
0 Kudos

1,617 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MindBender on Tue Jul 21 02:11:30 MST 2015

Quote: wmues
Please do not mix slave mode with master mode.

I didn't mix them up; I just assumed that according to the timing diagrams, our existing master must release the LPC slave's SSEL between frames in order to have the LPC slave work correctly.


Quote: wmues
In master mode, the SPI can handle the SSEL (chip select) automatic. The SSEL is active for the duration of 1 word (4-16 bit).
If you write another word into the SPI data register while the last transfer is running, the SSEL line stays low between 2 words.
But: this is not reliable, because interrupts and/or DMA transfers may delay the writing into SPI data register.

So, in master mode, it is the best to handle SSEL by hand.

That's a nice caveat indeed. We're not using master mode on the LPC for now, but I'll try to remember it in case we do.


Quote: wmues
In slave mode, SSEL is simple a qualifier for data transfer.

So our existing master doesn't need to deactivate and reactivate the LPC slave's SSEL in between frames?
If SSEL is just a simple qualifier, that does mean that it's not really suitable to indicate the start of a datagram. But that is how it is currently used. I suppose I have to connect an extra GPIO to it, to get an interrupt when it is activated and deactivated, allowing me to separate datagrams.


Quote: wmues
If you want to transfer a block of data, you might want to use DMA to transfer the incomming data into memory. You may connect the SSEL to a GPIO port and fire an interrupt at the end of the block.

Exactly, great idea.


Quote: wmues
In the interrupt, you setup the DMA for the next block. If each block has the same length, you might use the DMA interrupt. (I WOULD NOT DO THAT. It's a loss of handshaking!)

I'll see if I can get it working by polling the registers first. After that I'll use interrupts and when that is working, I'll add DMA. Probably as you suggested: Setup DMA when SSEL is activated, disable DMA an notify the rest of the application when SSEL is de-activated.


Quote: wmues
You may need some sort of handshaking to signal the master that the interrupt handling is done. Or you define a maximum time for interrupt handling, and the master sends the next block without handshaking.

Our application is not that complecated; We only need to listen, for now.

Thanks guys!
0 Kudos

1,617 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wmues on Tue Jul 21 00:21:34 MST 2015
Please do not mix slave mode with master mode.

In master mode, the SPI can handle the SSEL (chip select) automatic. The SSEL is active for the duration of 1 word (4-16 bit).
If you write another word into the SPI data register while the last transfer is running, the SSEL line stays low between 2 words.
But: this is not reliable, because interrupts and/or DMA transfers may delay the writing into SPI data register.

So, in master mode, it is the best to handle SSEL by hand.

In slave mode, SSEL is simple a qualifier for data transfer. If you want to transfer a block of data, you might want to use DMA to transfer the incomming data into memory. You may connect the SSEL to a GPIO port and fire an interrupt at the end of the block.
In the interrupt, you setup the DMA for the next block. If each block has the same length, you might use the DMA interrupt. (I WOULD NOT DO THAT. It's a loss of handshaking!)

You may need some sort of handshaking to signal the master that the interrupt handling is done. Or you define a maximum time for interrupt handling, and the master sends the next block without handshaking.
0 Kudos

1,617 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rocketdawg on Mon Jul 20 09:28:29 MST 2015
For large transfers, one might consider DMA.  That leaves the CPU to do other important stuff while the DMA works in the background.
0 Kudos

1,617 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MindBender on Mon Jul 20 07:58:20 MST 2015
It seems that continuous transfer is possible in CPOL=0 CPHA=1 mode. The last paragraph of section 21.5.2.3 says: "For continuous back-to-back transfers, the SSEL pin is held LOW between successive data words and termination is the same as that of the single word transfer." It's easily overlooked, because it's just on the next page, and the illustrating timing diagram still specifies 4 to 16 bits, but this seems to do what we need.

The same goes for CPOL=1, CPHA=1 mode.
0 Kudos