Showing results for 
Search instead for 
Did you mean: 

Master Assigning Unique IDs to Slave SPI Devices

Senior II


I have successfully setup SPI between a master to many slave STM32F373s.  

I include an 8 bit deviceID in the packet header and the master always initiates the request.

I am looking for the best way for the master to assign unique device IDs.  

I'm considering adding jumpers or switches to set the device ID in hardware.  In this case I would have the master discover devices by sending requests starting with device ID 1 and incrementing device ID until there is no response/timeout.  I"m leaning towards this solution since it allows the user to keep devices in the same order after a reboot or if the modules are swapped out.  It also allows the ID to be retained.  

I'm considering having the master broadcast to all devices, and have each slave device wait for a random period before accepting requests from the master.  The master would continue to accept requests until a timeout is reached. 

I also have a 1 wire scheme to discover devices but it is a bit more complex and devices may have a different order in the 'chain' after reboot.

Should I be looking at a better solution than the ones I listed?

UPDATE: As a solution, I plan on daisy-chaining slave devices together so the master can assign their device Ids.  I'll be using up 2 SPI ports for each slave device.  Not sure if there is a better solution using just 2 GPIO pins per device ( bit banging through the daisy chain IO pins to set device IDs )

Thank you,

Senior III

Sorry, as I understand: your master should send a SPI "Broadcast" with DeviceIDs, to that SPI slaves would respond when they see their device ID?

  1. Every chip has a register to get a unique device ID: look for "Unique device register (96bits)".
  2. But the "problem" comes with SPI itself: in "full-duplex" mode, a SPI slave would send something back, when something comes in. Every slave would respond on MISO before the receive packet could be decoded.
  3. And even you would try to implement that every slave will just receive: but you had to stop the receiver (e.g. when running in DMA mode), check the received packet, with the device ID in it, so that you can change now what the slave should send: but it needs again a transaction done by master (SCLK provided), so that something can be sent by the slaves.

I guess, what you try to do is not a SPI protocol possible to implement, maybe you need a very delicate procedure on the master side, and a specific programming on all the slaves.

So, I would guess, you can do this (as a "protocol"):

  • all slaves are in Rx mode only (they just listen, they do not send anything back on MISO)
  • you send from master a "broadcast message", e.g. a request with an ID for a specific slave
  • this message has a fixed length, e.g. 8 bytes: all slaves wait for these 8 bytes
  • you give all the slaves time to evaluate the incoming packet, esp. they have to decode/verify the ID
  • now, the master has to send a new command (after given the slaves time)
  • this is needed because a slave cannot respond without a master providing the SCLK
  • now, if all slaves, follow your protocol properly - just one slave will respond ("addressed" with its ID)

BTW: the SPI nCS signal is there to select a SPI slaves. OK, you enable all slaves (they do not act on nCS, all active at the same time). OK, now they can listen to your master, in parallel. But it would be forbidden during a "broadcast" that any slave would respond with something (MISO must remain floating on all slaves!).

This is another issue you have to make sure:

  • the SPI bus must be "floating" on all slave devices: the MISO signal cannot be actively driven by any slave
  • you have to make sure, that EVERY slave releases the bus (and does not hold the MISO signal as actively driven). Possible, but just to make sure it is the case.
  • So, one single Slave (addressed before via sending an ID) has to activate now MISO - you might need to reconfigure the SPI slave.

And how do you know which slave has which ID? Using the register in every slave - all are different and master would not have a clue about the IDs. OK, you can assign (per SW, "hard-coded") to every slave an ID (which you, your master, knows, e.g. 0, 1, 2, 3, 4, ...). You have to compile and flash for every slave a slightly modified FW, so they differ in their IDs.

Draw a diagram for the "SPI protocol" you want to implement (ping-pong, and how the MISO would behave). Then implement the master and slave accordingly. What you want to do is not a "usual" "SPI protocol" (very special, but potentially possible).



This is an approach I had not thought of, thanks.

UPDATE:  I decided to just daisy chain my uCs together and use 2 SPI ports per device since this is the simplest.