Based on NightmareTony's response, which is pretty ambiguous to what he's responding to, I admit, I think there is a critical misunderstanding about what SPI is, and how it is to be used.
I apologize now if I misunderstood.
SPI is nothing more than a communications channel. On the OSI networking stack, it literally occupies "layer 1," the physical layer. It specifies how individual bits are transferred. One element of layer 2 is provided: distinguishing one message from another is performed by monitoring the device's _CS signal. Still though, I think we can safely say that it is a layer-1 technology.
One communicates over SPI by sending and receiving messages. Messages may or may not be abstract in nature -- many SPI devices map internal registers directly into an SPI message, for example. But, this is an implementation detail, knowledge that is of concern only to a device driver, and not to SPI in and of itself.
SPI operates in a fully synchronous manner. The SPI "master" is responsible for clocking bits into or out of a slave. Note that for every bit transmitted, precisely one bit is received; hence, the SPI controller properly transceives data -- there is (at layer-1's level of abstraction) no concept of sending or receiving data.
By convention, data is transmitted in 8-bit chunks. However, SPI's characteristics do not dictate an 8-bit word size. Ultimately, it is just a raw bit-stream, with the first bit of a message signalled by the assertion of _CS, and the final bit by its negation.
While the SPI controller and the slave interface operate fully synchronously, the peripherals themselves may operate asynchronously. In general, peripherals aren't useful otherwise. A video controller needs to operate asynchronously to update the screen while the CPU is off doing something else (otherwise, you end up with a computer whose sophistication and power only barely can exceed that of an Atari 2600, which drives the display via the CPU). A disk controller must operate asynchronously because it takes MUCH longer to write or read bits of data from a magnetic surface than from RAM. Etc.
Hence, you must think of the SPI bus as an extension of the CPU's address bus. In my observations on SPI peripherals so far, about half of them expose peripheral registers that normally would appear in a memory map, but inside a message. Hence, a message consists of an array of values, with value 0 corresponding to register 0, value 1 corresponding to register 1, etc. The other half consists of a master/slave arrangement, where the host sends the peripheral command messages, and expects a response back. But this, too, is how devices like IDE and SCSI work, again, via registers in the CPU's address space. I suppose the client/server model is just a specialization of the former case.
A third mode, where messages are sent with a proper layer-2 protocol like ATM or X.25, is very definitely possible, but I have not seen them yet. I was considering using this mode of operation for Kestrel's expansion system, but decided against it, choosing instead a more Firewire-like approach, where the CPU transmits virtual peek/poke messages into a peripheral's virtual address space. That gives me the ability to support autoconfiguration, ROM-resident device drivers, and normal peripheral control all basically for free -- but this is a topic for another time.
However, in ALL cases, the SPI bus operates completely independently of the peripherals purpose. Hence, techniques like polling, and the need for interrupts, do not go away.
To summarize:
* At all times, SPI both sends and receives a single bit of information per clock.
* SPI operates 100% synchronously to its controller (not necessarily the CPU, unless the CPU itself happens to be its controller). NOTE: This implies that the controller must be programmed to never exceed the timing limitations of the addressed slave peripheral. Ultimately, the CPU or firmware developer must either compute or derive this knowledge.
* The SPI controller, in turn, operates fully synchronously to the CPU without DMA, or asynchronously with DMA.
* The SPI controller never commences a bus transaction without explicit OK from the CPU. Hence, while the controller may be asynchronous to the CPU, the CPU still controls when individual transactions over the bus occur.
* The SPI slave interface operates completely asynchronously from the peripheral's logic.
* The peripheral exposes a register set or FIFO buffer (for messages) using basically the same logic as for any other memory-mapped I/O interface, albeit without address decoding logic (there's no need, if the SPI's serial shift register logic direct-connects to individual peripheral registers).
* The peripheral's SPI slave interface is responsible for mapping that interface into messages passed via SPI.
|