Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src
Fork of DMSupport by
Diff: FileSystems/MCIFileSystem.cpp
- Revision:
- 38:420cdc281467
- Parent:
- 31:d47cffcb0a3e
- Child:
- 40:6df4f63aa406
--- a/FileSystems/MCIFileSystem.cpp Mon Mar 23 13:45:16 2015 +0000
+++ b/FileSystems/MCIFileSystem.cpp Wed Apr 15 09:41:56 2015 +0200
@@ -23,7 +23,6 @@
#include "rtos.h"
#include "diskio.h" //STA_* defines
-#include "gpdma.h"
/******************************************************************************
* Defines and typedefs
@@ -642,9 +641,6 @@
LPC_SC->RSTCON0 = (1<<28);
LPC_SC->RSTCON0 &= ~(1<<28);
- /* Initialize GPDMA controller */
- gpdma_init();
-
/* Initialize SDC peripheral */
LPC_SC->PCONP |= SYSCTL_CLOCK_SDC;
@@ -685,8 +681,8 @@
NVIC_SetVector(MCI_IRQn, (uint32_t) mymciirq);
NVIC_EnableIRQ(MCI_IRQn);
- NVIC_SetVector(DMA_IRQn, (uint32_t) mydmairq);
- NVIC_EnableIRQ(DMA_IRQn);
+ /* Initialize GPDMA controller */
+ _eventDmaChannel = GPDMA::instance().acquireChannel(mydmairq);
}
int MCIFileSystem::disk_initialize() {
@@ -788,15 +784,72 @@
void MCIFileSystem::mci_DMAIRQHandler()
{
- _eventSuccess = gpdma_interrupt(_eventDmaChannel);
+ _eventSuccess = LPC_GPDMA->IntTCStat & (1<<_eventDmaChannel);
_eventReceived = true;
- NVIC_DisableIRQ(DMA_IRQn);
+ LPC_GPDMA->IntTCClear = (1<<_eventDmaChannel);
+ LPC_GPDMA->IntErrClr = (1<<_eventDmaChannel);
}
/******************************************************************************
* Private Functions
*****************************************************************************/
+static bool gpdma_transfer_to_mci(GPDMA::DMAChannels ChannelNum,
+ uint32_t src,
+ uint32_t Size)
+{
+ GPDMA::GPDMA_Channel_CFG_T cfg;
+ cfg.ChannelNum = ChannelNum;
+ cfg.TransferType = GPDMA::FlowControl_M2P_Ctrl_Periph;
+ cfg.TransferSize = Size;
+ cfg.TransferWidth = 0;
+ cfg.SrcAddr = src;
+ cfg.DstAddr = (uint32_t) (&LPC_MCI->FIFO);
+
+ uint32_t ctrl_word =
+ GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize)
+ | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8)
+ | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8)
+ | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)
+ | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)
+ | GPDMA_DMACCxControl_DestTransUseAHBMaster1
+ | GPDMA_DMACCxControl_SI
+ | GPDMA_DMACCxControl_I;
+
+ /* Select SD card interface in the DMA MUX*/
+ LPC_SC->DMAREQSEL &= ~(1 << 1);
+
+ return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_MEMORY, GPDMA_CONN_SDC);
+}
+
+static bool gpdma_transfer_from_mci(GPDMA::DMAChannels ChannelNum,
+ uint32_t dst,
+ uint32_t Size)
+{
+ GPDMA::GPDMA_Channel_CFG_T cfg;
+ cfg.ChannelNum = ChannelNum;
+ cfg.TransferType = GPDMA::FlowControl_P2M_Ctrl_Periph;
+ cfg.TransferSize = Size;
+ cfg.TransferWidth = 0;
+ cfg.SrcAddr = (uint32_t) (&LPC_MCI->FIFO);
+ cfg.DstAddr = dst;
+
+ uint32_t ctrl_word =
+ GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize)
+ | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8)
+ | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8)
+ | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)
+ | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)
+ | GPDMA_DMACCxControl_SrcTransUseAHBMaster1
+ | GPDMA_DMACCxControl_DI
+ | GPDMA_DMACCxControl_I;
+
+ /* Select SD card interface in the DMA MUX*/
+ LPC_SC->DMAREQSEL &= ~(1 << 1);
+
+ return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_SDC, GPDMA_CONN_MEMORY);
+}
+
bool MCIFileSystem::cardInserted() const
{
// If no card detect pin is given, then assume that a card is inserted.
@@ -968,7 +1021,6 @@
MCIFileSystem::ReturnCode MCIFileSystem::mci_ReadBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
{
ReturnCode Ret = SDC_RET_FAILED;
- uint8_t dmaChannel;
int32_t ByteNum = blockNum * MMC_SECTOR_SIZE;
do
@@ -988,9 +1040,8 @@
LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_RXDATAERR;
/* DMA Setup */
- gpdma_getFreeChannel(&dmaChannel);
- gpdma_transfer_from_mci(dmaChannel, (uint32_t)buffer, ByteNum);
- mci_SetupEventWakeup(dmaChannel);
+ mci_SetupEventWakeup();
+ gpdma_transfer_from_mci(_eventDmaChannel, (uint32_t)buffer, ByteNum);
/* set transfer information */
mci_SetDataTransfer(blockNum, true, DATA_TIMER_VALUE_R);
@@ -1005,7 +1056,7 @@
Ret = SDC_RET_FAILED;
}
- gpdma_stop(dmaChannel);
+ GPDMA::instance().stopTransfer(_eventDmaChannel);
if ((blockNum > 1) || (mci_GetCardState() == SDMMC_DATA_ST)) {
/* Send Stop transmission command */
@@ -1023,7 +1074,6 @@
MCIFileSystem::ReturnCode MCIFileSystem::mci_WriteBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
{
ReturnCode Ret = SDC_RET_FAILED;
- uint8_t dmaChannel;
do
{
@@ -1050,9 +1100,8 @@
LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_TXDATAERR;
/* DMA Setup */
- gpdma_getFreeChannel(&dmaChannel);
- gpdma_transfer_to_mci(dmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE);
- mci_SetupEventWakeup(dmaChannel);
+ mci_SetupEventWakeup();
+ gpdma_transfer_to_mci(_eventDmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE);
/* set transfer information */
mci_SetDataTransfer(blockNum, false, DATA_TIMER_VALUE_W);
@@ -1061,7 +1110,6 @@
if (mci_WaitForEvent() != 0) {
Ret = SDC_RET_FAILED;
}
- gpdma_stop(dmaChannel);
if ((blockNum > 1) || (mci_GetCardState() == SDMMC_RCV_ST)) {
/* Send Stop transmission command */
@@ -1728,16 +1776,12 @@
}
}
-void MCIFileSystem::mci_SetupEventWakeup(uint8_t dmaChannel)
+void MCIFileSystem::mci_SetupEventWakeup()
{
/* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
- NVIC_ClearPendingIRQ(DMA_IRQn);
- _eventDmaChannel = dmaChannel;
_eventReceived = false;
_eventSuccess = false;
-
- NVIC_EnableIRQ(DMA_IRQn);
}
uint32_t MCIFileSystem::mci_WaitForEvent() const
