SPI Framework chip select
Can someone explain to me how the SPI Framework chip select is supposed to work?
My pxa2xx_spi device does not use a chip_select at all, hence I have no cs_control routine defined in struct pxa2xx_spi_chip.cs_control. I have never understood how chip select is supposed to work in the SPI framework, other than explicit code in the controller driver calling a user defined function, as in pxa2xx_spi.c. I gather there is a mechanism involving the struct spi_board_info.chip_select which selects an index for a chip select at a higher level of the SPI framework. I don't know where the connection is between this and a physical GPIO line connected to an external chip.
Also, in connection with the Framework chip select mechanism, I have never understood, even if a correspondence is made between a spi_board_info.chip_select index and a physical IO line, how that CS is supposed to know when to change state. It is clear in pxa2xx_spi.c that when a user supplied cs_control function is called, the appropriate action defined in the function will take place. However, the null_cs_control routine in pxa2xx_spi.c, which is called if the user does not specify a routine in struct pxa2xx_spi_chip.cs_control, simply returns without calling any function defined in the SPI framework.
Dave, can you shed light for me?
Signature · 13 lines
Ned Forrester nforrester-/[email protected] Oceanographic Systems Lab 508-289-2226 Applied Ocean Physics and Engineering Dept. Woods Hole Oceanographic Institution Woods Hole, MA 02543, USA http://www.whoi.edu/sbl/liteSite.do?litesiteid=7212 http://www.whoi.edu/hpb/Site.do?id=1532 http://www.whoi.edu/page.do?pid=10079 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
A message that is not in the archive (sent off-list or not yet received): 47C85451.1030809-/[email protected]
Quoted 8 lines · Ned Forrester
Can someone explain to me how the SPI Framework chip select is supposed to work?
My
pxa2xx_spidevice does not use achip_selectat all, hence I have nocs_controlroutine defined in struct pxa2xx_spi_chip.cs_control. I have never understood how chip select is supposed to work in the SPI framework, other than explicit code in the controller driver calling a user defined function, as inpxa2xx_spi.c.
That's specific to that driver. PXA doesn't talk "native SPI" but does so with some external assistance ... like those callbacks.
Quoted 5 lines
I gather there is a
mechanism involving the struct spi_board_info.chip_select which selects an index for a chip select at a higher level of the SPI framework. I don't know where the connection is between this and a physical GPIO line connected to an external chip.
SPI involves three signal lines -- MOSI, MISO, SCK -- all of which are conceptually gated by a chipselect line (active low, usually).
So a transfer begins by setting those lines to their initial state, then activating the chipselect and starting a bunch of clock cycles that transfer data bits. And the transfer ends when the chipselect is de-activated.
There are some variations to that sequence ... stuff like chipselect being active high is rare, but sometimes there are dedicated busses that don't use a chipselect at all. Sometimes a chipselect doesn't quite gate signals but instead acts as another signal line ... JTAG has TMS, which sometimes gates state transitions, and MMC in its "SPI" variant has a few cases that require clocks be sent to devices when their chips are deselected.
Quoted 4 lines
Also, in connection with the Framework chip select mechanism, I have never understood, even if a correspondence is made between a spi_board_info.chip_select index and a physical IO line, how that CS is supposed to know when to change state.
Primarily, it changes at the begining and end of a message. Some transfers may require temporary mid-message deselection ... for example, if the SPI device has commands to write (tx command then tx data) and read (tx command then rx data) that are terminated by chip deselect, it can be important to issue an un-interrupted series of writes and reads. (That's what spi_transfer.cs_change assists.)
Quoted 7 lines
It is clear in
pxa2xx_spi.c
that when a user suppliedcs_controlfunction is called, the appropriate action defined in the function will take place. However, thenull_cs_controlroutine inpxa2xx_spi.c, which is called if the user does not specify a routine in struct pxa2xx_spi_chip.cs_control, simply returns without calling any function defined in the SPI framework.
I'd sure hope the null_cs routine is only used for dedicated busses ... it sure can't be correct when there are two or more devices on the bus.
- Dave
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
A message that is not in the archive (sent off-list or not yet received): 200802291204.33911.david-b-yBeKhBN/[email protected]
Quoted 4 lines · David Brownell
Quoted 3 lines · Ned Forrester
Can someone explain to me how the SPI Framework chip select is supposed to work?
Quoted 8 lines
Quoted 5 lines
My
pxa2xx_spidevice does not use achip_selectat all, hence I have nocs_controlroutine defined in struct pxa2xx_spi_chip.cs_control. I have never understood how chip select is supposed to work in the SPI framework, other than explicit code in the controller driver calling a user defined function, as inpxa2xx_spi.c.That's specific to that driver. PXA doesn't talk "native SPI" but does so with some external assistance ... like those callbacks.
I know, but are you saying that there is something limiting in the PXA architecture that requires the "external assistance" provided by the cs_control function in pxa2xx_spi.c, or are you saying that pxa2xx_spi.c chooses to implement chip select this way, but could use something higher up in the framework?
Quoted 8 lines
Quoted 5 lines
I gather there is a
mechanism involving the struct spi_board_info.chip_select which selects an index for a chip select at a higher level of the SPI framework. I don't know where the connection is between this and a physical GPIO line connected to an external chip.SPI involves three signal lines -- MOSI, MISO, SCK -- all of which are conceptually gated by a chipselect line (active low, usually).
I thought the chip select, when used, is not conceptual, but is a physical wire, and a separate one for each chip on the SPI bus.
So where does spi_board_info.chip_select enter the picture?
Sorry to be so dense, but I figured spi_board_info.chip_select was a flag to higher level code to request that a certain CS be manipulated. Is this just a flag for the sole use of the controller driver in doing whatever is needed to manipulate dedicated CS lines?
Quoted 11 lines
Quoted 4 lines
Also, in connection with the Framework chip select mechanism, I have never understood, even if a correspondence is made between a spi_board_info.chip_select index and a physical IO line, how that CS is supposed to know when to change state.
Primarily, it changes at the begining and end of a message. Some transfers may require temporary mid-message deselection ... for example, if the SPI device has commands to write (tx command then tx data) and read (tx command then rx data) that are terminated by chip deselect, it can be important to issue an un-interrupted series of writes and reads. (That's what spi_transfer.cs_change assists.)
But what makes it change if there is no explicit function changing something? I don't see any functions to call in spi.c or spi.h that utilize spi_board_info.chip_select.
Does some hardware provide a bunch of dedicated chip select pins that the controller driver must manipulate as required?
If so, is spi_board_info.chip_select just an selection index used only by the controller driver to tell it which dedicated pin to use?
Quoted 11 lines
Quoted 7 lines
It is clear in
pxa2xx_spi.c
that when a user suppliedcs_controlfunction is called, the appropriate action defined in the function will take place. However, thenull_cs_controlroutine inpxa2xx_spi.c, which is called if the user does not specify a routine in struct pxa2xx_spi_chip.cs_control, simply returns without calling any function defined in the SPI framework.I'd sure hope the
null_csroutine is only used for dedicated busses ... it sure can't be correct when there are two or more devices on the bus.
Well, that is what I am trying to figure out. If my above, newest assumptions are correct, then I guess that for PXA, there is no other way than struct pxa2xx_spi_chip.cs_control to specify which GPIO pin to manipulate, as there are so many to choose from, and they might be controlled by other drivers.
If there is hardware that has specific, dedicated pins for chip selects, and those pins are always known to be under the sole control of the controller driver, then I guess that would explain why spi_board_info.chip_select is useful in those cases.
If the above is true, then it would certainly be an error to pass NULL cs_control functions to pxa2xx_spi.c, if there is more than one chip on the bus.
Sorry to go on about this, but I have been confused about this for a while. Maybe PXA was a degenerate example to start with.
Signature · 13 lines
Ned Forrester nforrester-/[email protected] Oceanographic Systems Lab 508-289-2226 Applied Ocean Physics and Engineering Dept. Woods Hole Oceanographic Institution Woods Hole, MA 02543, USA http://www.whoi.edu/sbl/liteSite.do?litesiteid=7212 http://www.whoi.edu/hpb/Site.do?id=1532 http://www.whoi.edu/page.do?pid=10079 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
A message that is not in the archive (sent off-list or not yet received): 47C870D5.7000109-/[email protected]
Quoted 11 lines · Ned Forrester
Quoted 10 lines · David Brownell
Quoted 8 lines · Ned Forrester
Can someone explain to me how the SPI Framework chip select is supposed to work?
My
pxa2xx_spidevice does not use achip_selectat all, hence I have nocs_controlroutine defined in struct pxa2xx_spi_chip.cs_control. I have never understood how chip select is supposed to work in the SPI framework, other than explicit code in the controller driver calling a user defined function, as inpxa2xx_spi.c.
Quoted 6 lines
Quoted 2 lines
That's specific to that driver. PXA doesn't talk "native SPI" but does so with some external assistance ... like those callbacks.
I know, but are you saying that there is something limiting in the PXA architecture that requires the "external assistance" provided by the
cs_controlfunction inpxa2xx_spi.c,
It's the *SSP controllers that have the limitation. It's been a while since I looked at it, but as I recall ... the closest they come to a real chipselect is a single "frame" signal, which doesn't quite meet the requirement even for most single-chip busses.
Quoted 3 lines
or are you saying that
pxa2xx_spi.c
chooses to implement chip select this way, but could use something higher up in the framework?
Chipselect management goes along with queue management; it's all below the covers, so far as a protocol driver is concerned.
Quoted 11 lines
Quoted 8 lines
Quoted 5 lines
I gather there is a
mechanism involving the struct spi_board_info.chip_select which selects an index for a chip select at a higher level of the SPI framework. I don't know where the connection is between this and a physical GPIO line connected to an external chip.SPI involves three signal lines -- MOSI, MISO, SCK -- all of which are conceptually gated by a chipselect line (active low, usually).
I thought the chip select, when used, is not conceptual, but is a physical wire, and a separate one for each chip on the SPI bus.
When used, it's not conceptual. But recall the various exceptions I listed, including a bus with one device and no chipselect... as well as the more problematic variants like MMC and JTAG.
Quoted 1 line
So where does spi_board_info.chip_select enter the picture?
On a SPI bus that has multiple slaves, each one has its own chip select number. (I'm treating "daisy chained" slaves as a single slave, although its driver might expose internal structure.)
Quoted 4 lines
Sorry to be so dense, but I figured spi_board_info.chip_select was a flag to higher level code to request that a certain CS be manipulated. Is this just a flag for the sole use of the controller driver in doing whatever is needed to manipulate dedicated CS lines?
It's interpreted by the controller driver. The protocol drivers don't change it; it's part of the board configuration. When there are six different chip select lines, each has its own spi_device. (And the spi_board_info morphs into that spi_device.)
Quoted 12 lines
Quoted 11 lines
Quoted 4 lines
Also, in connection with the Framework chip select mechanism, I have never understood, even if a correspondence is made between a spi_board_info.chip_select index and a physical IO line, how that CS is supposed to know when to change state.
Primarily, it changes at the begining and end of a message. Some transfers may require temporary mid-message deselection ... for example, if the SPI device has commands to write (tx command then tx data) and read (tx command then rx data) that are terminated by chip deselect, it can be important to issue an un-interrupted series of writes and reads. (That's what spi_transfer.cs_change assists.)
Quoted 3 lines
But what makes it change if there is no explicit function changing something? I don't see any functions to call in
spi.corspi.hthat utilize spi_board_info.chip_select.
The spi_board_info is used only to create a spi_device.
A SPI master controller is responsible for managing the spi_device.chip_select when it starts to perform the spi_message interactions with a given spi_device.
Quoted 2 lines
Does some hardware provide a bunch of dedicated chip select pins that the controller driver must manipulate as required?
Yes. And in PXA those chipselects are normally implemented using GPIO lines.
Quoted 2 lines
If so, is spi_board_info.chip_select just an selection index used only by the controller driver to tell it which dedicated pin to use?
Well, spi_device.chip_select ... but otherwise, yes.
Quoted 12 lines
Quoted 11 lines
Quoted 7 lines
It is clear in
pxa2xx_spi.c
that when a user suppliedcs_controlfunction is called, the appropriate action defined in the function will take place. However, thenull_cs_controlroutine inpxa2xx_spi.c, which is called if the user does not specify a routine in struct pxa2xx_spi_chip.cs_control, simply returns without calling any function defined in the SPI framework.I'd sure hope the
null_csroutine is only used for dedicated busses ... it sure can't be correct when there are two or more devices on the bus.
Quoted 5 lines
Well, that is what I am trying to figure out. If my above, newest assumptions are correct, then I guess that for PXA, there is no other way than struct pxa2xx_spi_chip.cs_control to specify which GPIO pin to manipulate, as there are so many to choose from, and they might be controlled by other drivers.
Right. They might go through an FPGA for example, instead of the PXA's own GPIO registers.
Quoted 4 lines
If there is hardware that has specific, dedicated pins for chip selects, and those pins are always known to be under the sole control of the controller driver, then I guess that would explain why spi_board_info.chip_select is useful in those cases.
The chipselect number is always useful when the SPI bus has more than one slave; it's how the slaves are distinguished.
Quoted 6 lines
If the above is true, then it would certainly be an error to pass NULL
cs_controlfunctions topxa2xx_spi.c, if there is more than one chip on the bus.Sorry to go on about this, but I have been confused about this for a while. Maybe PXA was a degenerate example to start with.
There's enough of degeneracy in the world to go around. :)
What's slightly odd about PXA is just that the *ONLY* sane way to handle chipselects involves not using the *SSP controllers. Most other systems have a few dedicated lines managed by the controller; but that's because they manage SPI, rather than just being multipurpose serial link controllers.
_ Dave
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
A message that is not in the archive (sent off-list or not yet received): 200802291338.55149.david-b-yBeKhBN/[email protected]
Quoted 9 lines · David Brownell
Quoted 2 lines · Ned Forrester
Quoted 1 line · David Brownell
On Friday 29 February 2008, Ned Forrester wrote:
The
spi_board_infois used only to create aspi_device.A SPI master controller is responsible for managing the spi_device.chip_select when it starts to perform the
spi_messageinteractions with a givenspi_device.
Oops, I forgot to distinguish between spi_board_info (used once) and spi_device (used always). Understood.
Quoted 5 lines
Quoted 2 lines
Does some hardware provide a bunch of dedicated chip select pins that the controller driver must manipulate as required?
Yes. And in PXA those chipselects are normally implemented using GPIO lines.
OK, this is the missing link that I never realized before. I could never figure out how a master driver could know what to do with a chip select index, having no other clues. I did not know that some hardware has multiple dedicated CS pins. Understood now.
Quoted 4 lines
Quoted 2 lines
If so, is spi_board_info.chip_select just an selection index used only by the controller driver to tell it which dedicated pin to use?
Well, spi_device.chip_select ... but otherwise, yes.
Right. Got it, I mixed up spi_board_info and spi_device again.
Quoted 7 lines
Quoted 4 lines
If there is hardware that has specific, dedicated pins for chip selects, and those pins are always known to be under the sole control of the controller driver, then I guess that would explain why spi_board_info.chip_select is useful in those cases.
The chipselect number is always useful when the SPI bus has more than one slave; it's how the slaves are distinguished.
Ahh... Here is a place where pxa2xx-spi departs from the SPI framework by choice. That driver never uses spi_device.chip_select because each chip supplies its own private struct pxa2xx_spi_chip.cs_control at board setup time, passed as struct spi_board_info.controller_data, registered with spi_register_board_info(), and retrieved by pxa2xx_spi.c using spi->controller_data. I gather you can register one of these for each chip attached to the spi bus.
Thus the driver gets the cs_control function attached to each spi_device.controller_data. This data can be manipulated by the protocol driver, if needed, to adjust the various private device parameters in that structure, which could include cs_control(). The driver retrieves this information from spi_device (actually from a private structure attached to spi_device.controller_state and initialized in setup()) each time a message is processed.
[It makes my head hurt to trace this out :-) ]
Because each chip needs its own, unique cs_control() function, and this function pointer is available at message time, there is no need for pxa2xx_spi.c to use the spi_device.chip_select field to distinguish the CS functions.
I suppose that it could alternatively been implemented by storing the cs_control pointers in an array during setup(), and then using the index in spi_device.chip_select to access the various functions. Either way seems to work.
Thanks for clearing this up. I understand now.
Signature · 13 lines
Ned Forrester nforrester-/[email protected] Oceanographic Systems Lab 508-289-2226 Applied Ocean Physics and Engineering Dept. Woods Hole Oceanographic Institution Woods Hole, MA 02543, USA http://www.whoi.edu/sbl/liteSite.do?litesiteid=7212 http://www.whoi.edu/hpb/Site.do?id=1532 http://www.whoi.edu/page.do?pid=10079 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
A message that is not in the archive (sent off-list or not yet received): 47C88793.1050205-/[email protected]
Quoted 7 lines · Ned Forrester
Quoted 2 lines · David Brownell
The chipselect number is always useful when the SPI bus has more than one slave; it's how the slaves are distinguished.
Ahh... Here is a place where pxa2xx-spi departs from the SPI framework by choice. That driver never uses spi_device.chip_select
Not directly. Indirectly, since each chip_select is associated with a unique pxa2xx_spi_chip.cs_control(). The chipselect number (and signal) still distinguishes chips from each other.
Quoted 4 lines
I suppose that it could alternatively been implemented by storing the
cs_controlpointers in an array duringsetup(), and then using the index in spi_device.chip_select to access the various functions. Either way seems to work.
Right. The pxa2xx_spi driver could use any scheme to manage the chipselect signals, so long as each number maps to a unique signal.
- Dave
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
A message that is not in the archive (sent off-list or not yet received): 200803011237.51349.david-b-yBeKhBN/[email protected]
Quoted 11 lines · David Brownell
Quoted 6 lines · Ned Forrester
Quoted 2 lines · David Brownell
The chipselect number is always useful when the SPI bus has more than one slave; it's how the slaves are distinguished.
Ahh... Here is a place where pxa2xx-spi departs from the SPI framework by choice. That driver never uses spi_device.chip_select
Not directly. Indirectly, since each
chip_selectis associated with a uniquepxa2xx_spi_chip.cs_control(). The chipselect number (and signal) still distinguishes chips from each other.
Maybe we're just discussing semantics, but the last sentence does not apply to this driver. pxa2xx_spi.c never references the field spi_device.chip_select. The string "chip_select" appears nowhere in the code. You can assign spi_device.chip_select=0 for all chips, and as long as you supply a unique spi_device->controller_data->pxa2xx_spi_chip.cs_control for each chip, chip select will work as intended.
So in the sense that I mean, spi_device.chip_select field is unused; it does not need to be unique between chips. Yes, of course there have to be unique spi_device structures for each chip, and through a driver private means (spi_device.controller_data) the chip select mechanism for each chip becomes known to the driver.
It was this lack of example for any use of spi_device.chip_select in pxa2xx_spi.c that led to my confusion about how spi_device.chip_select was supposed to be used.
Signature · 13 lines
Ned Forrester nforrester-/[email protected] Oceanographic Systems Lab 508-289-2226 Applied Ocean Physics and Engineering Dept. Woods Hole Oceanographic Institution Woods Hole, MA 02543, USA http://www.whoi.edu/sbl/liteSite.do?litesiteid=7212 http://www.whoi.edu/hpb/Site.do?id=1532 http://www.whoi.edu/page.do?pid=10079 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
A message that is not in the archive (sent off-list or not yet received): 47C9FF5E.5060503-/[email protected]
Quoted 4 lines · Ned Forrester
You can assign spi_device.chip_select=0 for all chips, and as long as you supply a unique
spi_device->controller_data->pxa2xx_spi_chip.cs_controlfor each chip, chip select will work as intended.
The SPI core would reject such an atrocity. :)
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
A message that is not in the archive (sent off-list or not yet received): 200803011858.14400.david-b-yBeKhBN/[email protected]
Quoted 7 lines · David Brownell
Quoted 4 lines · Ned Forrester
You can assign spi_device.chip_select=0 for all chips, and as long as you supply a unique
spi_device->controller_data->pxa2xx_spi_chip.cs_controlfor each chip, chip select will work as intended.The SPI core would reject such an atrocity. :)
Well, if you are sure, I suppose it must be somewhere. I could only find a check for chip->chip_select >= master->num_chipselect in spi_new_device(), but not any comparison between chp_select values of different chips. Probably I don't know where to find all the files of the SPI core.
Signature · 13 lines
Ned Forrester nforrester-/[email protected] Oceanographic Systems Lab 508-289-2226 Applied Ocean Physics and Engineering Dept. Woods Hole Oceanographic Institution Woods Hole, MA 02543, USA http://www.whoi.edu/sbl/liteSite.do?litesiteid=7212 http://www.whoi.edu/hpb/Site.do?id=1532 http://www.whoi.edu/page.do?pid=10079 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/