GPDMA (Direct Memory Access) and LLI (Link List Item) test see: http://mbed.org/users/okini3939/notebook/dma_jp/
Diff: main.cpp
- Revision:
- 0:de79d4a48e63
- Child:
- 1:1a77fa863282
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Sep 13 14:49:52 2013 +0000 @@ -0,0 +1,98 @@ +#include "mbed.h" +#include "MODDMA.h" + +#define LLI_NUM 4 + +Serial pc(USBTX, USBRX); +DigitalOut myled(LED1); + +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(); + + for (i = 0; i < LLI_NUM; i ++) { + dmadata[i][0] = '0' + dmacount; + } + dmacount ++; + if (dmacount >= 10) { + dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); + } +/* + i = (dmacount & 1) ? 0 : 1; + if (dmacount < 5) { + dmadata[0][0] = '0' + dmacount; + dmadata[1][0] = '0' + dmacount; + } else { + dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); + } +*/ + // Clear DMA IRQ flags. + if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); + if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); +} + +void err_callback () { +} + + +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; +}