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();
}