From 1d7fb82f0aec11331635532583617d773888b991 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 15 Sep 2014 23:49:57 +0100 Subject: [PATCH] stmhal: Change 64-bit arithmetic to 32-bit for SD card block addressing. By measuring SD card addresses in blocks and not bytes, one can get away with using 32-bit numbers. This patch also uses proper atomic lock/unlock around SD card read/write, adds SD.info() function, and gives error code for failed read/writes. --- stmhal/diskio.c | 4 +- stmhal/hal/inc/stm32f4xx_hal_sd.h | 10 +- stmhal/hal/src/stm32f4xx_hal_sd.c | 56 +++++++--- stmhal/sdcard.c | 104 ++++++++++-------- stmhal/sdcard.h | 6 +- stmhal/usbd_msc_storage.c | 4 +- .../class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h | 2 +- .../class/cdc_msc_hid/src/usbd_msc_scsi.c | 23 ++-- 8 files changed, 126 insertions(+), 83 deletions(-) diff --git a/stmhal/diskio.c b/stmhal/diskio.c index 35b9eab99f..44059b04d5 100644 --- a/stmhal/diskio.c +++ b/stmhal/diskio.c @@ -127,7 +127,7 @@ DRESULT disk_read ( #if MICROPY_HW_HAS_SDCARD case PD_SDCARD: - if (!sdcard_read_blocks(buff, sector, count)) { + if (sdcard_read_blocks(buff, sector, count) != 0) { return RES_ERROR; } return RES_OK; @@ -160,7 +160,7 @@ DRESULT disk_write ( #if MICROPY_HW_HAS_SDCARD case PD_SDCARD: - if (!sdcard_write_blocks(buff, sector, count)) { + if (sdcard_write_blocks(buff, sector, count) != 0) { return RES_ERROR; } return RES_OK; diff --git a/stmhal/hal/inc/stm32f4xx_hal_sd.h b/stmhal/hal/inc/stm32f4xx_hal_sd.h index 93bacc5da8..66ae7cc1bf 100644 --- a/stmhal/hal/inc/stm32f4xx_hal_sd.h +++ b/stmhal/hal/inc/stm32f4xx_hal_sd.h @@ -630,8 +630,9 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd); * @{ */ /* Blocking mode: Polling */ -HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks); -HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks); +// dpgeorge: read/write functions renamed to emphasise that address is given by block number +HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_BlockNumber(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks); +HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_BlockNumber(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks); HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr); /* Non-Blocking mode: Interrupt */ @@ -646,8 +647,9 @@ void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd); void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd); /* Non-Blocking mode: DMA */ -HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks); -HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks); +// dpgeorge: read/write functions renamed to emphasise that address is given by block number +HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_BlockNumber_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks); +HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_BlockNumber_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks); HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout); HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout); /** diff --git a/stmhal/hal/src/stm32f4xx_hal_sd.c b/stmhal/hal/src/stm32f4xx_hal_sd.c index 5018f1b23c..75439dabb0 100644 --- a/stmhal/hal/src/stm32f4xx_hal_sd.c +++ b/stmhal/hal/src/stm32f4xx_hal_sd.c @@ -449,13 +449,13 @@ __weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) * is managed by polling mode. * @param hsd: SD handle * @param pReadBuffer: pointer to the buffer that will contain the received data - * @param ReadAddr: Address from where data is to be read + * @param BlockNumber: Block number from where data is to be read (byte address = BlockNumber * BlockSize) * @param BlockSize: SD card Data block size * This parameter should be 512 * @param NumberOfBlocks: Number of SD blocks to read * @retval SD Card error state */ -HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks) +HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_BlockNumber(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks) { SDIO_CmdInitTypeDef sdio_cmdinitstructure; SDIO_DataInitTypeDef sdio_datainitstructure; @@ -465,10 +465,16 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuff /* Initialize data control register */ hsd->Instance->DCTRL = 0; + uint32_t ReadAddr; if (hsd->CardType == HIGH_CAPACITY_SD_CARD) { BlockSize = 512; - ReadAddr /= 512; + ReadAddr = BlockNumber; + } + else + { + // should not overflow for standard-capacity cards + ReadAddr = BlockNumber * BlockSize; } /* Set Block Size for Card */ @@ -507,7 +513,7 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuff sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK; } - sdio_cmdinitstructure.Argument = (uint32_t)ReadAddr; + sdio_cmdinitstructure.Argument = ReadAddr; SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); /* Read block(s) in polling mode */ @@ -633,13 +639,13 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuff * transfer is managed by polling mode. * @param hsd: SD handle * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit - * @param WriteAddr: Address from where data is to be written + * @param BlockNumber: Block number to where data is to be written (byte address = BlockNumber * BlockSize) * @param BlockSize: SD card Data block size * This parameter should be 512. * @param NumberOfBlocks: Number of SD blocks to write * @retval SD Card error state */ -HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks) +HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_BlockNumber(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks) { SDIO_CmdInitTypeDef sdio_cmdinitstructure; SDIO_DataInitTypeDef sdio_datainitstructure; @@ -651,10 +657,16 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBu /* Initialize data control register */ hsd->Instance->DCTRL = 0; + uint32_t WriteAddr; if (hsd->CardType == HIGH_CAPACITY_SD_CARD) { BlockSize = 512; - WriteAddr /= 512; + WriteAddr = BlockNumber; + } + else + { + // should not overflow for standard-capacity cards + WriteAddr = BlockNumber * BlockSize; } /* Set Block Size for Card */ @@ -684,7 +696,7 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBu sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK; } - sdio_cmdinitstructure.Argument = (uint32_t)WriteAddr; + sdio_cmdinitstructure.Argument = WriteAddr; SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); /* Check for error conditions */ @@ -851,13 +863,13 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBu * to check the completion of the read process * @param hsd: SD handle * @param pReadBuffer: Pointer to the buffer that will contain the received data - * @param ReadAddr: Address from where data is to be read + * @param BlockNumber: Block number from where data is to be read (byte address = BlockNumber * BlockSize) * @param BlockSize: SD card Data block size * This paramater should be 512. * @param NumberOfBlocks: Number of blocks to read. * @retval SD Card error state */ -HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks) +HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_BlockNumber_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks) { SDIO_CmdInitTypeDef sdio_cmdinitstructure; SDIO_DataInitTypeDef sdio_datainitstructure; @@ -898,10 +910,16 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead /* Enable the DMA Stream */ HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks)); + uint32_t ReadAddr; if (hsd->CardType == HIGH_CAPACITY_SD_CARD) { BlockSize = 512; - ReadAddr /= 512; + ReadAddr = BlockNumber; + } + else + { + // should not overflow for standard-capacity cards + ReadAddr = BlockNumber * BlockSize; } /* Set Block Size for Card */ @@ -941,7 +959,7 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK; } - sdio_cmdinitstructure.Argument = (uint32_t)ReadAddr; + sdio_cmdinitstructure.Argument = ReadAddr; SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); /* Check for error conditions */ @@ -968,13 +986,13 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead * to check the completion of the write process (by SD current status polling). * @param hsd: SD handle * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit - * @param WriteAddr: Address from where data is to be read + * @param BlockNumber: Block number to where data is to be written (byte address = BlockNumber * BlockSize) * @param BlockSize: the SD card Data block size * This parameter should be 512. * @param NumberOfBlocks: Number of blocks to write * @retval SD Card error state */ -HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks) +HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_BlockNumber_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks) { SDIO_CmdInitTypeDef sdio_cmdinitstructure; SDIO_DataInitTypeDef sdio_datainitstructure; @@ -1015,10 +1033,16 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWri /* Enable SDIO DMA transfer */ __HAL_SD_SDIO_DMA_ENABLE(); + uint32_t WriteAddr; if (hsd->CardType == HIGH_CAPACITY_SD_CARD) { BlockSize = 512; - WriteAddr /= 512; + WriteAddr = BlockNumber; + } + else + { + // should not overflow for standard-capacity cards + WriteAddr = BlockNumber * BlockSize; } /* Set Block Size for Card */ @@ -1049,7 +1073,7 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWri sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK; } - sdio_cmdinitstructure.Argument = (uint32_t)WriteAddr; + sdio_cmdinitstructure.Argument = WriteAddr; SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); /* Check for error conditions */ diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c index 8952161b69..a628d3e450 100644 --- a/stmhal/sdcard.c +++ b/stmhal/sdcard.c @@ -141,54 +141,46 @@ uint64_t sdcard_get_capacity_in_bytes(void) { return cardinfo.CardCapacity; } -bool sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { +mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { // check that dest pointer is aligned on a 4-byte boundary if (((uint32_t)dest & 3) != 0) { - return false; + return SD_ERROR; } // check that SD card is initialised if (sd_handle.Instance == NULL) { - return false; + return SD_ERROR; } // We must disable IRQs because the SDIO peripheral has a small FIFO // buffer and we can't let it fill up in the middle of a read. // This will not be needed when SD uses DMA for transfer. - __disable_irq(); - HAL_SD_ErrorTypedef err = HAL_SD_ReadBlocks(&sd_handle, (uint32_t*)dest, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, num_blocks); - __enable_irq(); + mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + HAL_SD_ErrorTypedef err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks); + MICROPY_END_ATOMIC_SECTION(atomic_state); - if (err != SD_OK) { - return false; - } - - return true; + return err; } -bool sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { +mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { // check that src pointer is aligned on a 4-byte boundary if (((uint32_t)src & 3) != 0) { - return false; + return SD_ERROR; } // check that SD card is initialised if (sd_handle.Instance == NULL) { - return false; + return SD_ERROR; } // We must disable IRQs because the SDIO peripheral has a small FIFO // buffer and we can't let it drain to empty in the middle of a write. // This will not be needed when SD uses DMA for transfer. - __disable_irq(); - HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks(&sd_handle, (uint32_t*)src, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, num_blocks); - __enable_irq(); + mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks); + MICROPY_END_ATOMIC_SECTION(atomic_state); - if (err != SD_OK) { - return false; - } - - return true; + return err; } #if 0 @@ -205,7 +197,7 @@ bool sdcard_read_blocks_dma(uint8_t *dest, uint32_t block_num, uint32_t num_bloc } // do the read - if (HAL_SD_ReadBlocks_DMA(&sd_handle, (uint32_t*)dest, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE) != SD_OK) { + if (HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE) != SD_OK) { return false; } @@ -230,7 +222,7 @@ bool sdcard_write_blocks_dma(const uint8_t *src, uint32_t block_num, uint32_t nu SD_Error status; - status = HAL_SD_WriteBlock_DMA(&sd_handle, (uint32_t*)src, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, num_blocks); + status = HAL_SD_WriteBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks); if (status != SD_OK) { return false; } @@ -247,14 +239,17 @@ bool sdcard_write_blocks_dma(const uint8_t *src, uint32_t block_num, uint32_t nu /******************************************************************************/ // Micro Python bindings +// +// Note: these function are a bit ad-hoc at the moment and are mainly intended +// for testing purposes. In the future SD should be a proper class with a +// consistent interface and methods to mount/unmount it. -static mp_obj_t sd_present(mp_obj_t self) { +STATIC mp_obj_t sd_present(mp_obj_t self) { return MP_BOOL(sdcard_is_present()); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(sd_present_obj, sd_present); -static MP_DEFINE_CONST_FUN_OBJ_1(sd_present_obj, sd_present); - -static mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) { +STATIC mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) { bool result; if (mp_obj_is_true(state)) { result = sdcard_power_on(); @@ -264,40 +259,59 @@ static mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) { } return MP_BOOL(result); } +STATIC MP_DEFINE_CONST_FUN_OBJ_2(sd_power_obj, sd_power); -static MP_DEFINE_CONST_FUN_OBJ_2(sd_power_obj, sd_power); - -static mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) { - uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE); - if (!sdcard_read_blocks(dest, mp_obj_get_int(block_num), 1)) { - m_free(dest, SDCARD_BLOCK_SIZE); +STATIC mp_obj_t sd_info(mp_obj_t self) { + HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo); + if (sd_handle.Instance == NULL) { return mp_const_none; } + HAL_SD_CardInfoTypedef cardinfo; + HAL_SD_Get_CardInfo(&sd_handle, &cardinfo); + // cardinfo.SD_csd and cardinfo.SD_cid have lots of info but we don't use them + mp_obj_t tuple[3] = { + mp_obj_new_int_from_ull(cardinfo.CardCapacity), + mp_obj_new_int_from_uint(cardinfo.CardBlockSize), + mp_obj_new_int(cardinfo.CardType), + }; + return mp_obj_new_tuple(3, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(sd_info_obj, sd_info); + +STATIC mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) { + uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE); + mp_uint_t ret = sdcard_read_blocks(dest, mp_obj_get_int(block_num), 1); + + if (ret != 0) { + m_free(dest, SDCARD_BLOCK_SIZE); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "sdcard_read_blocks failed [%u]", ret)); + } + return mp_obj_new_bytearray_by_ref(SDCARD_BLOCK_SIZE, dest); } +STATIC MP_DEFINE_CONST_FUN_OBJ_2(sd_read_obj, sd_read); -static MP_DEFINE_CONST_FUN_OBJ_2(sd_read_obj, sd_read); - -static mp_obj_t sd_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t source) { +STATIC mp_obj_t sd_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t data) { mp_buffer_info_t bufinfo; - uint8_t tmp[1]; - - pyb_buf_get_for_send(source, &bufinfo, tmp); + mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); if (bufinfo.len % SDCARD_BLOCK_SIZE != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "writes must be aligned to SDCARD_BLOCK_SIZE (%d) bytes", SDCARD_BLOCK_SIZE)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "writes must be a multiple of %d bytes", SDCARD_BLOCK_SIZE)); } - if (!sdcard_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_BLOCK_SIZE)) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "sdcard_write_blocks failed")); + mp_uint_t ret = sdcard_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_BLOCK_SIZE); + + if (ret != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "sdcard_write_blocks failed [%u]", ret)); } + return mp_const_none; } - -static MP_DEFINE_CONST_FUN_OBJ_3(sd_write_obj, sd_write); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(sd_write_obj, sd_write); STATIC const mp_map_elem_t sdcard_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_present), (mp_obj_t)&sd_present_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_power), (mp_obj_t)&sd_power_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&sd_info_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&sd_read_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&sd_write_obj }, }; diff --git a/stmhal/sdcard.h b/stmhal/sdcard.h index 3a5353467e..8197768de0 100644 --- a/stmhal/sdcard.h +++ b/stmhal/sdcard.h @@ -32,7 +32,9 @@ bool sdcard_is_present(void); bool sdcard_power_on(void); void sdcard_power_off(void); uint64_t sdcard_get_capacity_in_bytes(void); -bool sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); -bool sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); + +// these return 0 on success, non-zero on error +mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); +mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); extern const struct _mp_obj_base_t pyb_sdcard_obj; diff --git a/stmhal/usbd_msc_storage.c b/stmhal/usbd_msc_storage.c index b6b1972266..ab2d4459ab 100644 --- a/stmhal/usbd_msc_storage.c +++ b/stmhal/usbd_msc_storage.c @@ -321,7 +321,7 @@ int8_t SDCARD_STORAGE_PreventAllowMediumRemoval(uint8_t lun, uint8_t param) { * @retval Status */ int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { - if (!sdcard_read_blocks(buf, blk_addr, blk_len)) { + if (sdcard_read_blocks(buf, blk_addr, blk_len) != 0) { return -1; } return 0; @@ -336,7 +336,7 @@ int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_ * @retval Status */ int8_t SDCARD_STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { - if (!sdcard_write_blocks(buf, blk_addr, blk_len)) { + if (sdcard_write_blocks(buf, blk_addr, blk_len) != 0) { return -1; } return 0; diff --git a/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h b/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h index 798bdc99db..7eca900ee0 100644 --- a/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h +++ b/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h @@ -83,7 +83,7 @@ typedef struct { uint16_t scsi_blk_size; uint32_t scsi_blk_nbr; - uint32_t scsi_blk_addr; + uint32_t scsi_blk_addr_in_blks; uint32_t scsi_blk_len; } USBD_MSC_BOT_HandleTypeDef; diff --git a/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c b/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c index 60258d64d9..894812c18f 100644 --- a/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c +++ b/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c @@ -510,7 +510,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *para return -1; } - hmsc->scsi_blk_addr = (params[2] << 24) | \ + hmsc->scsi_blk_addr_in_blks = (params[2] << 24) | \ (params[3] << 16) | \ (params[4] << 8) | \ params[5]; @@ -520,13 +520,12 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *para - if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0) + if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr_in_blks, hmsc->scsi_blk_len) < 0) { return -1; /* error */ } hmsc->bot_state = USBD_BOT_DATA_IN; - hmsc->scsi_blk_addr *= hmsc->scsi_blk_size; hmsc->scsi_blk_len *= hmsc->scsi_blk_size; /* cases 4,5 : Hi <> Dn */ @@ -591,7 +590,7 @@ static int8_t SCSI_Write10 (USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *pa } - hmsc->scsi_blk_addr = (params[2] << 24) | \ + hmsc->scsi_blk_addr_in_blks = (params[2] << 24) | \ (params[3] << 16) | \ (params[4] << 8) | \ params[5]; @@ -601,13 +600,12 @@ static int8_t SCSI_Write10 (USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *pa /* check if LBA address is in the right range */ if(SCSI_CheckAddressRange(pdev, lun, - hmsc->scsi_blk_addr, + hmsc->scsi_blk_addr_in_blks, hmsc->scsi_blk_len) < 0) { return -1; /* error */ } - hmsc->scsi_blk_addr *= hmsc->scsi_blk_size; hmsc->scsi_blk_len *= hmsc->scsi_blk_size; /* cases 3,11,13 : Hn,Ho <> D0 */ @@ -656,9 +654,12 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *pa return -1; /* Error, Verify Mode Not supported*/ } + hmsc->scsi_blk_addr_in_blks = (params[2] << 24) | (params[3] << 16) | (params[4] << 8) | params[5]; + hmsc->scsi_blk_len = (params[7] << 8) | params[8]; + if(SCSI_CheckAddressRange(pdev, lun, - hmsc->scsi_blk_addr, + hmsc->scsi_blk_addr_in_blks, hmsc->scsi_blk_len) < 0) { return -1; /* error */ @@ -705,7 +706,7 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun) if( ((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun , hmsc->bot_data, - hmsc->scsi_blk_addr / hmsc->scsi_blk_size, + hmsc->scsi_blk_addr_in_blks, len / hmsc->scsi_blk_size) < 0) { @@ -723,7 +724,7 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun) len); - hmsc->scsi_blk_addr += len; + hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size; hmsc->scsi_blk_len -= len; /* case 6 : Hi = Di */ @@ -752,7 +753,7 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun) if(((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun , hmsc->bot_data, - hmsc->scsi_blk_addr / hmsc->scsi_blk_size, + hmsc->scsi_blk_addr_in_blks, len / hmsc->scsi_blk_size) < 0) { SCSI_SenseCode(pdev, @@ -763,7 +764,7 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun) } - hmsc->scsi_blk_addr += len; + hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size; hmsc->scsi_blk_len -= len; /* case 12 : Ho = Do */