sources/common/libs/STM32Cube_F4/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_mmc.c
/**
  * @brief  Reads block(s) from a specified address in a card. The Data transfer
  *         is managed by DMA mode.
  * @note   This API should be followed by a check on the card state through
  *         HAL_MMC_GetCardState().
  * @note   You could also check the DMA transfer process through the MMC Rx
  *         interrupt event.
  * @param  hmmc: Pointer MMC handle
  * @param  pData: Pointer to the buffer that will contain the received data
  * @param  BlockAdd: Block Address from where data is to be read
  * @param  NumberOfBlocks: Number of blocks to read.
  * @retval HAL status
  */
@brief  Reads block(s) from a specified address in a card. The Data transfer
is managed by DMA mode.
@note   This API should be followed by a check on the card state through
HAL_MMC_GetCardState().
@note   You could also check the DMA transfer process through the MMC Rx
interrupt event.
@param  hmmc: Pointer MMC handle
@param  pData: Pointer to the buffer that will contain the received data
@param  BlockAdd: Block Address from where data is to be read
@param  NumberOfBlocks: Number of blocks to read.
@retval HAL status
@brief Reads block ( s ) from a specified address in a card . The Data transfer is managed by DMA mode . @note This API should be followed by a check on the card state through HAL_MMC_GetCardState () . @note You could also check the DMA transfer process through the MMC Rx interrupt event . @param hmmc : Pointer MMC handle @param pData : Pointer to the buffer that will contain the received data @param BlockAdd : Block Address from where data is to be read @param NumberOfBlocks : Number of blocks to read . @retval HAL status
HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
{
  SDIO_DataInitTypeDef config;
  uint32_t errorstate;
  uint32_t add = BlockAdd;
  if(NULL == pData)
  {
    hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
    return HAL_ERROR;
  }
  if(hmmc->State == HAL_MMC_STATE_READY)
  {
    hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
    if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
    {
      hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
      return HAL_ERROR;
    }
    hmmc->State = HAL_MMC_STATE_BUSY;
    hmmc->Instance->DCTRL = 0U;
#if defined(SDIO_STA_STBITERR)
    __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
#else 
    __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
#endif 
    hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
    hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
    hmmc->hdmarx->XferAbortCallback = NULL;
    if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
    {
      add *= 512U;
    }
    hmmc->hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY;
    MODIFY_REG(hmmc->hdmarx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmarx->Init.Direction);
    if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
    {
      __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
      __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
      hmmc->ErrorCode = HAL_MMC_ERROR_DMA;
      hmmc->State = HAL_MMC_STATE_READY;
      return HAL_ERROR;
    }
    else
    {
      __HAL_MMC_DMA_ENABLE(hmmc);
      config.DataTimeOut   = SDMMC_DATATIMEOUT;
      config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
      config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
      config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
      config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
      config.DPSM          = SDIO_DPSM_ENABLE;
      (void)SDIO_ConfigData(hmmc->Instance, &config);
      if(NumberOfBlocks > 1U)
      {
        hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
        errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
      }
      else
      {
        hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
        errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
      }
      if(errorstate != HAL_MMC_ERROR_NONE)
      {
        __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 
        __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
        hmmc->ErrorCode = errorstate;
        hmmc->State = HAL_MMC_STATE_READY;
        return HAL_ERROR;
      }
      return HAL_OK;
    }
  }
  else
  {
    return HAL_BUSY;
  }
}
HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA ( MMC_HandleTypeDef * hmmc , uint8_t * pData , uint32_t BlockAdd , uint32_t NumberOfBlocks ) { SDIO_DataInitTypeDef config ; uint32_t errorstate ; uint32_t add = BlockAdd ; if ( NULL == pData ) { hmmc -> ErrorCode |= HAL_MMC_ERROR_PARAM ; return HAL_ERROR ; } if ( hmmc -> State == HAL_MMC_STATE_READY ) { hmmc -> ErrorCode = HAL_MMC_ERROR_NONE ; if ( ( BlockAdd + NumberOfBlocks ) > ( hmmc -> MmcCard . LogBlockNbr ) ) { hmmc -> ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE ; return HAL_ERROR ; } hmmc -> State = HAL_MMC_STATE_BUSY ; hmmc -> Instance -> DCTRL = 0U ; #if defined ( SDIO_STA_STBITERR ) __HAL_MMC_ENABLE_IT ( hmmc , ( SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR ) ) ; #else __HAL_MMC_ENABLE_IT ( hmmc , ( SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND ) ) ; #endif hmmc -> hdmarx -> XferCpltCallback = MMC_DMAReceiveCplt ; hmmc -> hdmarx -> XferErrorCallback = MMC_DMAError ; hmmc -> hdmarx -> XferAbortCallback = NULL ; if ( ( hmmc -> MmcCard . CardType ) != MMC_HIGH_CAPACITY_CARD ) { add *= 512U ; } hmmc -> hdmarx -> Init . Direction = DMA_PERIPH_TO_MEMORY ; MODIFY_REG ( hmmc -> hdmarx -> Instance -> CR , DMA_SxCR_DIR , hmmc -> hdmarx -> Init . Direction ) ; if ( HAL_DMA_Start_IT ( hmmc -> hdmarx , ( uint32_t ) & hmmc -> Instance -> FIFO , ( uint32_t ) pData , ( uint32_t ) ( MMC_BLOCKSIZE * NumberOfBlocks ) / 4 ) != HAL_OK ) { __HAL_MMC_DISABLE_IT ( hmmc , ( SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND ) ) ; __HAL_MMC_CLEAR_FLAG ( hmmc , SDIO_STATIC_FLAGS ) ; hmmc -> ErrorCode = HAL_MMC_ERROR_DMA ; hmmc -> State = HAL_MMC_STATE_READY ; return HAL_ERROR ; } else { __HAL_MMC_DMA_ENABLE ( hmmc ) ; config . DataTimeOut = SDMMC_DATATIMEOUT ; config . DataLength = MMC_BLOCKSIZE * NumberOfBlocks ; config . DataBlockSize = SDIO_DATABLOCK_SIZE_512B ; config . TransferDir = SDIO_TRANSFER_DIR_TO_SDIO ; config . TransferMode = SDIO_TRANSFER_MODE_BLOCK ; config . DPSM = SDIO_DPSM_ENABLE ; ( void ) SDIO_ConfigData ( hmmc -> Instance , & config ) ; if ( NumberOfBlocks > 1U ) { hmmc -> Context = ( MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA ) ; errorstate = SDMMC_CmdReadMultiBlock ( hmmc -> Instance , add ) ; } else { hmmc -> Context = ( MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA ) ; errorstate = SDMMC_CmdReadSingleBlock ( hmmc -> Instance , add ) ; } if ( errorstate != HAL_MMC_ERROR_NONE ) { __HAL_MMC_CLEAR_FLAG ( hmmc , SDIO_STATIC_FLAGS ) ; __HAL_MMC_DISABLE_IT ( hmmc , ( SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND ) ) ; hmmc -> ErrorCode = errorstate ; hmmc -> State = HAL_MMC_STATE_READY ; return HAL_ERROR ; } return HAL_OK ; } } else { return HAL_BUSY ; } }
@brief  Reads block(s) from a specified address in a card.
@brief Reads block ( s ) from a specified address in a card .
/* Initialize data control register */ /* SDIO_STA_STBITERR not defined */ /* SDIO_STA_STBITERR */ /* Set the DMA transfer complete callback */ /* Set the DMA error callback */ /* Set the DMA Abort callback */ /* Force DMA Direction */ /* Enable the DMA Channel */ /* Enable MMC DMA transfer */ /* Configure the MMC DPSM (Data Path State Machine) */ /* Read Blocks in DMA mode */ /* Read Multi Block command */ /* Read Single Block command */ /* Clear all the static flags */