cancel
Showing results for 
Search instead for 
Did you mean: 

USB Mass Storage interface with external NOR-Flash connected via SPI to STM32F412ZG

Developer_Nit
Associate II

Hello,

I am trying to interface USB Mass Storage with external Flash. I have implemented the complete structure that is necessary as below,

typedef struct _USBD_STORAGE
{
  int8_t (* Init) (uint8_t lun);
  int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint16_t *block_size);
  int8_t (* IsReady) (uint8_t lun);
  int8_t (* IsWriteProtected) (uint8_t lun);
  int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
  int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
  int8_t (* GetMaxLun)(void);
  int8_t *pInquiry;
  
}USBD_StorageTypeDef;
 
 
USBD_StorageTypeDef USBD_MSC_Template_fops =
{
	FLASH_Init,
	FLASH_GetCapacity,
	FLASH_IsReady,
	FLASH_IsWriteProtected,
	FLASH_Read,
	FLASH_Write,
	FLASH_GetMaxLun,
	(int8_t *)UMSC_FLASH_Inquirydata,
 
};

In addition, I have defined all the functions that performs flash operations (i.e read/write operations, initialization etc). I have also passed the structure to USB register,

 /* Init Device Library,Add Supported Class and Start the library*/
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC);
 
USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_MSC_Template_fops);
USBD_Start(&hUsbDeviceFS);

When i Connect to the PC, It detects as a mass storage device. But when i try to open, it opts me to format the flash. When try to format, it always throws me an error that flash cannot be formatted. The configurations that i have set in PC and my code are as follows,

#define FLASH_LUN_NBR                  1
#define FLASH_BLK_NBR                 0x2000
#define FLASH_BLK_SIZ                    2048
#define FLASH_END_ADDR		  0xFFFFFF
#define FLASH_START_ADDR          0x000000
 
PC side configuration: 
Allocation of bytes --> 256KB
 

Is anything else has to be configured to make this work or my code requires a FTL or FATfs for this to work? (According to my research the PC FATfs should take care of this?) I am currently using a direct SPI read write operations to the flash.

The hardware I am using are as follows,

MCU : STM32F412ZG (SPI2 Bus)

Flash: S25FL129p (NOR Type, 16MB)

Sector size : 256KB

It would be great if someone helps me out on this problem.

5 REPLIES 5

The system on the PC side wants a simple block interface, usually 512 byte blocks, might tolerate 2048 byte ones, it isn't going to deal with 256KB erase block issues, you're going to have to handle the write in place of small blocks within those.​

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Developer_Nit
Associate II

Thank you for the reply, I tried with the 512 bytes blocks and also 2048 bytes block. But my PC pops up the error window stating that flash cannot be formatted. The real questions are,

1) Is File system necessary to just to read write some files to slash from PC? Wouldnt the PC handle it? Or a simple SPI Read/write operations are enough?

2) Is my code/ approach correct to interface USb and SPI Flash to read/write from PC?

3) Are the configurations mentioned with respect to External flash correct?

Thank you.

How would you imagine it working without a file system? You have to apply some form to the data. You could perhaps look to implement MTP rather than MSC. You could write a driver, figure that's even more complicated to pull off.

The PC wants you to be a block storage device when connected as a MSC. The job there is to read back the same data blocks that are written. It fails when you don't do that. Perhaps trace the interaction you see during a format, log the block numbers and CRC for the content, and then contrast that with what you hand back.

Like I said, the PC isn't going to manage the handing of the blocks on your end, that's your job. It is complicated because you can't overwrite the data in-place, you must erase the prior content, and write the new. When the PC writes just 512 bytes, you've got to juggle the 256KB-512bytes that's NOT changing.

If you use something like an eMMC NAND device you push the block management inside that device, and it behaves like a hard disk or SD Card.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Developer_Nit
Associate II

Thank you for the response. I have a question related to your statement, "How would you imagine it working without a file system? You have to apply some form to the data"

  • How would my flash get to know which file has to be opened or created when the input from the USB MSC is only the block address but not the file name or directory. API for read/write as per driver is,
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)

Are the above statements correct, if so then i have to interface FTL to make this work. Else what would be the approach to make this happen.

Thank you.

The PC uses the file system to access the blocks, the file system defines the files, directories and structures, and contains that information inside the blocks, usually through a specific hierarchy. I'd have thought computer systems architecture courses would cover such materials.

To access such a file system locally you'd need a FATFS layer to provide the equivalent FS/BLOCK interpretation on the STM32 side.

At the end of the day you've got to manage the cases of writing a few bytes or blocks with the 256KB without losing the existing/unchanged content. You could use a block translation table, so you replace the current erase block with a pre-erased one and migrate the content, but that has a whole other set of complications, especially without out-of-band meta-data or means to reliably update the table to the media, or recover it later.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..