0

I've been trying to mount an SD card, write some data to some files, then dismount the SD card. Mount a separate one and write to more files (This is done via a multiplexer and two separate but identical SD card modules). I am using an STM32F3 and an SPI interface, I can mount and write to files without issue but I am struggling to properly deinitialise all of FatFs variables between SD cards.

I am taking the following steps

Using f_close to close all open files. Dismounting the drive by mounting a NULL drive f_mount(0, "", 0);. I then call FATFS_UnLinkDriver. My main issue appears to be that after all these steps disk.is_initilized still returns 1.

DSTATUS disk_initialize (
    BYTE pdrv               /* Physical drive nmuber to identify the drive */
)
{
  DSTATUS stat = RES_OK;
  
  if(disk.is_initialized[pdrv] == 0)
  { 
    disk.is_initialized[pdrv] = 1;
    stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
  }
  return stat;
}

Therefore the SPI initilising code I am using is not called for the second SD card. I can get around this by manually calling the SPI initialise but I would like to know if I am missing any steps in deinitialising. Ideally I would like to return all of FatFS stack to the default state, as if the microcontroller were power cycled between SD card swaps.

Liamm36
  • 13
  • 4
  • Why would you not simply connect two SD cards with independent chip selects and treat then as separate devices? In any event, switching cards is logically no different the removing one card an inserting another - why do you need to re-initialise the SPI? – Clifford Jul 01 '21 at 10:57
  • @Clifford It's part of a wider system, a data logger (this device) and a much more powerful data processor. The multiplexer is to share access to the SD cards between the two devices. I should have been clearer with SPI initialise code sorry. It isn't initialising an SPI interface but instead initiliasing the SD card to use SPI. – Liamm36 Jul 01 '21 at 11:42
  • What you just described is not what your question suggests. In the question you refer to two separate SD cards and one processor, in your comment you suggest a single SD card accessed by two separate processors. – Clifford Jul 01 '21 at 12:14
  • It would have perhaps been simpler to have one processor access the SD card and provide an interface via a communication interface between the two processors to allow the other processor to access the file system. For example if the two devices were connected via PPP, with TCP/IP stack on that, you could use FTP to access the file system "remotely". Or you could do something proprietary in far less code no doubt if the development time is not an issue. – Clifford Jul 01 '21 at 12:19
  • @Clifford The STM32 does have access to two seperate SD cards, although only one at a time via the multiplexer. The other processor will have access to the SD card not currently in use by the STM32. We are sampling data from a large array of sensors which needs to be accurately timestamped and uninterrupted. We thought this would be the best approach while also fulfilling the requirement to have a backup of the data. We considered networked drives/comms however due to power requirements the data processor can only be active for a few minutes per day. – Liamm36 Jul 01 '21 at 13:51
  • OK - that is all a matter of design decisions and hardware - not really related to your question. I think my a answer stands - let us know how it goes. I suspect that may not be the only issue with this scheme you'll need to solve, but it will at least force the initialisation to run. – Clifford Jul 01 '21 at 19:38

1 Answers1

1

The media access interface where disk_initialise() is defined did not envisage perhaps you physically changing the hardware interface. disk.is_initialized[pdrv] is there only to block unnecessary reinitialization of the hardware, and is a one way switch.

You can force reinitialisation simply by resetting disk.is_initialized[pdrv] to 0:

DSTATUS disk_deinitialize (
    BYTE pdrv               /* Physical drive number to identify the drive */
)
{
  disk.is_initialized[pdrv] = 0 ;
  return RES_OK ;
}

Thereafter a call to disk_initialize() will perform the initialisation.

Or you could have a re-initialise function:

DSTATUS disk_reinitialize (
    BYTE pdrv               /* Physical drive number to identify the drive */
)
{
  disk.is_initialized[pdrv] = 0 ;
  return disk_initialize( pdrv ) ;
}
Community
  • 1
  • 1
Clifford
  • 88,407
  • 13
  • 85
  • 165