Skip to main content
dominik2
Associate II
November 30, 2015
Question

eDMA with SPC560B

  • November 30, 2015
  • 2 replies
  • 1157 views
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 topic has been closed for replies.

    2 replies

    dominik2
    dominik2Author
    Associate II
    November 30, 2015
    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 Technical Moderator
    November 30, 2015
    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

    In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question.