mDMA implements DMA APIs for mbed. It is inspired by modDMA and simpleDMA. Compared with other mbed DMA implementations, mDMA has new features like 1) support LLI 2) support more than 4KB data transfer 3) support vectorized transfer. 4) support burst transfer. 5) Improved memory-memory transfer. It could beat memcpy 6) The library implementation fit the code structure of mbed sdk. Currently only support LPC1768 but could be extended to other platforms.

Dependents:   test_mDMA

dma.cpp

Committer:
steniu01
Date:
2015-03-09
Revision:
1:9421d79fb372
Parent:
0:8e50c5fd42f6

File content as of revision 1:9421d79fb372:

#include "dma.h"

namespace mbed {


DMA::DMA (int priority):
channel_num(_channel_num) 
{
    chan = chooseFreeChannel(priority) ;
//    channel_num = _channel_num;
    DMA_reset(chan);// reset the register value to default and clear the interrupts
    dma_init_struct = DMA_struct_create(); // initialize the dma data structure to default value
}


DMA::~DMA()
{
    DMA_struct_delete(dma_init_struct);
    DMA_IRQ_detach(chan);
}

// if no channel choosed, choose whichever free channel, otherwise, wait until the channel is free
int DMA::chooseFreeChannel (int channel)
{
    int reval=channel;
    if (channel > (channel_num-1) || channel < 0) 
    {
        reval = 0;
        while (1) { //if not chosen channel, round robin checked which channel is free
            if (!DMA_channel_active(reval))
                return reval;
            reval++;
            if (reval>(channel_num-1))
                reval=0;
        }
    } 
    else
    {
        while (DMA_channel_active(reval));//if has chosen the channel, wait until the channel is free
    }
    
    return reval;
}

void DMA::TriggerSource(TriggerType trig)
{
    DMA_trigger_source(dma_init_struct, trig);
}

void DMA::TriggerDestination(TriggerType trig)
{
    DMA_trigger_destination(dma_init_struct, trig);
}

/*
void DMA::next(LLI* list)
{
        DMA_next(dma_init_struct, list);
}
*/

void DMA::next(const uint32_t src, const uint32_t dst, uint32_t size)
{
    DMA_next(dma_init_struct, src, dst, size);
}

void DMA::start (unsigned int len)
{
    DMA_init(chan,dma_init_struct);
    DMA_start(chan, dma_init_struct, len);
}

void DMA::wait()
{
    while (DMA_channel_active(chan));
}

bool DMA::finished()
{
    return !DMA_channel_active(chan);
}
}