cancel
Showing results for 
Search instead for 
Did you mean: 

eDMA with SPC560B

dominik2
Associate II
Posted on November 30, 2015 at 16:05

Hi all,

I try to get the eDMA Modul working. My starting point is an example code from

the document ''Qorivva Simple Cookbook “Hello World�? Programs to Exercise Common Features on MPC5500 & MPC5600 Microcontrollers'' which can be found on the freescale homepage.

Their example is as follows:

/* main.c - DMA-Block Move example */

/* Rev 0.1 Sept 30, 2004 S.Mihalik, Copyright Freescale, 2004. All Rights Reserved */

/* Rev 1.0 Jul 10 2007 SM - Changed from TCD18 to TCD0 to be MPC5510 compatible */

/* Notes: */

/* 1. MMU not initialized; must be done by debug scripts or BAM */

/* 2. L2SRAM not initialized; must be done by debug scripts */

#include ''mpc563m.h'' /* Use proper include file such as mpc5510.h or mpc5554.h */

const uint8_t SourceData[] = {''Hello World\r''}; /* Source data string */

uint8_t Destination = 0; /* Destination byte */

void initTCD0(void) {

EDMA.TCD[0].SADDR = (vuint32_t) &SourceData; /* Load address of source data */

EDMA.TCD[0].SSIZE = 0; /* Read 2**0 = 1 byte per transfer */

EDMA.TCD[0].SOFF = 1; /* After transfer, add 1 to src addr*/

EDMA.TCD[0].SLAST = -12; /* After major loop, reset src addr*/

EDMA.TCD[0].SMOD = 0; /* Source modulo feature not used */

EDMA.TCD[0].DADDR = (vuint32_t) &Destination; /* Load address of destination */

EDMA.TCD[0].DSIZE = 0; /* Write 2**0 = 1 byte per transfer */

EDMA.TCD[0].DOFF = 0; /* Do not increment destination addr*/

EDMA.TCD[0].DLAST_SGA = 0; /* After major loop, no dest addr change*/

EDMA.TCD[0].DMOD = 0; /* Destination modulo feature not used */

EDMA.TCD[0].NBYTES = 1; /* Transfer 1 byte per minor loop */

EDMA.TCD[0].BITER = 12; /* 12 minor loop iterations */

EDMA.TCD[0].CITER = 12; /* Initialize current iteraction count */

EDMA.TCD[0].D_REQ = 1; /* Disable channel when major loop is done*/

EDMA.TCD[0].INT_HALF = 0; /* Interrupts are not used */

EDMA.TCD[0].INT_MAJ = 0;

EDMA.TCD[0].CITERE_LINK = 0; /* Linking is not used */

EDMA.TCD[0].BITERE_LINK = 0;

EDMA.TCD[0].MAJORE_LINK = 0; /* Dynamic program is not used */

EDMA.TCD[0].E_SG = 0;

EDMA.TCD[0].BWC = 0; /* Default bandwidth control- no stalls */

EDMA.TCD[0].START = 0; /* Initialize status flags */

EDMA.TCD[0].DONE = 0;

EDMA.TCD[0].ACTIVE = 0;

}

void main (void) {

int i = 0; /* Dummy idle counter */

initTCD0(); /* Initialize DMA Transfer Control Descriptor 0 */

EDMA.CR.R = 0x0000E400; /* Use fixed priority arbitration for DMA groups and channels */

EDMA.CPR[0].R = 0x12; /* Channel 0 priorites: group priority = 1, channel priority = 2 */

EDMA.SERQR.R = 0; /* Enable EDMA channel 0 */

EDMA.SSBR.R = 0; /* Set channel 0 START bit to initiate first minor loop transfer */

/* Initate DMA service using software */

while (EDMA.TCD[0].CITER != 1) { /* while not on last minor loop */

/* wait for START=0 and ACTIVE=0 */

while ((EDMA.TCD[0].START == 1) | (EDMA.TCD[0].ACTIVE == 1)) {}

EDMA.SSBR.R = 0; /* Set channel 0 START bit again for next minor loop transfer */

}

while (1) { i++; } /* Loop forever */

}

I adapted it a little bit so that it is at least running.

Now I have the problem, that I always get a source bus error. Are there steps, which have to be done before. Specially I have in mind the points:

1. MMU not initialized; must be done by debug scripts or BAM

2. L2SRAM not initialized; must be done by debug scripts

Is there an example application for the spc and how do I get it? I have looked in the SPC5Studio but didn't found anything.

Thanks for any help

kind regards,

Dominik

This discussion has been locked for participation. If you have a question, please start a new topic in order to ask your question
2 REPLIES 2
dominik2
Associate II
Posted on November 30, 2015 at 16:49

Hi all,

I got it to work.

I changed the function ''void initTCD0(void)'' to

void initTCD0(void) {

  EDMA.TCD[0].SADDR = (vuint32_t) &SourceData;  /* Load address of source data */

  EDMA.TCD[0].SSIZE = 0;                        /* Read 2**0 = 1 byte per transfer */

  EDMA.TCD[0].SOFF = 1;                         /* After transfer, add 1 to src addr*/

  EDMA.TCD[0].SLAST = -12;                      /* After major loop, reset src addr*/

  EDMA.TCD[0].SMOD = 0;                         /* Source modulo feature not used */

  EDMA.TCD[0].DADDR = (vuint32_t) &Destination; /* Load address of destination */

  EDMA.TCD[0].DSIZE = 0;                        /* Write 2**0 = 1 byte per transfer */

  EDMA.TCD[0].DOFF = 0;                         /* Do not increment destination addr*/

  EDMA.TCD[0].DLAST_SGA = 0;                    /* After major loop, no dest addr change*/

  EDMA.TCD[0].DMOD = 0;                         /* Destination modulo feature not used */

  EDMA.TCD[0].NBYTESu.R = 1;                    /* Transfer 1 byte per minor loop */

  EDMA.TCD[0].BITER = 12;                       /* 12 minor loop iterations */

  EDMA.TCD[0].CITER = 12;                       /* Initialize current iteraction count */

  EDMA.TCD[0].D_REQ = 1;                        /* Disable channel when major loop is done*/

  EDMA.TCD[0].INT_HALF = 0;                     /* Interrupts are not used */

  EDMA.TCD[0].INT_MAJ = 0;

  EDMA.TCD[0].CITERE_LINK = 0;                  /* Linking is not used */

  EDMA.TCD[0].BITERE_LINK = 0;

  EDMA.TCD[0].MAJORE_LINK = 0;                  /* Dynamic program is not used */

  EDMA.TCD[0].E_SG = 0;

  EDMA.TCD[0].BWC = 0;                          /* Default bandwidth control- no stalls */

  EDMA.TCD[0].START = 0;                        /* Initialize status flags */

  EDMA.TCD[0].DONE = 0;

  EDMA.TCD[0].ACTIVE = 0;

}

Beforehand I tried ''EDMA.TCD[0].NBYTESu.B.NBYTES = 1;''. I found a note in the reference manuel: 

''The TCD structures for the eDMA channels shown in Figure 136 are implemented in

internal SRAM. These structures are not initialized at reset; therefore, all channel TCD

parameters must be initialized by the application code before activating that channel.''

I think that was the missing link, but I'm not sure.

Additionally I added unique group and channel priorities:

    EDMA.CR.B.GRP0PRI = 0;

    EDMA.CR.B.GRP1PRI = 1;

    EDMA.CR.B.GRP2PRI = 2;

    EDMA.CR.B.GRP3PRI = 3;

    EDMA.CPR[0].R = 15;

    EDMA.CPR[1].R = 14;

    EDMA.CPR[2].R = 13;

    EDMA.CPR[3].R = 12;

    EDMA.CPR[4].R = 11;

    EDMA.CPR[5].R = 10;

    EDMA.CPR[6].R = 9;

    EDMA.CPR[7].R = 8;

    EDMA.CPR[8].R = 7;

    EDMA.CPR[9].R = 6;

    EDMA.CPR[10].R = 5;

    EDMA.CPR[11].R = 4;

    EDMA.CPR[12].R = 3;

    EDMA.CPR[13].R = 2;

    EDMA.CPR[14].R = 1;

    EDMA.CPR[15].R = 0; 

 

Kind regards,

Dominik

Erwan YVIN
ST Employee
Posted on November 30, 2015 at 17:30

Good job,

there is an EDMA for ADC/SPI Example in SPC5Studio :

SPC560Bxx OS-Less DSPI/ADC Example Application using some APIs in spc5_edma.*

With small updates , The freescale cookbook should work.

it is the same device.

             Best regards

                           Erwan