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.
This commit is contained in:
parent
6ff42c54bb
commit
1d7fb82f0a
|
@ -127,7 +127,7 @@ DRESULT disk_read (
|
||||||
|
|
||||||
#if MICROPY_HW_HAS_SDCARD
|
#if MICROPY_HW_HAS_SDCARD
|
||||||
case PD_SDCARD:
|
case PD_SDCARD:
|
||||||
if (!sdcard_read_blocks(buff, sector, count)) {
|
if (sdcard_read_blocks(buff, sector, count) != 0) {
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
}
|
}
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
|
@ -160,7 +160,7 @@ DRESULT disk_write (
|
||||||
|
|
||||||
#if MICROPY_HW_HAS_SDCARD
|
#if MICROPY_HW_HAS_SDCARD
|
||||||
case PD_SDCARD:
|
case PD_SDCARD:
|
||||||
if (!sdcard_write_blocks(buff, sector, count)) {
|
if (sdcard_write_blocks(buff, sector, count) != 0) {
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
}
|
}
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
|
|
|
@ -630,8 +630,9 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd);
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* Blocking mode: Polling */
|
/* Blocking mode: Polling */
|
||||||
HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, 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_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, 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);
|
||||||
|
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);
|
HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr);
|
||||||
|
|
||||||
/* Non-Blocking mode: Interrupt */
|
/* Non-Blocking mode: Interrupt */
|
||||||
|
@ -646,8 +647,9 @@ void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd);
|
||||||
void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd);
|
void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd);
|
||||||
|
|
||||||
/* Non-Blocking mode: DMA */
|
/* 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);
|
// dpgeorge: read/write functions renamed to emphasise that address is given by block number
|
||||||
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_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_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);
|
||||||
HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);
|
HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -449,13 +449,13 @@ __weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
|
||||||
* is managed by polling mode.
|
* is managed by polling mode.
|
||||||
* @param hsd: SD handle
|
* @param hsd: SD handle
|
||||||
* @param pReadBuffer: pointer to the buffer that will contain the received data
|
* @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
|
* @param BlockSize: SD card Data block size
|
||||||
* This parameter should be 512
|
* This parameter should be 512
|
||||||
* @param NumberOfBlocks: Number of SD blocks to read
|
* @param NumberOfBlocks: Number of SD blocks to read
|
||||||
* @retval SD Card error state
|
* @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_CmdInitTypeDef sdio_cmdinitstructure;
|
||||||
SDIO_DataInitTypeDef sdio_datainitstructure;
|
SDIO_DataInitTypeDef sdio_datainitstructure;
|
||||||
|
@ -465,10 +465,16 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuff
|
||||||
/* Initialize data control register */
|
/* Initialize data control register */
|
||||||
hsd->Instance->DCTRL = 0;
|
hsd->Instance->DCTRL = 0;
|
||||||
|
|
||||||
|
uint32_t ReadAddr;
|
||||||
if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
|
if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
|
||||||
{
|
{
|
||||||
BlockSize = 512;
|
BlockSize = 512;
|
||||||
ReadAddr /= 512;
|
ReadAddr = BlockNumber;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// should not overflow for standard-capacity cards
|
||||||
|
ReadAddr = BlockNumber * BlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Block Size for Card */
|
/* 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.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdio_cmdinitstructure.Argument = (uint32_t)ReadAddr;
|
sdio_cmdinitstructure.Argument = ReadAddr;
|
||||||
SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
|
SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
|
||||||
|
|
||||||
/* Read block(s) in polling mode */
|
/* 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.
|
* transfer is managed by polling mode.
|
||||||
* @param hsd: SD handle
|
* @param hsd: SD handle
|
||||||
* @param pWriteBuffer: pointer to the buffer that will contain the data to transmit
|
* @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
|
* @param BlockSize: SD card Data block size
|
||||||
* This parameter should be 512.
|
* This parameter should be 512.
|
||||||
* @param NumberOfBlocks: Number of SD blocks to write
|
* @param NumberOfBlocks: Number of SD blocks to write
|
||||||
* @retval SD Card error state
|
* @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_CmdInitTypeDef sdio_cmdinitstructure;
|
||||||
SDIO_DataInitTypeDef sdio_datainitstructure;
|
SDIO_DataInitTypeDef sdio_datainitstructure;
|
||||||
|
@ -651,10 +657,16 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBu
|
||||||
/* Initialize data control register */
|
/* Initialize data control register */
|
||||||
hsd->Instance->DCTRL = 0;
|
hsd->Instance->DCTRL = 0;
|
||||||
|
|
||||||
|
uint32_t WriteAddr;
|
||||||
if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
|
if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
|
||||||
{
|
{
|
||||||
BlockSize = 512;
|
BlockSize = 512;
|
||||||
WriteAddr /= 512;
|
WriteAddr = BlockNumber;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// should not overflow for standard-capacity cards
|
||||||
|
WriteAddr = BlockNumber * BlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Block Size for Card */
|
/* 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.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdio_cmdinitstructure.Argument = (uint32_t)WriteAddr;
|
sdio_cmdinitstructure.Argument = WriteAddr;
|
||||||
SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
|
SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
|
||||||
|
|
||||||
/* Check for error conditions */
|
/* 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
|
* to check the completion of the read process
|
||||||
* @param hsd: SD handle
|
* @param hsd: SD handle
|
||||||
* @param pReadBuffer: Pointer to the buffer that will contain the received data
|
* @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
|
* @param BlockSize: SD card Data block size
|
||||||
* This paramater should be 512.
|
* This paramater should be 512.
|
||||||
* @param NumberOfBlocks: Number of blocks to read.
|
* @param NumberOfBlocks: Number of blocks to read.
|
||||||
* @retval SD Card error state
|
* @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_CmdInitTypeDef sdio_cmdinitstructure;
|
||||||
SDIO_DataInitTypeDef sdio_datainitstructure;
|
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 */
|
/* Enable the DMA Stream */
|
||||||
HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks));
|
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)
|
if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
|
||||||
{
|
{
|
||||||
BlockSize = 512;
|
BlockSize = 512;
|
||||||
ReadAddr /= 512;
|
ReadAddr = BlockNumber;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// should not overflow for standard-capacity cards
|
||||||
|
ReadAddr = BlockNumber * BlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Block Size for Card */
|
/* 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.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdio_cmdinitstructure.Argument = (uint32_t)ReadAddr;
|
sdio_cmdinitstructure.Argument = ReadAddr;
|
||||||
SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
|
SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
|
||||||
|
|
||||||
/* Check for error conditions */
|
/* 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).
|
* to check the completion of the write process (by SD current status polling).
|
||||||
* @param hsd: SD handle
|
* @param hsd: SD handle
|
||||||
* @param pWriteBuffer: pointer to the buffer that will contain the data to transmit
|
* @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
|
* @param BlockSize: the SD card Data block size
|
||||||
* This parameter should be 512.
|
* This parameter should be 512.
|
||||||
* @param NumberOfBlocks: Number of blocks to write
|
* @param NumberOfBlocks: Number of blocks to write
|
||||||
* @retval SD Card error state
|
* @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_CmdInitTypeDef sdio_cmdinitstructure;
|
||||||
SDIO_DataInitTypeDef sdio_datainitstructure;
|
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 */
|
/* Enable SDIO DMA transfer */
|
||||||
__HAL_SD_SDIO_DMA_ENABLE();
|
__HAL_SD_SDIO_DMA_ENABLE();
|
||||||
|
|
||||||
|
uint32_t WriteAddr;
|
||||||
if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
|
if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
|
||||||
{
|
{
|
||||||
BlockSize = 512;
|
BlockSize = 512;
|
||||||
WriteAddr /= 512;
|
WriteAddr = BlockNumber;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// should not overflow for standard-capacity cards
|
||||||
|
WriteAddr = BlockNumber * BlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Block Size for Card */
|
/* 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.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdio_cmdinitstructure.Argument = (uint32_t)WriteAddr;
|
sdio_cmdinitstructure.Argument = WriteAddr;
|
||||||
SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
|
SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
|
||||||
|
|
||||||
/* Check for error conditions */
|
/* Check for error conditions */
|
||||||
|
|
104
stmhal/sdcard.c
104
stmhal/sdcard.c
|
@ -141,54 +141,46 @@ uint64_t sdcard_get_capacity_in_bytes(void) {
|
||||||
return cardinfo.CardCapacity;
|
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
|
// check that dest pointer is aligned on a 4-byte boundary
|
||||||
if (((uint32_t)dest & 3) != 0) {
|
if (((uint32_t)dest & 3) != 0) {
|
||||||
return false;
|
return SD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that SD card is initialised
|
// check that SD card is initialised
|
||||||
if (sd_handle.Instance == NULL) {
|
if (sd_handle.Instance == NULL) {
|
||||||
return false;
|
return SD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We must disable IRQs because the SDIO peripheral has a small FIFO
|
// 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.
|
// 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.
|
// This will not be needed when SD uses DMA for transfer.
|
||||||
__disable_irq();
|
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
|
||||||
HAL_SD_ErrorTypedef err = HAL_SD_ReadBlocks(&sd_handle, (uint32_t*)dest, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, num_blocks);
|
HAL_SD_ErrorTypedef err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
|
||||||
__enable_irq();
|
MICROPY_END_ATOMIC_SECTION(atomic_state);
|
||||||
|
|
||||||
if (err != SD_OK) {
|
return err;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// check that src pointer is aligned on a 4-byte boundary
|
||||||
if (((uint32_t)src & 3) != 0) {
|
if (((uint32_t)src & 3) != 0) {
|
||||||
return false;
|
return SD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that SD card is initialised
|
// check that SD card is initialised
|
||||||
if (sd_handle.Instance == NULL) {
|
if (sd_handle.Instance == NULL) {
|
||||||
return false;
|
return SD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We must disable IRQs because the SDIO peripheral has a small FIFO
|
// 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.
|
// 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.
|
// This will not be needed when SD uses DMA for transfer.
|
||||||
__disable_irq();
|
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
|
||||||
HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks(&sd_handle, (uint32_t*)src, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, num_blocks);
|
HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
|
||||||
__enable_irq();
|
MICROPY_END_ATOMIC_SECTION(atomic_state);
|
||||||
|
|
||||||
if (err != SD_OK) {
|
return err;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#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
|
// 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;
|
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;
|
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) {
|
if (status != SD_OK) {
|
||||||
return false;
|
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
|
// 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());
|
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;
|
bool result;
|
||||||
if (mp_obj_is_true(state)) {
|
if (mp_obj_is_true(state)) {
|
||||||
result = sdcard_power_on();
|
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);
|
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_info(mp_obj_t self) {
|
||||||
|
HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo);
|
||||||
static mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) {
|
if (sd_handle.Instance == NULL) {
|
||||||
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);
|
|
||||||
return mp_const_none;
|
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);
|
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 data) {
|
||||||
|
|
||||||
static mp_obj_t sd_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t source) {
|
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
uint8_t tmp[1];
|
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
||||||
|
|
||||||
pyb_buf_get_for_send(source, &bufinfo, tmp);
|
|
||||||
if (bufinfo.len % SDCARD_BLOCK_SIZE != 0) {
|
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)) {
|
mp_uint_t ret = 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"));
|
|
||||||
|
if (ret != 0) {
|
||||||
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "sdcard_write_blocks failed [%u]", ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mp_const_none;
|
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[] = {
|
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_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_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_read), (mp_obj_t)&sd_read_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&sd_write_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&sd_write_obj },
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,9 @@ bool sdcard_is_present(void);
|
||||||
bool sdcard_power_on(void);
|
bool sdcard_power_on(void);
|
||||||
void sdcard_power_off(void);
|
void sdcard_power_off(void);
|
||||||
uint64_t sdcard_get_capacity_in_bytes(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;
|
extern const struct _mp_obj_base_t pyb_sdcard_obj;
|
||||||
|
|
|
@ -321,7 +321,7 @@ int8_t SDCARD_STORAGE_PreventAllowMediumRemoval(uint8_t lun, uint8_t param) {
|
||||||
* @retval Status
|
* @retval Status
|
||||||
*/
|
*/
|
||||||
int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
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 -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -336,7 +336,7 @@ int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_
|
||||||
* @retval Status
|
* @retval Status
|
||||||
*/
|
*/
|
||||||
int8_t SDCARD_STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
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 -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -83,7 +83,7 @@ typedef struct {
|
||||||
uint16_t scsi_blk_size;
|
uint16_t scsi_blk_size;
|
||||||
uint32_t scsi_blk_nbr;
|
uint32_t scsi_blk_nbr;
|
||||||
|
|
||||||
uint32_t scsi_blk_addr;
|
uint32_t scsi_blk_addr_in_blks;
|
||||||
uint32_t scsi_blk_len;
|
uint32_t scsi_blk_len;
|
||||||
} USBD_MSC_BOT_HandleTypeDef;
|
} USBD_MSC_BOT_HandleTypeDef;
|
||||||
|
|
||||||
|
|
|
@ -510,7 +510,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *para
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hmsc->scsi_blk_addr = (params[2] << 24) | \
|
hmsc->scsi_blk_addr_in_blks = (params[2] << 24) | \
|
||||||
(params[3] << 16) | \
|
(params[3] << 16) | \
|
||||||
(params[4] << 8) | \
|
(params[4] << 8) | \
|
||||||
params[5];
|
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 */
|
return -1; /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
hmsc->bot_state = USBD_BOT_DATA_IN;
|
hmsc->bot_state = USBD_BOT_DATA_IN;
|
||||||
hmsc->scsi_blk_addr *= hmsc->scsi_blk_size;
|
|
||||||
hmsc->scsi_blk_len *= hmsc->scsi_blk_size;
|
hmsc->scsi_blk_len *= hmsc->scsi_blk_size;
|
||||||
|
|
||||||
/* cases 4,5 : Hi <> Dn */
|
/* 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[3] << 16) | \
|
||||||
(params[4] << 8) | \
|
(params[4] << 8) | \
|
||||||
params[5];
|
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 */
|
/* check if LBA address is in the right range */
|
||||||
if(SCSI_CheckAddressRange(pdev,
|
if(SCSI_CheckAddressRange(pdev,
|
||||||
lun,
|
lun,
|
||||||
hmsc->scsi_blk_addr,
|
hmsc->scsi_blk_addr_in_blks,
|
||||||
hmsc->scsi_blk_len) < 0)
|
hmsc->scsi_blk_len) < 0)
|
||||||
{
|
{
|
||||||
return -1; /* error */
|
return -1; /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
hmsc->scsi_blk_addr *= hmsc->scsi_blk_size;
|
|
||||||
hmsc->scsi_blk_len *= hmsc->scsi_blk_size;
|
hmsc->scsi_blk_len *= hmsc->scsi_blk_size;
|
||||||
|
|
||||||
/* cases 3,11,13 : Hn,Ho <> D0 */
|
/* 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*/
|
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,
|
if(SCSI_CheckAddressRange(pdev,
|
||||||
lun,
|
lun,
|
||||||
hmsc->scsi_blk_addr,
|
hmsc->scsi_blk_addr_in_blks,
|
||||||
hmsc->scsi_blk_len) < 0)
|
hmsc->scsi_blk_len) < 0)
|
||||||
{
|
{
|
||||||
return -1; /* error */
|
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 ,
|
if( ((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun ,
|
||||||
hmsc->bot_data,
|
hmsc->bot_data,
|
||||||
hmsc->scsi_blk_addr / hmsc->scsi_blk_size,
|
hmsc->scsi_blk_addr_in_blks,
|
||||||
len / hmsc->scsi_blk_size) < 0)
|
len / hmsc->scsi_blk_size) < 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -723,7 +724,7 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun)
|
||||||
len);
|
len);
|
||||||
|
|
||||||
|
|
||||||
hmsc->scsi_blk_addr += len;
|
hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size;
|
||||||
hmsc->scsi_blk_len -= len;
|
hmsc->scsi_blk_len -= len;
|
||||||
|
|
||||||
/* case 6 : Hi = Di */
|
/* 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 ,
|
if(((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun ,
|
||||||
hmsc->bot_data,
|
hmsc->bot_data,
|
||||||
hmsc->scsi_blk_addr / hmsc->scsi_blk_size,
|
hmsc->scsi_blk_addr_in_blks,
|
||||||
len / hmsc->scsi_blk_size) < 0)
|
len / hmsc->scsi_blk_size) < 0)
|
||||||
{
|
{
|
||||||
SCSI_SenseCode(pdev,
|
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;
|
hmsc->scsi_blk_len -= len;
|
||||||
|
|
||||||
/* case 12 : Ho = Do */
|
/* case 12 : Ho = Do */
|
||||||
|
|
Loading…
Reference in New Issue