This is a normal sequence for an SPI Read:


I want to code for an SPI slave. How is this normally done? How can the slave respond so quick (in the next bit!) with the appropriate data out after it has received the address of the register the master wants to read?

  • 2
    \$\begingroup\$ What is the nature of your SPI slave? Microcontroller? FPGA? On a microcontroller, you'd normally handle it in the SPI interrupt handler, but you do need to verify that you can load the SPI data output register in the limited amount of time available. It has to be the highest-priority interrupt in the system. I had no trouble doing this on a PIC18Fsomething several years ago (SPI running at about 1 MHz). \$\endgroup\$ – Dave Tweed Sep 3 '13 at 11:40
  • \$\begingroup\$ Is there any leniency in the CS going low for some amount of time before the master clocks in/out data? \$\endgroup\$ – Andy aka Sep 3 '13 at 11:43
  • \$\begingroup\$ I'd assume the SPI bus speed would be << the slave's clock frequency, giving it enough time to do what it needs to do. \$\endgroup\$ – John U Sep 3 '13 at 11:58
  • \$\begingroup\$ Do you want to code a SPI slave that YOU can use? In that case you can choose the frequency to match what your slave software can handle. If not, you will have to keep up with what your master wants from you (that's the essence of a slave..), which might well be impossible is software. \$\endgroup\$ – Wouter van Ooijen Sep 3 '13 at 13:32

There is a reason hardware is usually used to implement SPI slaves. It can be done in a microcontroller if you know the clock speed will be limited to some maximum value, a certain sequence is always followed by the master, etc. It is very difficult in the general case due to the possibly very short time between receiving information and then having to produce data based on that information.

In your case you have less than 1 clock cycle to digest the last bit of the address before having to produce data that is presumably dependent on that address. If you know the system or have some control over it, you can have the master use a slow clock or at least stretch the clock between the 23rd and 24th rising edge. Otherwise, a non-hardware solution is probably not viable.

Let's say the clock speed is 10 MHz, which is perfectly valid for lots of SPI devices. That means you only have 100 ns between clock cycles. A dsPIC running at 40 MIPS can only do 4 instruction cycles during that time, which is very unlikly to be anywhere near enough to use the address, do the lookup, and start returning the data.

Not all things are possible just because you want them to be. This particular protocol was clearly intended for some kind of dedicated chip to implement on the slave side. Anything short of a FPGA isn't going to work for that in the general case.


In general (exceptions may exist, but I know of none), microcontroller-based SPI slaves will unavoidably impose timing constraints that make them usable only with masters that are aware of those constraints and abide by them. The I2C standard is designed so that a slave with a tiny amount of hardware can ask a properly-designed master to match its speed to an arbitrarily-slow slave processor, but SPI has no such features. With most microcontrollers' SPI slave peripherals, the only practical means of handshaking is to determine the worst-case time after CS changes or a byte is sent before the slave will be guaranteed ready for the next event, and have the master unconditionally wait that long after each event. Consequently, even though having two controllers communicate using SPI could theoretically be 10x as fast as using I2C or UARTs, SPI will often end up being slower because of the need to have the master accommodate the slave's worst-case times (e.g. if after a byte the slave will normally be ready for the next byte 2us later, but some other interrupt occurs as the byte arrives it may may take 50us, useful SPI communication will probably be limited to about 20Kbytes/second), while a quad-buffered UART or I2C could probably handle about 50Kbytes/second.

It would not be difficult for SPI hardware to include features so the master could easily accommodate itself to the slave's timing (I've designed "SPI bridge" hardware that did so), but I'm not aware of any controllers that include such hardware internally.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.