cancel
Showing results for 
Search instead for 
Did you mean: 

how to acess internal flash as mass storage device

vs.3
Associate II

i tried but it asking formate the device in my computer.

i am using #Stm32f103ret6​  #USB​  #Mass-storage​ 

13 REPLIES 13
adrian
Associate III

You’d have to write a driver to read and write sectors from the internal flash.

assuming that is working you’re going to be very limited in the formats it could be organised with due to the size of the flash (minus the amount used for your application), FAT12.

internal storage is not a good choice for mass storage.

vs.3
Associate II

it is detecting as device but asking to formate the device in my computer

int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,

              uint8_t lun, 

              uint8_t *params)

{

  

 switch (params[0])

 {

 case SCSI_TEST_UNIT_READY:

  return SCSI_TestUnitReady(pdev, lun, params);

   

 case SCSI_REQUEST_SENSE:

  return SCSI_RequestSense (pdev, lun, params);

 case SCSI_INQUIRY:

  return SCSI_Inquiry(pdev, lun, params);

   

 case SCSI_START_STOP_UNIT:

  return SCSI_StartStopUnit(pdev, lun, params);

   

 case SCSI_ALLOW_MEDIUM_REMOVAL:

  return SCSI_StartStopUnit(pdev, lun, params);

   

 case SCSI_MODE_SENSE6:

  return SCSI_ModeSense6 (pdev, lun, params);

   

 case SCSI_MODE_SENSE10:

  return SCSI_ModeSense10 (pdev, lun, params);

   

 case SCSI_READ_FORMAT_CAPACITIES:

  return SCSI_ReadFormatCapacity(pdev, lun, params); ///#stops here

   

 case SCSI_READ_CAPACITY10:

  return SCSI_ReadCapacity10(pdev, lun, params);

   

 case SCSI_READ10:

  return SCSI_Read10(pdev, lun, params); 

   

 case SCSI_WRITE10:

  return SCSI_Write10(pdev, lun, params);

   

 case SCSI_VERIFY10:

  return SCSI_Verify10(pdev, lun, params);

   

 default:

  SCSI_SenseCode(pdev, 

          lun,

          ILLEGAL_REQUEST, 

          INVALID_CDB);   

  return -1;

 }

}

scsi_readformate_capacity();

remaining scsci cmds not excuted

adrian
Associate III

You’re going to have to step through the code and see what is happening, in this case it’s asking for the size of the storage device, your driver will need to return an appropriate value.

put a breakpoint on the call to SCSI_ReadFormatCapacity and see what user functions it calls to determine this.

static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)

{

 USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; 

  

 uint16_t blk_size;

 uint32_t blk_nbr;

 uint16_t i;

  

 for(i=0 ; i < 12 ; i++) 

 {

  hmsc->bot_data[i] = 0;

 }

  

 if(((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &blk_nbr, &blk_size) != 0)

 {

  SCSI_SenseCode(pdev,

          lun,

          NOT_READY, 

          MEDIUM_NOT_PRESENT);

  return -1;

 } 

 else

 {

  hmsc->bot_data[3] = 0x08;

  hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1) >> 24);

  hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1) >> 16);

  hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1) >> 8);

  hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1);

   

  hmsc->bot_data[8] = 0x02;

  hmsc->bot_data[9] = (uint8_t)(blk_size >> 16);

  hmsc->bot_data[10] = (uint8_t)(blk_size >> 8);

  hmsc->bot_data[11] = (uint8_t)(blk_size);

   

  hmsc->bot_data_length = 12;

  return 0;

 }

}

return 0;

# 00h for success, 02h for an error (called a Check Condition), or 08h for busy

this is my drivers basic code

#define STORAGE_LUN_NBR         1

#define STORAGE_BLK_NBR         0x10000

#define STORAGE_BLK_SIZ         0x200

/* USER CODE BEGIN INQUIRY_DATA_FS */

/** USB Mass storage Standard Inquiry Data. */

const int8_t STORAGE_Inquirydata_FS[] = {/* 36 */

  

 /* LUN 0 */

 0x00,

 0x80,

 0x02,

 0x02,

 (STANDARD_INQUIRY_DATA_LEN - 5),

 0x00,

 0x00,

 0x00,

 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */

 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product   : 16 Bytes */

 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',

 '0', '.', '0' ,'1'           /* Version   : 4 Bytes */

}; 

/* USER CODE END INQUIRY_DATA_FS */

/* USER CODE BEGIN PRIVATE_VARIABLES */

/* USER CODE END PRIVATE_VARIABLES */

/**

 * @}

 */

/** @defgroup USBD_STORAGE_Exported_Variables

 * @brief Public variables.

 * @{

 */

extern USBD_HandleTypeDef hUsbDeviceFS;

/* USER CODE BEGIN EXPORTED_VARIABLES */

/* USER CODE END EXPORTED_VARIABLES */

/**

 * @}

 */

/** @defgroup USBD_STORAGE_Private_FunctionPrototypes

 * @brief Private functions declaration.

 * @{

 */

static int8_t STORAGE_Init_FS(uint8_t lun);

static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size);

static int8_t STORAGE_IsReady_FS(uint8_t lun);

static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun);

static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);

static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);

static int8_t STORAGE_GetMaxLun_FS(void);

/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */

/*TODO FUNCTIONAL*/

/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */

/**

 * @}

 */

USBD_StorageTypeDef USBD_Storage_Interface_fops_FS =

{

 STORAGE_Init_FS,

 STORAGE_GetCapacity_FS,

 STORAGE_IsReady_FS,

 STORAGE_IsWriteProtected_FS,

 STORAGE_Read_FS,

 STORAGE_Write_FS,

 STORAGE_GetMaxLun_FS,

 (int8_t *)STORAGE_Inquirydata_FS

};

/* Private functions ---------------------------------------------------------*/

/**

 * @brief Initializes over USB FS IP

 * @param lun:

 * @retval USBD_OK if all operations are OK else USBD_FAIL

 */

int8_t STORAGE_Init_FS(uint8_t lun)

{

 /* USER CODE BEGIN 2 */

HAL_FLASH_Unlock();

return (USBD_OK);

 /* USER CODE END 2 */

}

/**

 * @brief .

 * @param lun: .

 * @param block_num: .

 * @param block_size: .

 * @retval USBD_OK if all operations are OK else USBD_FAIL

 */

int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)

{

 /* USER CODE BEGIN 3 */

 *block_num = STORAGE_BLK_NBR;

 *block_size = STORAGE_BLK_SIZ;

 return (USBD_OK);

 /* USER CODE END 3 */

}

/**

 * @brief .

 * @param lun: .

 * @retval USBD_OK if all operations are OK else USBD_FAIL

 */

int8_t STORAGE_IsReady_FS(uint8_t lun)

{

 /* USER CODE BEGIN 4 */

 return (USBD_OK);

 /* USER CODE END 4 */

}

/**

 * @brief .

 * @param lun: .

 * @retval USBD_OK if all operations are OK else USBD_FAIL

 */

int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)

{

 /* USER CODE BEGIN 5 */

 return (USBD_OK);

 /* USER CODE END 5 */

}

/**

 * @brief .

 * @param lun: .

 * @retval USBD_OK if all operations are OK else USBD_FAIL

 */

int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)

{

  return (USBD_OK);

}

/**

 * @brief .

 * @param lun: .

 * @retval USBD_OK if all operations are OK else USBD_FAIL

 */

int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)

{

 /* USER CODE BEGIN 7 */

 return (USBD_OK);

 /* USER CODE END 7 */

}

/**

 * @brief .

 * @param None

 * @retval .

 */

int8_t STORAGE_GetMaxLun_FS(void)

{

 /* USER CODE BEGIN 8 */

 return (STORAGE_LUN_NBR - 1);

// return 0;

 /* USER CODE END 8 */

}

do i need change any think in the code to detect the device

Windows expects your device to contain a useable FAT file system, if it doesn't it will want to format the media and will expect your sector level read and write functions to actually do their job properly. ​

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

in my computer shows my device if click on it it is asking to formate if i click on formate it shows windows was unable to complete the formate

SCSI_Write10();

while excuting this function above problem came.

adrian
Associate III

The driver you posted above is incomplete, there is no code to read and write to the flash, it just blindly says that it completed ok.

you need to provide a complete driver.

So test your underlying read/write functions so the actually function in a correct and timely manner. The erase size and time on STM32 tends to be rather large, and not entirely compatible with real time expectations, or as a 512 sector.

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

Returning OK doesn't actually do anything, you'll need to add code to perform the requested operation. A mass storage device will need to return the exact same data that was written to any given block. That's how that stuff works.

/**
 * @brief .
 * @param lun: .
 * @retval USBD_OK if all operations are OK else USBD_FAIL
 */
 
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  return (USBD_OK);
}
 
/**
 * @brief .
 * @param lun: .
 * @retval USBD_OK if all operations are OK else USBD_FAIL
 */
 
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
 /* USER CODE BEGIN 7 */
 return (USBD_OK);
 /* USER CODE END 7 */
} 

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