GPDMA (Direct Memory Access) and LLI (Link List Item) test see: http://mbed.org/users/okini3939/notebook/dma_jp/

Dependencies:   mbed

main.cpp

Committer:
okini3939
Date:
2013-09-13
Revision:
1:1a77fa863282
Parent:
0:de79d4a48e63

File content as of revision 1:1a77fa863282:

#include "mbed.h"
#include "MODDMA.h"

#define LLI_NUM 5

Serial pc(USBTX, USBRX);
DigitalOut myled(LED1), errled(LED4);

MODDMA dma;
MODDMA_Config *dmacfg;
MODDMA_LLI *lli[LLI_NUM];
MODDMA::GPDMA_CONNECTION dmacon;
volatile int dmacount = 0;
char dmadata[LLI_NUM][40];
char text[] = "* count, dmadata[*] abcdefg\r\n";

void tc_callback () {
    int i;
    MODDMA_Config *config = dma.getConfig();

    myled = ! myled;

    for (i = 0; i < LLI_NUM; i ++) {
        dmadata[i][0] = '0' + dmacount;
    }

    dmacount ++;
    if (dmacount > 10) {
        lli[LLI_NUM - 1]->Control = NULL;
    }

    // Clear DMA IRQ flags.
    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();    
    if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();    
}

void err_callback () {
    MODDMA_Config *config = dma.getConfig();

    errled = 1;
    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
}


int main() {
    int i, len;

    pc.printf("MODDMA LLI test\r\n");

    dmacfg = new MODDMA_Config;
    dmacon = MODDMA::UART0_Tx;

    len = strlen(text);
    for (i = 0; i < LLI_NUM; i ++) {
        strcpy(dmadata[i], text);
        dmadata[i][17] = '0' + i;

        lli[i] = new MODDMA_LLI;
    }

    dmacfg
     ->channelNum    ( MODDMA::Channel_0 )
     ->srcMemAddr    ( (uint32_t)dmadata[0] )
     ->dstConn       ( dmacon )
     ->transferSize  ( len )
     ->transferType  ( MODDMA::m2p )
     ->dmaLLI        ( (uint32_t)lli[1] )
     ->attach_tc     ( tc_callback )
     ->attach_err    ( err_callback )
    ; // config end
    lli[0]->SrcAddr = (uint32_t)dmadata[0];
    lli[0]->DstAddr = (uint32_t)dma.LUTPerAddr(dmacon);
    lli[0]->NextLLI = (uint32_t)lli[1];
    lli[0]->Control = dma.CxControl_TransferSize((uint32_t)len) 
                | dma.CxControl_SBSize((uint32_t)dma.LUTPerBurst(dmacon)) 
                | dma.CxControl_DBSize((uint32_t)dma.LUTPerBurst(dmacon)) 
                | dma.CxControl_SWidth((uint32_t)dma.LUTPerWid(dmacon)) 
                | dma.CxControl_DWidth((uint32_t)dma.LUTPerWid(dmacon)) 
                | dma.CxControl_SI() 
                | dma.CxControl_I();
    for (i = 1; i < LLI_NUM; i ++) {
        lli[i]->SrcAddr = (uint32_t)dmadata[i];
        lli[i]->DstAddr = lli[0]->DstAddr;
        lli[i]->NextLLI = (uint32_t)lli[i < LLI_NUM - 1 ? i + 1 : 0];
        lli[i]->Control = lli[0]->Control;
    }

    if (dma.Setup( dmacfg )) {
//        _ssp->FCR = (1<<3); // DMA Mode
        dma.Enable( dmacfg );
    }

    wait(3);
    pc.printf("end\r\n");

    return 0;
}