Hi Martin
1) SD cards and SPI FLASH are quite different due to the fact that SD cards have a controller in them handling such details like level-wearing and bad block management (this is invisible to the user but is probably highly developed) - at least I think... (I read a SanDisc technical document where this point seems to be confirmed). Therefore level wearing is something that would be quite difficult to retain. This is however not a problem in applications where the quantity of writes is not too high.
Also the dimensions of SPI based FAT32 may call for a slightly different configuration. ATMEL SPI FLASH chips (with small granularity) seem to me to be good candidates since they fit well, whereas large granularity types will be a bit of pain.
Although I do see that FAT would fit certain SPI FLASH devices fairly well it would still mean a quite different hardware interface to the SD card one. If the demand is there it can be looked at after the SD card work is completed and established.
2) I don't know that there would be any advantage of a user file collection stored in the utFAT. It could also not operate with the existing addressing mechanism. [Reminder: SPI FLASH memory is effectively linear and so can be memory mapped (virtually, as the uFileSystem does). SD cards - and FAT in general - are not linear, they work with sectors (effectively windows into a small block of memory) and and clusters which are like blocks of the files (or directory information) linked together almost anywhere in the memory (not linear)] If utFAT is used I think that standard file addressing is the way to go. However if SPI FLASH is used I find embedded user files a good compromise to allowing it to essentially look like a file system with long file names and even directories (the complete directory path is the file name), complete web pages to be packed into one single file for uploading and fast access (still not as fast as uFileSystem access but faster that FAT32 access since the file search is generally rather less complicated).
3) No, it is not really possible to use compatible commands. The operation of the two are just so different. However it is still easy to use. Here is an example (present state and may change before release...Also no error handling for simplicity.)
FTP file retrieval, uFileSystem case - the file is identified from the path/name. The length is checked and,
ptrFile = uOpenFile((CHAR *)(ucIp_Data+5)); // get file pointer
if ((uGetFileLength(ptrFile)) && (fnTCP_Connect(FTP_TCP_Data_socket, ipFTP_data, usFTP_DataPort, FTP_DATA_PORT, 0) >= 0)) {
ucFTP_action = DO_UPLOAD;
FileOffset = 0; // start at beginning of file
}
.. data is put to the output buffer.
uGetFileData(ptrFile, FileOffset, ptrBuffer, usTxLength)); // read from the file to a buffer
.. (with some management of the length and file offset)
In the utFAT case:
static UTDIRECTORY utDirectory = {0}; // directory object for a single user
static UTFILE utFile = {0}; // file object for a single connection
utOpenDirectory(DISK_D, FTP_ROOT, &utDirectory); // set the FTP root (eg. D:/ftp_dir/) - initialisation
utFile.ptr_utDirObject = &utDirectory; // link the file object to its directory object
.. locate the file according to the retrieval name (eg. /dir_1/file_000000012888_long_name.txt
utOpenFile((const CHAR *)(ucIp_Data+5), &utFile, UTFAT_OPEN_FOR_READ);
..
if (utFile.ulFileSize != 0) {
utReadFile(&utFile, ptrBuffer, usTxLength); // read from the file to a buffer
}
In this case the management of the file is content is performed in the utReadFile() (and UTFILE object) since it needs to be able to do seek type functions.
Integrating this into FTP and HTTP was not difficult. In fact, since the utFAT (necessarily) performs extra file location management some of the pointers/indexers used together with the uFileSystem are superfluous. I just set them to the momentary utFAT values to keep them in sync so that it is easier to understand the two when they are side-by-side. Eg.
FileLength = utFile.ulFileSize; // set the local length (as used by uFileSystem code) to the internal value to ensure compatibility with later length use
In an attempt to ensure porting (or using both files systems together - useful as a fall back in case the card is extracted...) I have encapsulated details of mounting disks. The only addition code is setting where the directory is located (can also be root), which initialises everything for its subsequent use by the particular user (see utOpenDirectory()) - whereby there may need to be be multiple directory objects if multiple users have their own relative locations in the utFAT (like multiple DOS windows each have their own independent present location). Then it is easy to move to other directory locations - allowing absolute or relative addressing (relative is generally more efficient for the file searches too). The user code shouldn't need to worry about too much detail (eg. - D:/dir_2/myFile.pdf or ../../dir_3/dir_4/myOtherFile.jpeg - basically just pass an appropriate string).
Regards
Mark