1
\$\begingroup\$

An unexpected need emerged in my design, which is to control 2 slave SPI devices simultaneously. At first, of course, I was planning to to use the SPI Bus as usual and control both devices using the /CS pins so everything seemed fine.

By reviewing the datasheet of device A today, I noticed that it expects all of the data in one go, which means I cannot do the procedure I originally had planned:

1) Select device B 2) Read data from B 3) Unselect device B 4) Select device A 5) Write data from B 6) Unselect device A 7) Repeat until all data from B goes to A (around 1.1 Mbit)

The device A assumes that when its /CS goes high it's the end of data stream. Of course I cannot read everything from B in one ran and store them to MCU RAM, since the data are way bigger.

Naturally, the next thing that came to my mind is to use 2 separate master SPIs at the same time: select both chips, read on byte from B and feed it immediately to A.

So my questions are:

a) Is that possible using an ATmega32u4? It has a critical role in the overall design and changing to another MCU Would be a step back.

b) I read that the USART can act as a second SPI master. Is that viable and reliable? How hard is to implement?

c) If, unfortunately, is not possible and I have to change MCU, which one would you recommend? Note that the USB capability of ATmega32U4 is essential.

d) Is the new process (read from B, feed to A) likely to cause any unexpected behavior? Does not seem in my point of view, I am asking just in case since I am a new engineer.

Any other idea or direction is welcome! Thanks in advance.

UPDATE In case it plays a significant role, Device A is an FPGA while B is an flash memory. The MCU has a dual role: Download the bitstream from the PC via USB and store it on the flash ROM / use the stored bitstream to configure the FPGA upon reset/power on. Both FPGA and flash use SPI. According to the datasheet of the FPGA (ice40 family, Lattice, "iCE40 Programming and Configuration" p.26), the image has to be programmed without interruption.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ SPI master is reasonably simple to implement in pure software, using just GPIOs. \$\endgroup\$
    – Turbo J
    May 23 '18 at 15:10
  • \$\begingroup\$ It has 2 SPI peripherals ? \$\endgroup\$
    – Long Pham
    May 23 '18 at 15:11
  • \$\begingroup\$ @LongPham Yes, the ATmega32u4 has connected 2 SPI peripherals and the mcu takes the data from the one and pass it to the other. \$\endgroup\$
    – Manos
    May 23 '18 at 15:28
  • \$\begingroup\$ Sounds like you need several transfers to get all data from A to B, using MCU as temporary storage for data before you switch operation of the SPI from "read A" to "write B" and you are limited by the amount of memory on the MCU in terms of a full transfer. Further, when you reissue a SPI read transaction to get remaining data, the slave on the external device does not know to access data from a location in memory where you stopped on previous transfer(?) What are "Device A" and "Device B"? If FPGAs we can easily fix this. Can you add a drawing with the pertinent details? \$\endgroup\$
    – CapnJJ
    May 23 '18 at 16:32
  • \$\begingroup\$ @CapnJJ Yes, indeed it's an FPGA. The MCU has a dual role: Download the bitstream from the PC via USB and store it on the flash ROM / use the stored bitstream to configure the FPGA upon reset/power on. Both FPGA and flash use SPI. According to the datasheet of the FPGA (ice40 family, Lattice, "iCE40 Programming and Configuration" p.26), the image has to be programmed without interruption. \$\endgroup\$
    – Manos
    May 23 '18 at 16:49
2
\$\begingroup\$

You might want to take a different approach altogether. Instead of attaching both the PROM and the FPGA to the µC as slave devices, attach the PROM directly to the FPGA, and allow the FPGA to boot in SPI master mode instead of SPI slave mode. Bonus: the booting will happen more quickly.

You'll still be able to access the PROM from the µC after the FPGA has booted for firmware updates or data storage, by passing the µC's SPI interface signals through the FPGA logic.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ This is a very elegant solution and I considered it carefully and finally I came up with a "modified" version of yours. By examining the FPGA & MCU datasheets, both devices, obviously, boot with their I/Os in HiZ. This mean that they can be both master to the PROM and share the same lines, albeit not at the same time. So, FPGA and MCU both boot with the common pins in HiZ, then FPGA configures itself and deactivates those pins again. After this, the MCU is free to do updates: enable the SPI, do the update, then disable the SPI and return those PINs to HiZ. (Not tested yet, though) \$\endgroup\$
    – Manos
    May 24 '18 at 11:14
  • 1
    \$\begingroup\$ Yes, that works too. The main reason I suggested the pass-through is that it gives you the opportunity to use that same SPI interface on the uC to also control the application logic in the FPGA if desired. \$\endgroup\$
    – Dave Tweed
    May 24 '18 at 11:21
  • \$\begingroup\$ Well, the direct connection means that the MCU can program the flash when the FPGA has no configuration loaded. Also, if you provide a separate chip select line to the FPGA, then the FPGA and SPI flash can behave as two separate SPI slaves. I would recommend connecting up a couple of more signals: namely, the MCU has to have the ability to reset the FPGA and hold it in reset so that it can access the SPI flash without contention as well as trigger the FPGA to load the new configuration, and the MCU should be able to know when the FPGA has finished loading the configuration. \$\endgroup\$ May 24 '18 at 17:58
  • \$\begingroup\$ For Xilinx, those signals are PROGRAM_B and DONE. Looks like the equivalent signals on Lattice parts are CRESET_B and CDONE. \$\endgroup\$ May 24 '18 at 18:01
2
\$\begingroup\$

a) Afaik the Atmega have only 1 SPI bus.

b) No experience (but I'm novice)

c) I use STM#2's mostly. These have 2 SPI buses and if you need more there are version which have 3 (or even more possibly). The cheapest (cost less than an Arduino) STM32F103C8T6 has 2 SPI buses.

d) The SPI buses on the STM32 (and probably other uc's) are independent so there should not be any problem with the process. However, since STM32 has DMA you might be able to do it 'directly', i.e. sending incoming SPI data immediately to the outgoing SPI.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for your answer, they look interesting I will have them in mind in case nothing can be done with the current one. \$\endgroup\$
    – Manos
    May 23 '18 at 15:31
  • \$\begingroup\$ Good luck (btw, you can use some STM32s also with Arduino code). Note however, that in principle the STM32 is a step up in complexity too (I'm still learning, being a novice). \$\endgroup\$ May 23 '18 at 15:55
1
\$\begingroup\$

You state that the FPGA assumes end of configuration data when CS is de-asserted. Is there a timeout as well? That is, if you can have an indefinite delay while leaving CS active will the device behave properly?

If there is simply a need to prevent the FPGA device from closing the transaction, then the problem can be simplified as one of keeping CS selected while not allowing commands to the flash from being read in as garbage data. For this a second SPI master may be overkill

I would suggest using a buffer device between MCU and FPGA for the MISO, MOSI, and SCLK line, and use that to disable the SPI signals by using the reset/enable pin on the buffer device.

The transaction would look like

  1. Asynchronously Assert CS for FPGA
  2. Disable Buffer Device
  3. Read FLASH device as usual
  4. Enable Buffer Device
  5. FPGA Transaction (CS already asserted)
  6. GOTO 2 until done
  7. Asynchronously De-Assert CS for FPGA
\$\endgroup\$
1
  • \$\begingroup\$ According to the provided document on configuration, there is a Time-out (p.25) but it's not entirely clear if refers to Master mode only or both Master & Slave modes. Also, I looked through the entire datasheet but could not locate the actual time. Nevertheless, I would prefer a way of not installing additional hardware in this particular design but I would have it in mind for future designs, thanks! \$\endgroup\$
    – Manos
    May 24 '18 at 11:04
0
\$\begingroup\$

USART as SPI master

As the datasheet says in chapter 19,

The Universal Synchronous and Asynchronous serial Receiver and Transmitter (USART) can be set to a master SPI compliant mode of operation.

So you can have two independent SPI (master) ports to transfer data between the slaves.

Using an I2C external EEPROM

Instead of an SPI flash, you can connect an I2C EEPROM to the TWI port (PD0, PD1) on the MCU. I2C is called TWI or 2-wire Serial Interface in Atmel-ese, but they are essentially the same thing. Drawback: EEPROMs are generally more expensive as flash memory.

\$\endgroup\$
1
  • \$\begingroup\$ I would suggest an FRAM part, which is similar part and usually shares the same I2C protocol, but has access times <100us instead of typical 5-10ms for EEPROM. \$\endgroup\$
    – crasic
    May 24 '18 at 19:19

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.