Esempio n. 1
0
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 SD_ERROR;
    }

    // check that SD card is initialised
    if (sd_handle.Instance == NULL) {
        return SD_ERROR;
    }

    HAL_SD_ErrorTypedef err = SD_OK;

    if (query_irq() == IRQ_STATE_ENABLED) {
        dma_init(&sd_rx_dma, DMA_STREAM_SDIO_RX, &dma_init_struct_sdio,
            DMA_CHANNEL_SDIO_RX, DMA_PERIPH_TO_MEMORY, &sd_handle);
        sd_handle.hdmarx = &sd_rx_dma;

        err = HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
        if (err == SD_OK) {
            // wait for DMA transfer to finish, with a large timeout
            err = HAL_SD_CheckReadOperation(&sd_handle, 100000000);
        }

        dma_deinit(sd_handle.hdmarx);
        sd_handle.hdmarx = NULL;
    } else {
        err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
    }

    return err;
}
Esempio n. 2
0
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
    // check that SD card is initialised
    if (sd_handle.Instance == NULL) {
        return SD_ERROR;
    }

    HAL_SD_ErrorTypedef err = SD_OK;

    // check that dest pointer is aligned on a 4-byte boundary
    uint8_t *orig_dest = NULL;
    uint32_t saved_word;
    if (((uint32_t)dest & 3) != 0) {
        // Pointer is not aligned so it needs fixing.
        // We could allocate a temporary block of RAM (as sdcard_write_blocks
        // does) but instead we are going to use the dest buffer inplace.  We
        // are going to align the pointer, save the initial word at the aligned
        // location, read into the aligned memory, move the memory back to the
        // unaligned location, then restore the initial bytes at the aligned
        // location.  We should have no trouble doing this as those initial
        // bytes at the aligned location should be able to be changed for the
        // duration of this function call.
        orig_dest = dest;
        dest = (uint8_t*)((uint32_t)dest & ~3);
        saved_word = *(uint32_t*)dest;
    }

    if (query_irq() == IRQ_STATE_ENABLED) {
        // we must disable USB irqs to prevent MSC contention with SD card
        uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);

        dma_init(&sd_rx_dma, &SDMMC_RX_DMA, &sd_handle);
        sd_handle.hdmarx = &sd_rx_dma;

        // make sure cache is flushed and invalidated so when DMA updates the RAM
        // from reading the peripheral the CPU then reads the new data
        MP_HAL_CLEANINVALIDATE_DCACHE(dest, num_blocks * SDCARD_BLOCK_SIZE);

        err = HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
        if (err == SD_OK) {
            // wait for DMA transfer to finish, with a large timeout
            err = HAL_SD_CheckReadOperation(&sd_handle, 100000000);
        }

        dma_deinit(&SDMMC_RX_DMA);
        sd_handle.hdmarx = NULL;

        restore_irq_pri(basepri);
    } else {
        err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
    }

    if (orig_dest != NULL) {
        // move the read data to the non-aligned position, and restore the initial bytes
        memmove(orig_dest, dest, num_blocks * SDCARD_BLOCK_SIZE);
        memcpy(dest, &saved_word, orig_dest - dest);
    }

    return err;
}
Esempio n. 3
0
bool sdcard_read_blocks_dma(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 true;
    }

    // check that SD card is initialised
    if (sd_handle.Instance == NULL) {
        return true;
    }

    // do the read
    if (HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks) != SD_OK) {
        return true;
    }

    // wait for DMA transfer to finish, with a large timeout
    if (HAL_SD_CheckReadOperation(&sd_handle, 100000000) != SD_OK) {
        return true;
    }

    return false;
}