예제 #1
0
파일: sdc_lld.c 프로젝트: Kreyl/nute
 */
bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
                            uint8_t *buf, uint32_t n) {
  uint32_t resp[1];

  chDbgCheck((n < (0x1000000 / MMCSD_BLOCK_SIZE)), "max transaction size");

  //SDIO->DTIMER = STM32_SDC_READ_TIMEOUT;
  SDIO->DTIMER = 0xFFFFFFFF;    // KL

  /* Checks for errors and waits for the card to be ready for reading.*/
  if (_sdc_wait_for_transfer_state(sdcp))
    return CH_FAILED;

  /* Prepares the DMA channel for writing.*/
  dmaStreamSetMemory0(sdcp->dma, buf);
  dmaStreamSetTransactionSize(sdcp->dma,
                              (n * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
  dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
  dmaStreamEnable(sdcp->dma);

  /* Setting up data transfer.*/
  SDIO->ICR   = STM32_SDIO_ICR_ALL_FLAGS;
  SDIO->MASK  = SDIO_MASK_DCRCFAILIE |
                SDIO_MASK_DTIMEOUTIE |
                SDIO_MASK_STBITERRIE |
                SDIO_MASK_RXOVERRIE |
                SDIO_MASK_DATAENDIE;
  SDIO->DLEN  = n * MMCSD_BLOCK_SIZE;

  /* Talk to card what we want from it.*/
  if (sdc_lld_prepare_read(sdcp, startblk, n, resp) == TRUE)
    goto error;

  /* Transaction starts just after DTEN bit setting.*/
  SDIO->DCTRL = SDIO_DCTRL_DTDIR |
                SDIO_DCTRL_DBLOCKSIZE_3 |
                SDIO_DCTRL_DBLOCKSIZE_0 |
                SDIO_DCTRL_DMAEN |
                SDIO_DCTRL_DTEN;
  if (sdc_lld_wait_transaction_end(sdcp, n, resp) == TRUE)
    goto error;

  return CH_SUCCESS;

error:
  sdc_lld_error_cleanup(sdcp, n, resp);
  return CH_FAILED;
예제 #2
0
/**
 * @brief   Reads one or more blocks.
 *
 * @param[in] sdcp      pointer to the @p SDCDriver object
 * @param[in] startblk  first block to read
 * @param[out] buf      pointer to the read buffer
 * @param[in] blocks    number of blocks to read
 *
 * @return              The operation status.
 * @retval HAL_SUCCESS  operation succeeded.
 * @retval HAL_FAILED   operation failed.
 *
 * @notapi
 */
bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
                          uint8_t *buf, uint32_t blocks) {
    uint32_t resp[1];

    osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);

    sdcp->sdio->DTIMER = STM32_SDC_READ_TIMEOUT;

    /* Checks for errors and waits for the card to be ready for reading.*/
    if (_sdc_wait_for_transfer_state(sdcp))
        return HAL_FAILED;

    /* Prepares the DMA channel for writing.*/
    dmaStreamSetMemory0(sdcp->dma, buf);
    dmaStreamSetTransactionSize(sdcp->dma,
                                (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
    dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
    dmaStreamEnable(sdcp->dma);

    /* Setting up data transfer.*/
    sdcp->sdio->ICR   = STM32_SDIO_ICR_ALL_FLAGS;
    sdcp->sdio->MASK  = SDIO_MASK_DCRCFAILIE |
                        SDIO_MASK_DTIMEOUTIE |
                        SDIO_MASK_STBITERRIE |
                        SDIO_MASK_RXOVERRIE |
                        SDIO_MASK_DATAENDIE;
    sdcp->sdio->DLEN  = blocks * MMCSD_BLOCK_SIZE;

    /* Transaction starts just after DTEN bit setting.*/
    sdcp->sdio->DCTRL = SDIO_DCTRL_DTDIR |
                        SDIO_DCTRL_DBLOCKSIZE_3 |
                        SDIO_DCTRL_DBLOCKSIZE_0 |
                        SDIO_DCTRL_DMAEN |
                        SDIO_DCTRL_DTEN;

    if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == TRUE)
        goto error;

    if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == TRUE)
        goto error;

    return HAL_SUCCESS;

error:
    sdc_lld_error_cleanup(sdcp, blocks, resp);
    return HAL_FAILED;
}