2014-05-03 23:27:38 +01:00
|
|
|
/*
|
2017-07-19 04:01:22 +01:00
|
|
|
* This file is part of the MicroPython project, http://micropython.org/
|
2014-05-03 23:27:38 +01:00
|
|
|
*/
|
|
|
|
|
2014-03-21 23:32:01 +00:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
* @file usbd_storage_msd.c
|
|
|
|
* @author MCD application Team
|
|
|
|
* @version V1.1.0
|
|
|
|
* @date 19-March-2012
|
|
|
|
* @brief This file provides the disk operations functions.
|
|
|
|
******************************************************************************
|
|
|
|
* @attention
|
|
|
|
*
|
|
|
|
* <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
|
|
|
|
*
|
|
|
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
|
|
|
* You may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at:
|
|
|
|
*
|
|
|
|
* http://www.st.com/software_license_agreement_liberty_v2
|
|
|
|
*
|
2017-07-19 04:01:22 +01:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
2014-03-21 23:32:01 +00:00
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*
|
2017-07-19 04:01:22 +01:00
|
|
|
* Heavily modified by dpgeorge for MicroPython.
|
2014-03-21 23:32:01 +00:00
|
|
|
*
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
|
|
|
|
2014-11-01 21:26:06 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
|
2014-03-30 12:30:35 +01:00
|
|
|
#include "usbd_cdc_msc_hid.h"
|
2014-03-21 23:32:01 +00:00
|
|
|
#include "usbd_msc_storage.h"
|
|
|
|
|
2018-02-01 01:44:16 +00:00
|
|
|
#include "py/mpstate.h"
|
2014-03-21 23:32:01 +00:00
|
|
|
#include "storage.h"
|
|
|
|
#include "sdcard.h"
|
|
|
|
|
2014-04-15 19:56:32 +01:00
|
|
|
// These are needed to support removal of the medium, so that the USB drive
|
|
|
|
// can be unmounted, and won't be remounted automatically.
|
2014-09-30 04:12:01 +01:00
|
|
|
static uint8_t flash_started = 0;
|
2014-04-16 18:01:17 +01:00
|
|
|
|
|
|
|
#if MICROPY_HW_HAS_SDCARD
|
2014-09-30 04:12:01 +01:00
|
|
|
static uint8_t sdcard_started = 0;
|
2014-04-16 18:01:17 +01:00
|
|
|
#endif
|
2014-04-15 19:56:32 +01:00
|
|
|
|
2014-03-21 23:32:01 +00:00
|
|
|
/******************************************************************************/
|
|
|
|
// Callback functions for when the internal flash is the mass storage device
|
|
|
|
|
|
|
|
static const int8_t FLASH_STORAGE_Inquirydata[] = { // 36 bytes
|
|
|
|
// LUN 0
|
|
|
|
0x00,
|
2014-03-23 12:48:58 +00:00
|
|
|
0x80, // 0x00 for a fixed drive, 0x80 for a removable drive
|
2014-03-21 23:32:01 +00:00
|
|
|
0x02,
|
|
|
|
0x02,
|
|
|
|
(STANDARD_INQUIRY_DATA_LEN - 5),
|
|
|
|
0x00,
|
|
|
|
0x00,
|
|
|
|
0x00,
|
|
|
|
'u', 'P', 'y', ' ', ' ', ' ', ' ', ' ', // Manufacturer : 8 bytes
|
|
|
|
'm', 'i', 'c', 'r', 'o', 'S', 'D', ' ', // Product : 16 Bytes
|
|
|
|
'F', 'l', 'a', 's', 'h', ' ', ' ', ' ',
|
|
|
|
'1', '.', '0' ,'0', // Version : 4 Bytes
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize the storage medium
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t FLASH_STORAGE_Init(uint8_t lun) {
|
|
|
|
storage_init();
|
2014-09-30 04:12:01 +01:00
|
|
|
flash_started = 1;
|
2014-03-21 23:32:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief return medium capacity and block size
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @param block_num : number of physical block
|
|
|
|
* @param block_size : size of a physical block
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t FLASH_STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) {
|
|
|
|
*block_size = storage_get_block_size();
|
|
|
|
*block_num = storage_get_block_count();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief check whether the medium is ready
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t FLASH_STORAGE_IsReady(uint8_t lun) {
|
2014-09-30 04:12:01 +01:00
|
|
|
if (flash_started) {
|
|
|
|
return 0;
|
2014-04-15 19:56:32 +01:00
|
|
|
}
|
2014-09-30 04:12:01 +01:00
|
|
|
return -1;
|
2014-03-21 23:32:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief check whether the medium is write-protected
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t FLASH_STORAGE_IsWriteProtected(uint8_t lun) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-15 19:56:32 +01:00
|
|
|
// Remove the lun
|
2014-09-30 04:12:01 +01:00
|
|
|
int8_t FLASH_STORAGE_StartStopUnit(uint8_t lun, uint8_t started) {
|
|
|
|
flash_started = started;
|
2014-04-15 19:56:32 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-16 23:08:36 +01:00
|
|
|
int8_t FLASH_STORAGE_PreventAllowMediumRemoval(uint8_t lun, uint8_t param) {
|
|
|
|
// sync the flash so that the cache is cleared and the device can be unplugged/turned off
|
2017-01-27 12:10:18 +00:00
|
|
|
storage_flush();
|
2014-04-16 23:08:36 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-03-21 23:32:01 +00:00
|
|
|
/**
|
|
|
|
* @brief Read data from the medium
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @param buf : Pointer to the buffer to save data
|
|
|
|
* @param blk_addr : address of 1st block to be read
|
|
|
|
* @param blk_len : nmber of blocks to be read
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t FLASH_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
2017-01-27 12:10:18 +00:00
|
|
|
storage_read_blocks(buf, blk_addr, blk_len);
|
2014-03-21 23:32:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Write data to the medium
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @param buf : Pointer to the buffer to write from
|
|
|
|
* @param blk_addr : address of 1st block to be written
|
|
|
|
* @param blk_len : nmber of blocks to be read
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t FLASH_STORAGE_Write (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
2017-01-27 12:10:18 +00:00
|
|
|
storage_write_blocks(buf, blk_addr, blk_len);
|
2014-03-21 23:32:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Return number of supported logical unit
|
|
|
|
* @param None
|
|
|
|
* @retval number of logical unit
|
|
|
|
*/
|
|
|
|
int8_t FLASH_STORAGE_GetMaxLun(void) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const USBD_StorageTypeDef USBD_FLASH_STORAGE_fops = {
|
|
|
|
FLASH_STORAGE_Init,
|
|
|
|
FLASH_STORAGE_GetCapacity,
|
|
|
|
FLASH_STORAGE_IsReady,
|
|
|
|
FLASH_STORAGE_IsWriteProtected,
|
2014-09-30 04:12:01 +01:00
|
|
|
FLASH_STORAGE_StartStopUnit,
|
2014-04-16 23:08:36 +01:00
|
|
|
FLASH_STORAGE_PreventAllowMediumRemoval,
|
2014-03-21 23:32:01 +00:00
|
|
|
FLASH_STORAGE_Read,
|
|
|
|
FLASH_STORAGE_Write,
|
|
|
|
FLASH_STORAGE_GetMaxLun,
|
|
|
|
(int8_t *)FLASH_STORAGE_Inquirydata,
|
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
// Callback functions for when the SD card is the mass storage device
|
|
|
|
|
2014-03-30 12:30:35 +01:00
|
|
|
#if MICROPY_HW_HAS_SDCARD
|
|
|
|
|
2014-03-21 23:32:01 +00:00
|
|
|
static const int8_t SDCARD_STORAGE_Inquirydata[] = { // 36 bytes
|
|
|
|
// LUN 0
|
|
|
|
0x00,
|
|
|
|
0x80, // 0x00 for a fixed drive, 0x80 for a removable drive
|
|
|
|
0x02,
|
|
|
|
0x02,
|
|
|
|
(STANDARD_INQUIRY_DATA_LEN - 5),
|
|
|
|
0x00,
|
|
|
|
0x00,
|
|
|
|
0x00,
|
|
|
|
'u', 'P', 'y', ' ', ' ', ' ', ' ', ' ', // Manufacturer : 8 bytes
|
|
|
|
'm', 'i', 'c', 'r', 'o', 'S', 'D', ' ', // Product : 16 Bytes
|
|
|
|
'S', 'D', ' ', 'c', 'a', 'r', 'd', ' ',
|
|
|
|
'1', '.', '0' ,'0', // Version : 4 Bytes
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize the storage medium
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t SDCARD_STORAGE_Init(uint8_t lun) {
|
|
|
|
if (!sdcard_power_on()) {
|
|
|
|
return -1;
|
|
|
|
}
|
2014-09-30 04:12:01 +01:00
|
|
|
sdcard_started = 1;
|
2014-03-21 23:32:01 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief return medium capacity and block size
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @param block_num : number of physical block
|
|
|
|
* @param block_size : size of a physical block
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t SDCARD_STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) {
|
|
|
|
*block_size = SDCARD_BLOCK_SIZE;
|
|
|
|
*block_num = sdcard_get_capacity_in_bytes() / SDCARD_BLOCK_SIZE;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief check whether the medium is ready
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t SDCARD_STORAGE_IsReady(uint8_t lun) {
|
2014-09-30 04:12:01 +01:00
|
|
|
if (sdcard_started) {
|
|
|
|
return 0;
|
2014-04-15 19:56:32 +01:00
|
|
|
}
|
2014-09-30 04:12:01 +01:00
|
|
|
return -1;
|
2014-03-21 23:32:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief check whether the medium is write-protected
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t SDCARD_STORAGE_IsWriteProtected(uint8_t lun) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-15 19:56:32 +01:00
|
|
|
// Remove the lun
|
2014-09-30 04:12:01 +01:00
|
|
|
int8_t SDCARD_STORAGE_StartStopUnit(uint8_t lun, uint8_t started) {
|
|
|
|
sdcard_started = started;
|
2014-04-15 19:56:32 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-16 23:08:36 +01:00
|
|
|
int8_t SDCARD_STORAGE_PreventAllowMediumRemoval(uint8_t lun, uint8_t param) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-03-21 23:32:01 +00:00
|
|
|
/**
|
|
|
|
* @brief Read data from the medium
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @param buf : Pointer to the buffer to save data
|
|
|
|
* @param blk_addr : address of 1st block to be read
|
|
|
|
* @param blk_len : nmber of blocks to be read
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
2014-09-15 23:49:57 +01:00
|
|
|
if (sdcard_read_blocks(buf, blk_addr, blk_len) != 0) {
|
2014-03-21 23:32:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Write data to the medium
|
|
|
|
* @param lun : logical unit number
|
|
|
|
* @param buf : Pointer to the buffer to write from
|
|
|
|
* @param blk_addr : address of 1st block to be written
|
|
|
|
* @param blk_len : nmber of blocks to be read
|
|
|
|
* @retval Status
|
|
|
|
*/
|
|
|
|
int8_t SDCARD_STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
2014-09-15 23:49:57 +01:00
|
|
|
if (sdcard_write_blocks(buf, blk_addr, blk_len) != 0) {
|
2014-03-21 23:32:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Return number of supported logical unit
|
|
|
|
* @param None
|
|
|
|
* @retval number of logical unit
|
|
|
|
*/
|
|
|
|
int8_t SDCARD_STORAGE_GetMaxLun(void) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const USBD_StorageTypeDef USBD_SDCARD_STORAGE_fops = {
|
|
|
|
SDCARD_STORAGE_Init,
|
|
|
|
SDCARD_STORAGE_GetCapacity,
|
|
|
|
SDCARD_STORAGE_IsReady,
|
|
|
|
SDCARD_STORAGE_IsWriteProtected,
|
2014-09-30 04:12:01 +01:00
|
|
|
SDCARD_STORAGE_StartStopUnit,
|
2014-04-16 23:08:36 +01:00
|
|
|
SDCARD_STORAGE_PreventAllowMediumRemoval,
|
2014-03-21 23:32:01 +00:00
|
|
|
SDCARD_STORAGE_Read,
|
|
|
|
SDCARD_STORAGE_Write,
|
|
|
|
SDCARD_STORAGE_GetMaxLun,
|
|
|
|
(int8_t *)SDCARD_STORAGE_Inquirydata,
|
|
|
|
};
|
2014-03-30 12:30:35 +01:00
|
|
|
|
|
|
|
#endif // MICROPY_HW_HAS_SDCARD
|