Hej!
JimmyAndersson skrev: ↑17 juni 2021, 23:34:32
Bra! Hårt och känslokallt ska det vara.
De ska minsann få veta hur det var att inte ha något forum att fråga...
Daniel:
Koden i ditt senaste inlägg är ju ganska snårig.
En funktion som anropar en funktion som...
Jag kan inte språket/miljön du använder men det ser ut som att du behöver ändra det som har med SPI att göra, så det motsvarar din miljö.
Jag är tillräckligt knasig för att programmera allt jag gör i assembler eller php, men jag förstår C tillräckligt för att hänga med, så visa gärna mer kod, eller en länk till hela koden.
Jag delar med mig av koden som jag använder. Färdig att direkt använda för egentligen alla system. Bara ändra SPI anropen bara.
Rick81 skrev: ↑18 juni 2021, 07:50:31
Jag har inplementerat fatFS i PIC16 via SPI och STM32 med SDIO.
Har för mig det bara var lägga in SPI anrop i platform och diskio. Sen var det en ms tickfunktion man behövde specca för timing.
Sen får man tänka på att ändra hastighet på SPI vid initeriering och sedan ökar man den.
Jag lägger upp mitt exempelprojekt i form av C-kod. Denna C-kod är universial och passar alla system, så länge man ändrar SPI anropen i fatfs_sd.c filen.
Det enda jag har gjort är att jag har lagt till filen
integer.h och jag har ändrat i
fatfs_sd.c och
fatfs_sd.h
Filerna fatfs_sd.c och fatfs_sd.h har jag hittat här:
https://github.com/eziya/STM32_SPI_SDCA ... fatfs_sd.h
https://github.com/eziya/STM32_SPI_SDCA ... fatfs_sd.c
Det jag har modifierat är att jag har exempelvis flyttat om lite i headerfilen fatfs_sd.h till diskio.h och alla #define från fatfs_sd.h till fatfs_sd.c bara för att jag inte ska kunna komma åt dessa från andra ställen i min användrarkod. När det kommer till variablerna Timer1 och Timer2 i fatfs_sd.c så har jag gjort om detta.
Kod: Markera allt
/* timeout 200ms */
Timer1 = 200;
/* loop until receive a response or timeout */
do {
token = SPI_RxByte();
} while((token == 0xFF) && Timer1);
Till
Kod: Markera allt
/* timeout 200ms */
uint16_t end_time = 200;
uint32_t time = HAL_GetTick();
/* loop until receive a response or timeout */
do {
token = SPI_RxByte();
} while((token == 0xFF) && (end_time > HAL_GetTick() - time));
För att använda detta så måste man inkludera följande.
Kod: Markera allt
#include "Memory Card/fatfs_sd.h"
#include "Memory Card/ff.h"
I sin main.c fil.
Där efter så ska man anropa denna kod för att deklarera SPI enheten.
Kod: Markera allt
void SD_SPI_init(SPI_HandleTypeDef* hspi, GPIO_TypeDef* CS_Pin_Port, uint16_t CS_Pin)
Så nu är det mest bara att anropa följande funktioner. Dessa funktioner finns dock inte med i Memory Card.zip filen som jag bifogar. Kopiera bara denna kod och kör funktionerna.
Kod: Markera allt
static FIL fil;
FRESULT SD_Mont_Card(){
FATFS fs;
return f_mount(&fs, "", 0);
}
FRESULT SD_Umont_Card() {
return f_mount(NULL, "", 1);
}
FRESULT SD_Open_Existing_File_With_Read_Write(char* filename) {
return f_open(&fil, filename, FA_READ | FA_WRITE); // Posix "r+"
}
FRESULT SD_Make_Filesystem() {
uint32_t work[FF_MAX_SS];
MKFS_PARM opt;
opt.fmt = FM_FAT32;
opt.au_size = 0;
opt.align = 0;
opt.n_fat = 0;
opt.n_root = 0;
return f_mkfs("", &opt, work, FF_MAX_SS);
}
FRESULT SD_Create_New_File_With_Read_Write(char* filename) {
return f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE | FA_READ); // Posix "w+"
}
FRESULT SD_Append_Existing_File_With_Read_Write(char* filename) {
return f_open(&fil, filename, FA_OPEN_APPEND | FA_WRITE | FA_READ); // Posix "a+"
}
FRESULT SD_Close_File() {
return f_close(&fil);
}
FRESULT SD_Check_Space(uint32_t* totalSpace, uint32_t* freeSpace){
FATFS *pfs;
DWORD fre_clust;
FRESULT status = f_getfree("", &fre_clust, &pfs);
*totalSpace = (uint32_t)((pfs->n_fatent - 2) * pfs->csize * 0.5);
*freeSpace = (uint32_t)(fre_clust * pfs->csize * 0.5);
return status;
}
FRESULT SD_Read_File(uint8_t* buffer, uint32_t bytes_to_read, uint32_t* bytes_read){
return f_read(&fil, buffer, bytes_to_read, bytes_read);
}
FRESULT SD_Write_File(uint8_t* buffer, uint32_t bytes_to_write, uint32_t* bytes_written){
return f_write(&fil, buffer, bytes_to_write, bytes_written);
}
Men det fel jag får är FR_DISK_ERR, vilket betyder att den inte hittar någon FAT volym när jag anropar SD_Make_Filesystem() funktionen.
Nu får jag bara FR_NOT_READY. Men när jag monterar SD kortet så får jag FR_OK.
Edit: Nu får jag bara FR_DISK_ERR efter att jag har verkligen sett till så SD-kortet sitter fast + att jag har dragit ned SPI-klockans hastighet.
Här hamnar jag idag när jag öppnar en fil efter jag har monterat SD-kortet.
Kod: Markera allt
FRESULT SD_Create_New_File_With_Read_Write(char* filename) {
return f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE | FA_READ); // Posix "w+"
}
Sedan här
Kod: Markera allt
/*-----------------------------------------------------------------------*/
/* Open or Create a File */
/*-----------------------------------------------------------------------*/
FRESULT f_open (
FIL* fp, /* Pointer to the blank file object */
const TCHAR* path, /* Pointer to the file name */
BYTE mode /* Access mode and open mode flags */
)
{
FRESULT res;
DIR dj;
FATFS *fs;
#if !FF_FS_READONLY
DWORD cl, bcs, clst, tm;
LBA_t sc;
FSIZE_t ofs;
#endif
DEF_NAMBUF
if (!fp) return FR_INVALID_OBJECT;
/* Get logical drive number */
mode &= FF_FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND;
res = mount_volume(&path, &fs, mode); <-------------------------- HÄR
Sedan kommer jag hit.
Kod: Markera allt
/*-----------------------------------------------------------------------*/
/* Determine logical drive number and mount the volume if needed */
/*-----------------------------------------------------------------------*/
static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */
const TCHAR** path, /* Pointer to pointer to the path name (drive number) */
FATFS** rfs, /* Pointer to pointer to the found filesystem object */
BYTE mode /* !=0: Check write protection for write access */
)
{
int vol;
DSTATUS stat;
LBA_t bsect;
DWORD tsect, sysect, fasize, nclst, szbfat;
WORD nrsv;
FATFS *fs;
UINT fmt;
/* Get logical drive number */
*rfs = 0;
vol = get_ldnumber(path);
if (vol < 0) return FR_INVALID_DRIVE;
/* Check if the filesystem object is valid or not */
fs = FatFs[vol]; /* Get pointer to the filesystem object */
if (!fs) return FR_NOT_ENABLED; /* Is the filesystem object available? */
#if FF_FS_REENTRANT
if (!lock_fs(fs)) return FR_TIMEOUT; /* Lock the volume */
#endif
*rfs = fs; /* Return pointer to the filesystem object */
mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */
if (fs->fs_type != 0) { /* If the volume has been mounted */
stat = disk_status(fs->pdrv);
if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */
return FR_WRITE_PROTECTED;
}
return FR_OK; /* The filesystem object is already valid */
}
}
/* The filesystem object is not valid. */
/* Following code attempts to mount the volume. (find an FAT volume, analyze the BPB and initialize the filesystem object) */
fs->fs_type = 0; /* Clear the filesystem object */
fs->pdrv = LD2PD(vol); /* Volume hosting physical drive */
stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
if (stat & STA_NOINIT) { /* Check if the initialization succeeded */
return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ <----------------------------HÄR!!!!!!!!!
}
Om man vill konfiguera FatFS så är det bara att ändra parametrarna i ffconf.h, exempelvis detta. Det är EXAKT samma parametrar i FATFS i STM32CubeIDE.
Kod: Markera allt
#define FF_MIN_SS 512
#define FF_MAX_SS 4096
/* This set of options configures the range of sector size to be supported. (512,
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk, but a larger value may be required for on-board flash memory and some
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
/ for variable sector size mode and disk_ioctl() function needs to implement
/ GET_SECTOR_SIZE command. */