This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Sharing a SPI bus with an SD card (FATFS) and another SPI Slave

Hello, 

I am having a few issues with getting the SD card FATFS example code to share the same bus as another slave I transfer data to. 

I have a few questions:

1) Since, I don't need the two slaves to transfer simultaneously, should I have them use the same SPI instance?

2) What part of the FATFS example needs to be done only once? I want to write to the SD card every 1 second or so, so I split the example code into two functions: sd_spi_start() containing the initializing and the mounting, and sd_write() containing the directory reading, file opening, file writing and file closing. So I was planning on calling sd_spi_start() once and the sd_write() multiple times... is this the correct approach?

3) Right now I am stuck where I write to SD card using sd_write() (Channel 6), write to the other slave using nrf_drv_spi_transfer() , then try to write to SD card again and it just gets stuck (the CS pin just stays low):

Do you have any idea to why this is happening?

Parents
  • So I can get it to work if I uninitialize SPI in between SD card SPI transfers and other slave SPI transfers. Since it works I'll move forward with this but if someone has an idea why I have to do this let me know so that I can optimize this further.

  • I know that the Nordic SPI controller has a feature where you can tell it what chip select pin to use and it will toggle it automatically when issuing transfers. Are you using this feature?

    Having the SPI controller assert the chip select line automatically is handy in that it saves you from having to manually toggle the GPIO pin yourself (there's some savings in code), however it really only works well if there is one slave, because the SPI controller can only control one chip select pin at a time, and each slave has a different chip select line.

    If you are using the automatic chip select handling feature, then I could see how you'd have to reconfigure the SPI controller each time you decide to switch from using one slave to another. In that case, I would suggest that you stop doing it that way and manually toggle the chip select lines instead.

    If you're not using that feature, then I'm not sure what could be wrong. For my current project I have an SD card and resistive touch controller on the same bus, and I can access both of them without needing to reconfigure the SPI bus in between. I do manually toggle the chip selects though.

    -Bill

  • Hello, it's been a year but I have tried all what you said. The main  problem seems to be the FatFs itself. It won't let me initialize FATfs blkdev without unitializing the SPI instance I have for the other slave I want to share the bus with.

  • As I said early on in the thread:

    In general (not specific to Nordic), I would always try to avoid sharing an SD-Card with any other SPI device. I don't really think that SD-Cards are designed to share their SPI interface

    See: https://devzone.nordicsemi.com/f/nordic-q-a/63517/interfacing-between-nrf52840-and-bme680-i2c-or-spi/258966#258966

    and: https://devzone.nordicsemi.com/f/nordic-q-a/63570/adding-sd-card-as-second-spi-slave/259181#259181

  • This isn't true. If you want to recommend that people avoid this configuration, do it for the right reason: it may be a little hard for newcomers. There's nothing electrically to prevent this from working as long as you do it right.

    I've designed two boards where a single SPI controller instance was used with multiple slaves, including an SD card. The first design (NXP Kinetis KW01 chip) had three devices: an XPT2046 touch controller, ILI9341 display chip and an SD card all on the same SPI channel. With the nRF52840, I the design had just the SD card and XT2046 controller on the same SPI bus. Both designs worked fine.

    The things to remember are:

    - each slave uses the same SCK/MOSI/MISO pins, *but* each slave must be wired to its own chip select pin (as the hardware designer, you have to make sure this is true)

    - you have to be sure to only assert the chip select pin for one slave at a time when doing SPI transfers (assert CS1/do a transfer/release CS1, assert CS2/do a transfer/release CS2/etc...)

    - for each slave device, figure out what's the fastest clock speed it can support, then see which one is the slowest -- set the SPI controller clock frequency so that it doesn't exceed this slowest speed

    - if you're using an RTOS (i.e. you have threads), use a mutex to guard access to the SPI controller (i.e. always take the mutex before doing a SPI transfer and then give the mutex after)

    Note that the rule about choosing the slowest clock speed can be fudged a little. With the nRF52840, I found you can actually change the FREQUENCY register on the fly without having to reinitialize everything. This may be necessary if the slowest slave's max speed is so slow that using with the other slaves would result in them performing too poorly for your needs.

    That means you can switch the clock to low frequency only when you talk to the slow slave, and then switch it back to a higher frequency when you're finished.

    Also, I'm not necessarily suggesting that people *should* share one SPI controller with many slaves, but I know that you *can* do it if necessary and it will work.

    I think the real complication here is figuring out how to make this work with the Nordic SDK in particular. For the boards I worked on, I did not use the Nordic SDK. (In fact I wrote my own driver for the nRF52 SPIM device.) I don't know if there is a working example in the SDK that shows how to use a single SPI controller with two slaves. If there is, then that's the model that should be followed here (and the fact that one slave ends up being an SD card shouldn't really matter). If there isn't such an example, then they really ought to add one since while it's not a great idea, it's not an especially rare use case either.

    -Bill

  • Hello, it's been a year but I have tried all what you said.

    I don't believe it took you a whole year. It's really rude to disappear for so long and then come back expecting more help. Disappointed

    It won't let me initialize FATfs blkdev without unitializing the SPI instance I have for the other slave I want to share the bus with.

    It's also really rude to only give a short sentence about your problem without giving any details or showing example code.

    Please note: the Nordic SDK probably contains its own diskio.c code to interface with FatFs. If it's that code which is giving you trouble, then you may need to customize it. However I'm not going to do that for you.

    -Bill

  • There's nothing electrically to prevent this from working

    Follow the links where I cited some reasons for avoiding this configuration. They are not electrical - they are to do with the way SD Cards communicate on the interface - in particular, when an SD Card starts up, it is not in SPI mode.

    I didn't say it can't be done - just that there are issues to consider.

    An SD Card is not just another SPI Slave.

Reply
  • There's nothing electrically to prevent this from working

    Follow the links where I cited some reasons for avoiding this configuration. They are not electrical - they are to do with the way SD Cards communicate on the interface - in particular, when an SD Card starts up, it is not in SPI mode.

    I didn't say it can't be done - just that there are issues to consider.

    An SD Card is not just another SPI Slave.

Children
No Data
Related