Memory to Memory DMA demo from CMSIS example. This demo execute 1000 times of 32 word memory to memory DMA (copy), and also measures number of dummy loop execution during DMA cylcles. Line 56 of "DMA_M2M.c" can change DMA source. where; 1)static : source is SRAM 2)const : source is Flash ROM

Dependencies:   mbed

DMA_M2M.c

Committer:
todotani
Date:
2010-11-14
Revision:
0:692bf16d1455

File content as of revision 0:692bf16d1455:

/***********************************************************************//**
 * @file        flash_2_ram.c
 * @purpose     This example used to test GPDMA function by transferring
 *              data from flash to ram memory
 * @version     2.0
 * @date        21. May. 2010
 * @author      NXP MCU SW Application Team
 *   
 *  Adupted for mebed 
 *  and modified for insturction execution test during DMA
 *    by Todotani 14 Nov. 2010
 *---------------------------------------------------------------------
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
 **********************************************************************/

#include "lpc17xx_gpdma.h"
#include "lpc17xx_libcfg.h"
#include "mbed.h"
#include "GetTickCount.h"

/* Example group ----------------------------------------------------------- */
/** @defgroup GPDMA_Flash_2_Ram_Test    Flash_2_Ram_Test
 * @ingroup GPDMA_Examples
 * @{
 */

/************************** PRIVATE DEFINTIONS*************************/
#define DMA_SIZE        32          /** DMA transfer size */
#define DMA_CYCLES      1000

/************************** PRIVATE VARIABLES *************************/
uint8_t menu[]=
    "********************************************************************************\n\r"
    "Hello NXP Semiconductors \n\r"
    "GPDMA demo \n\r"
    "\t - MCU: LPC1768(mbed) \n\r"
    "\t - Core: ARM CORTEX-M3 \n\r"
    "\t - Communicate via: UART0 - 9600 bps \n\r"
    "This example used to test GPDMA function by transfer data from Flash \n\r"
    "to RAM memory\n\r"
    "********************************************************************************\n\r";
uint8_t menu2[] = "Demo terminated! \n\r";
uint8_t err_menu[] = "Buffer Check fail!\n\r";
uint8_t compl_menu[] = "Buffer Check success!\n\r\n\r";

//DMAScr_Buffer will be burn into flash when compile
static uint32_t DMASrc_Buffer[DMA_SIZE]=
{
    0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
    0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
    0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
    0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
    0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
    0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
    0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
    0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40
};

uint32_t DMADest_Buffer[DMA_SIZE];
//uint32_t *DMADest_Buffer = (uint32_t *)0x2007C000;   //LPC_AHBRAM0_BASE;

volatile uint32_t TC_count = 0;
uint32_t loop = 0;
GPDMA_Channel_CFG_Type GPDMACfg;

Serial pc(USBTX, USBRX);


/*-------------------------MAIN FUNCTION------------------------------*/
extern "C" void DMA_IRQHandler (void);      // extern "C" required for mbed

void Buffer_Init(void);
void Buffer_Verify(void);
void SetupDMA(void);


/*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
/*********************************************************************//**
 * @brief        GPDMA interrupt handler sub-routine
 * @param[in]    None
 * @return       None
 **********************************************************************/
void DMA_IRQHandler (void)
{
    // check GPDMA interrupt on channel 0
    if (GPDMA_IntGetStatus(GPDMA_STAT_INT, 0)) { //check interrupt status on channel 0
        // Check counter terminal status
        if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0)) {
            // Clear terminate counter Interrupt pending
            GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);

            if (++TC_count < DMA_CYCLES) {
                // Setup channel with given parameter
                GPDMA_Setup(&GPDMACfg);
                // Run DMA again
                GPDMA_ChannelCmd(0, ENABLE);
                return;
            } else {
                /* DMA run predetermined cycles */
                int elapsedTime =  GetTickCount();
                Buffer_Verify();
                pc.printf("%s", compl_menu);
                pc.printf("DMA %d cycles, %d loop executions\n\r", TC_count, loop);
                pc.printf("Elapsed time %d ms\n\r\n\r", elapsedTime);

                while(1);   // Halt program
            }
        }
        
        if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)){
            // Clear error counter Interrupt pending
            GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
            pc.printf("DMA Error detected.\n\r");
            while(1);       // Halt program
        }
    }
}


/*********************************************************************//**
 * @brief        Verify buffer
 * @param[in]    None
 * @return       None
 **********************************************************************/
void Buffer_Verify(void)
{
    uint8_t i;
    uint32_t *src_addr = (uint32_t *)DMASrc_Buffer;
    uint32_t *dest_addr = (uint32_t *)DMADest_Buffer;

    for ( i = 0; i < DMA_SIZE; i++ )
    {
        if ( *src_addr++ != *dest_addr++ )
        {
            pc.printf("Verrify Error!.\n\r");
        }
    }
}


/*-------------------------MAIN FUNCTION--------------------------------*/
/*********************************************************************//**
 * @brief        c_entry: Main program body
 * @param[in]    None
 * @return       int
 **********************************************************************/
int c_entry(void)
{
    pc.baud(9600);

    // print welcome screen
    pc.printf("%s", menu);

    /* Disable GPDMA interrupt */
    NVIC_DisableIRQ(DMA_IRQn);
    /* preemption = 1, sub-priority = 1 */
    NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01));

    /* Initialize GPDMA controller */
    GPDMA_Init();

    // Setup GPDMA channel --------------------------------
    // channel 0
    GPDMACfg.ChannelNum = 0;
    // Source memory
    GPDMACfg.SrcMemAddr = (uint32_t)DMASrc_Buffer;
    // Destination memory
    GPDMACfg.DstMemAddr = (uint32_t)DMADest_Buffer;
    // Transfer size
    GPDMACfg.TransferSize = DMA_SIZE;
    // Transfer width
    GPDMACfg.TransferWidth = GPDMA_WIDTH_WORD;
    // Transfer type
    GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2M;
    // Source connection - unused
    GPDMACfg.SrcConn = 0;
    // Destination connection - unused
    GPDMACfg.DstConn = 0;
    // Linker List Item - unused
    GPDMACfg.DMALLI = 0;
    // Setup channel with given parameter
    GPDMA_Setup(&GPDMACfg);

    /* Enable GPDMA interrupt */
    NVIC_EnableIRQ(DMA_IRQn);
    
    pc.printf("Start transfer...\n\r");
    GetTickCount_Start();
    
    // Enable GPDMA channel 0
    GPDMA_ChannelCmd(0, ENABLE);

    /* Wait for GPDMA processing complete */
    while (1) {
        loop++;
    }

    return 1;
}

/* With ARM and GHS toolsets, the entry point is main() - this will
 allow the linker to generate wrapper code to setup stacks, allocate
 heap area, and initialize and copy code and data segments. For GNU
 toolsets, the entry point is through __start() in the crt0_gnu.asm
 file, and that startup code will setup stacks and data */
int main(void) {
    return c_entry();
}

#ifdef  DEBUG
/*******************************************************************************
 * @brief        Reports the name of the source file and the source line number
 *                 where the CHECK_PARAM error has occurred.
 * @param[in]    file Pointer to the source file name
 * @param[in]    line assert_param error line source number
 * @return        None
 *******************************************************************************/
void check_failed(uint8_t *file, uint32_t line) {
    /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

    /* Infinite loop */
    while (1)
        ;
}
#endif

/*
 * @}
 */