[SOLVED] DMA Burst mode -> DAC

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

[SOLVED] DMA Burst mode -> DAC

1,072 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Auslander on Wed Nov 20 04:24:47 MST 2013
I'm trying to run code from Application Note AN10917 on LPC4357 without any sucess. I'm wondering what i'm doing wrong.
int main (void)                                    // Main Program
{
    int i;

    SystemInit();

    for(i=0; i < WAVE_SAMPLE_NUM; i++)
        sinusoide = 512*sin(2*PI*i/WAVE_SAMPLE_NUM);

    for(i=0; i < WAVE_SAMPLE_NUM; i++)
        sinusoide = ((sinusoide + 512) << 6)// DACR bit 6-15, VALUE
             | 1 << 16;// DACR bit 16, BIAS = 1

    LPC_SCU->SFSP4_4 = 0;   //GIPO; EPD, EPUN, EZI morajo biti 0!
    LPC_GPIO_PORT->DIR[2] &=~ (1 << 4);    //P4_4 kot input
    LPC_SCU->ENAIO2 |= 1;   /*Enable analog function DAC on pin P4_4*/

    LLI0.source      = (uint32_t) &sinusoide[0];
    LLI0.destination = (uint32_t) &(LPC_DAC->CR);
    LLI0.next        = (uint32_t) &LLI0;
    LLI0.control     = 1<<26 | 2<<21 | 2<<18 | WAVE_SAMPLE_NUM;

    LPC_GPDMA->CONFIG = 1;                  // enable the GPDMA controller
    LPC_GPDMA->SYNC   = 
(0<<15);        // enable synchro

    LPC_GPDMA->C0SRCADDR  = (uint32_t) &sinusoide[0];
    LPC_GPDMA->C0DESTADDR = (uint32_t) &(LPC_DAC->CR);
    LPC_GPDMA->C0LLI      = (uint32_t) &LLI0; // linked lists for ch0
    LPC_GPDMA->C0CONTROL  = WAVE_SAMPLE_NUM   // transfer size (0 - 11) = 64
                            | (0 << 12)            // source burst size (12 - 14) = 1
                            | (0 << 15)            // destination burst size (15 - 17) = 1
                            | (2 << 18)            // source width (18 - 20) = 32 bit
                            | (2 << 21)            // destination width (21 - 23) = 32 bit
                            | (0 << 24)            // source AHB select (24) = AHB 0
                            | (0 << 25)            // destination AHB select (25) = AHB 0
                            | (1 << 26)            // source increment (26) = increment
                            | (0 << 27)            // destination increment (27) = no increment
                            | (0 << 28)            // mode select (28) = access in user mode
                            | (0 << 29)            // (29) = access not bufferable
                            | (0 << 30)            // (30) = access not cacheable
                            | (0 << 31);           // terminal count interrupt disabled

    LPC_GPDMA->C0CONFIG   =  1   // channel enabled (0)
                            | (0 << 1) // source peripheral (1 - 5) = none
                            | (0x0F << 6)// destination peripheral (6 - 10) = DAC
                            | (1 << 11)// flow control (11 - 13) = mem to per
                            | (0 << 14)// (14) = mask out error interrupt
                            | (0 << 15)// (15) = mask out terminal count interrupt
                            | (0 << 16)// (16) = no locked transfers
                            | (0 << 18);// (27) = no HALT

/* DACclk = 25 MHz, so 10 usec interval*/
    LPC_DAC->CNTVAL = 250;
/* DMA, timer running, dbuff */
    LPC_DAC->CTRL   = 1<<3 | 1<<2 | 1<<1;           


    while(1) ;                                      // Loop forever
}


Did I missed something?
标签 (1)
0 项奖励
回复
3 回复数

835 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pacman on Thu Nov 21 04:55:30 MST 2013
Yes, it's easy to overlook, but the manual is large too (and I'm very happy that it is). It's great that you got the problem solved. :)

The section I learned it from was Table 346 on page 506 under "bit 25":

Quote:
Destination AHB master select:
Remark: Only Master1 can access a peripheral. [color=#900]Master0 can
only access memory[/color].



Here are a few other places it's mentioned:
Section 20.3 (page 491)...

Quote:
[list]  [*]Two AHB bus masters for transferring data. These interfaces transfer data when a DMA request goes active. Master 1 can access memories and peripherals, master 0 can access memories and the SGPIO only.[/list]



Section 20.4 (page 492)...

Quote:
...The source and destination areas can each be either a memory region or a peripheral for master 1. Master 0 can only access memory.



Section 20.8.2 (page 516)...

Quote:
[list]  [*]Memory-to-peripheral (master 1 only).
  [*]Peripheral-to-memory (master 1 only).
  [*]Memory-to-memory.
  [*]Peripheral-to-peripheral (master 1 only).
[/list]



[color=#060]Have in mind, that choosing the right combination of AHB Master 0 and AHB Master 1 may improve performance significantly.[/color]

Make sure you read the "Remark" under the "Enable" bit in table 347 (page 507) as well.

(also, please see one of my earlier posts)
0 项奖励
回复

835 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Auslander on Thu Nov 21 03:11:27 MST 2013
tnx, your tip was very helpful

When i selected AHB Master1 in LPC_GPDMA->C0CONTROL |= (1 << 25), it began to work.

I really don't know how i didn't see that in user manual...
Thanks again
0 项奖励
回复

835 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pacman on Wed Nov 20 13:21:29 MST 2013

Quote: Auslander
    LPC_GPDMA->SYNC   = (0<<15);        // enable synchro



Although that's not the problem, I recommend replacing it by....
    LPC_GPDMA->SYNC &= ~(1<<15);        // enable synchro



Quote: Auslander
    LPC_GPDMA->C0CONTROL  = WAVE_SAMPLE_NUM   // transfer size (0 - 11) = 64
                            | (0 << 12)            // source burst size (12 - 14) = 1
                            | (0 << 15)            // destination burst size (15 - 17) = 1
                            | (2 << 18)            // source width (18 - 20) = 32 bit
                            | (2 << 21)            // destination width (21 - 23) = 32 bit
                            | (0 << 24)            // source AHB select (24) = AHB 0
                            | (0 << 25)            // destination AHB select (25) = AHB 0
                            | (1 << 26)            // source increment (26) = increment
                            | (0 << 27)            // destination increment (27) = no increment
                            | (0 << 28)            // mode select (28) = access in user mode
                            | (0 << 29)            // (29) = access not bufferable
                            | (0 << 30)            // (30) = access not cacheable
                            | (0 << 31);           // terminal count interrupt disabled

Did I missed something?



I believe you should try changing destination to use AHB Master 1.
You cannot (as far is I experienced and have read in the manual) write to peripheral using AHB Master 0.
0 项奖励
回复