0

I've been trying to transfer all my code from the STM32 Arduino library to ST Hal library, but I've been running into a problem with the SD-card. I'm using a SDHC sd card that has two partitions (one for factory reset and the other for normal settings) They show up on my PC as drive D and E.

So when setting up FATFS for my STM32F1 chip everything worked fine when using SD Bus one bit mode. Using standard code I could write into the factory reset partition:

  FRESULT res = f_open(&SDFile, (const TCHAR *)"Test2.txt", FA_CREATE_ALWAYS | FA_WRITE);
  if(res == FR_OK){
    HAL_GPIO_WritePin(DASH_LED_1_GPIO_Port, DASH_LED_1_Pin, GPIO_PIN_SET);
    res = f_putc('S', &SDFile);
    if(res != -1){
      HAL_GPIO_WritePin(DASH_LED_2_GPIO_Port, DASH_LED_2_Pin, GPIO_PIN_SET);
    }
    res = f_write(&SDFile, (const void*)buffer, sizeof(buffer), &byteswritten );
    if(res == FR_OK){
      HAL_GPIO_WritePin(DASH_LED_3_GPIO_Port, DASH_LED_3_Pin, GPIO_PIN_SET);

    }
    f_close(&SDFile);
  }

When initializing the code and mounting a drive everything seemed fine, even when I wanted to mount the second partitions (i'm not really sure if thats what i'm doing with the code) the returns in my debugger were all FR_OK:

uint8_t retSD;    /* Return value for SD */
char SDPath[4];   /* SD logical drive path */
char OtherPath[4];
FATFS SDFatFS;    /* File system object for SD logical drive */
FIL SDFile;       /* File object for SD */

/* USER CODE BEGIN Variables */
PARTITION VolToPart[2] = {
  {0,0},
  {0,1}
};
/* USER CODE END Variables */    

void MX_FATFS_Init(void) 
{
  /*## FatFS: Link the SD driver ###########################*/
  retSD = FATFS_LinkDriver(&SD_Driver, SDPath);

  /* USER CODE BEGIN Init */
  FRESULT res = f_mount(&SDFatFS, SDPath, 0 );
  if(res != FR_OK){
    Error_Handler();
  }
  res = f_mount(&SDFatFS, OtherPath, 0);
  if(res != FR_OK){
    Error_Handler();
  }

  /* additional user code for init */     
  /* USER CODE END Init */
}

I will admit that even though I did my research I found the mounting and the subsequent VolToPart array that you apparently need to be a little bit vague.

After debugging the code while mounting twice (see code above), I tested the code using the drive identifiers (I turned on _FS_RPATH, which I don't think has an effect, but just to be sure) I could write Hello World to 0:Test2.txt but got an invalid drive error for 1:Test2.txt.

I want to be able to switch between drives, but I feel like I'm missing something that I need to initiliaze or do. At this moment I'm not sure if FatFs can see the SDCard partitions and I'm just not initializing it or if its a completely seperate drive that the SD card cannot see. I hope someone it able to help me with this, let me know if you need more info.

Edit: I found out some stuff after debugging for a while: SDPath is getting defined as "0:/"in link driver, so it makes sense for that this drive works. Other path does not get defined (as far as I can tell, and just gets the default value of "0:/", which means I'm doing the same mount twice. When I tried to add a seperate driver and intialize that one, it still ended up being an invalid disk error.

extern Diskio_drvTypeDef  SD_Driver;
extern Diskio_drvTypeDef  Other_Driver;
const Diskio_drvTypeDef  SD_Driver =
{
  SD_initialize,
  SD_status,
  SD_read, 
#if  _USE_WRITE == 1
  SD_write,
#endif /* _USE_WRITE == 1 */

#if  _USE_IOCTL == 1
  SD_ioctl,
#endif /* _USE_IOCTL == 1 */
};

const Diskio_drvTypeDef  Other_Driver =
{
  SD_initialize,
  SD_status,
  SD_read, 
#if  _USE_WRITE == 1
  SD_write,
#endif /* _USE_WRITE == 1 */

#if  _USE_IOCTL == 1
  SD_ioctl,
#endif /* _USE_IOCTL == 1 */
};

I then ran link driver twice and received a FR_INVALID_DRIVE message on the second mount. I tried this both with the same FATFS object and different ones.

uint8_t retSD;    /* Return value for SD */
char SDPath[4];   /* SD logical drive path */
char OtherPath[4];
FATFS SDFatFS;    /* File system object for SD logical drive */
FATFS OtherFatFS;
FIL SDFile;       /* File object for SD */

/* USER CODE BEGIN VolToPart */
/* Volume - Partition resolution table should be user defined in case of Multiple partition */
/* When multi-partition feature is enabled (1), each logical drive number is bound to arbitrary physical drive and partition
listed in the VolToPart[] */
PARTITION VolToPart[] = {
  {0,0},
  {1,0}
};
/* USER CODE END VolToPart */  

/* USER CODE BEGIN Variables */
/* USER CODE END Variables */    

void MX_FATFS_Init(void) 
{
  /*## FatFS: Link the SD driver ###########################*/
  retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
  retSD = FATFS_LinkDriver(&Other_Driver, OtherPath);
  /* USER CODE BEGIN Init */
  FRESULT res = f_mount(&SDFatFS, SDPath, 1 );
  if(res != FR_OK){
    Error_Handler();
  }
  res = f_mount(&SDFatFS, OtherPath, 1);
  if(res != FR_OK){
    Error_Handler();
  }
Jipolie01
  • 15
  • 5
  • First thing to try is to force mount with `res = f_mount(&SDFatFS, OtherPath, 1);` -- with option `0` the call is effectively a no-op, and is guaranteed to succeed -- and see the error. Meanwhile, how `SDPath` and `OtherPath` are initialized? – user58697 Aug 27 '19 at 23:54
  • Using the immediate mount options still produces FR_OK's for both mounts. In the example that I used SDPath are initialized within the linkdriver and otherPath nowhere (so maybe the second FR_OK is a result of undefined behaviour). I'll put an update of some of my findings in the original post – Jipolie01 Aug 28 '19 at 15:45

0 Answers0