/******************************************************************************
Filename: dma.c
Target: cc2430
Revised: 16/12-2005
Revision: 1.0
Description:
This example shows how to set up a DMA transfer between two RAM locations.
See also other examples for DMA setup (e.g. AES, ADC_SERIES, FLASH).
******************************************************************************/
#include "app_ex.h"
#include <string.h>
// Prototypes
void initDma(void);
void dma_main(void);
/******************************************************************************
* @fn initDma
*
* @brief
* Initializes components for the DMA transfer application example.
*
* Parameters:
*
* @param void
*
* @return void
*
******************************************************************************/
void initDma(void)
{
initLcd();
SET_MAIN_CLOCK_SOURCE(CRYSTAL);
INIT_BUTTON();
INIT_GLED();
INIT_YLED();
}
/******************************************************************************
* @fn dma_main
*
* @brief
* Sets up the DMA to transfer data between to RAM locations, trigged by
* external interrupt generated by button S1. Checks validity of data
* after transfer.
*
* Parameters:
*
* @param void
*
* @return void
*
******************************************************************************/
#ifdef COMPLETE_APPLICATION
void dma_main(void){
#else
void main(void){
#endif
DMA_DESC dmaChannel;
char sourceString[56] = "This is a test string used to demonstrate DMA transfer."; //56 bytes
char destString[56];
INT8 i;
INT8 errors = 0;
initDma();
//Clearing the destination
memset(destString,0,sizeof(destString));
// Setting up the DMA channel.
SET_WORD(dmaChannel.SRCADDRH, dmaChannel.SRCADDRL, &sourceString); // The start address of the data to be transmitted
SET_WORD(dmaChannel.DESTADDRH, dmaChannel.DESTADDRL, &destString); // The start address of the destination.
SET_WORD(dmaChannel.LENH, dmaChannel.LENL, sizeof(sourceString)); // Setting the number of bytes to transfer.
dmaChannel.VLEN = VLEN_USE_LEN; // Using the length field to determine how many bytes to transfer.
dmaChannel.PRIORITY = PRI_HIGH; // High priority.
dmaChannel.M8 = M8_USE_8_BITS; // Irrelevant since length is determined by the LENH and LENL.
dmaChannel.IRQMASK = FALSE; // The DMA shall not issue an IRQ upon completion.
dmaChannel.DESTINC = DESTINC_1; // The destination address is to be incremented by 1 after each transfer.
dmaChannel.SRCINC = SRCINC_1; // The source address inremented by 1 byte after each transfer.
dmaChannel.TRIG = DMATRIG_NONE; // The DMA channel will be started manually.
dmaChannel.TMODE = TMODE_BLOCK; // The number of bytes specified by LENH and LENL is transferred.
dmaChannel.WORDSIZE = WORDSIZE_BYTE; // One byte is transferred each time.
// Using DMA channel 0.
// Setting where the DMA channel is to read the desciptor and arming the DMA channel.
DMA_SET_ADDR_DESC0(&dmaChannel);
DMA_ABORT_CHANNEL(0);
DMA_ARM_CHANNEL(0);
//Waiting for the user to start the transfer.
lcdUpdate((char*)"Press S1",(char*)"to start DMA.");
while(!buttonPushed());
// Clearing all DMA complete flags and starting the transfer.
DMAIRQ = 0x00;
DMA_START_CHANNEL(0);
// Waiting for the DMA to finish.
while(!(DMAIRQ & DMA_CHANNEL_0));
// Verifying that data is transferred correctly
for(i=0;i<sizeof(sourceString);i++)
{
if(sourceString[i] != destString[i])
errors++;
}
//Displaying the result
if(errors == 0)
{lcdUpdate((char*)"Dma transfer",(char*)"correct!");}
else
{lcdUpdate((char*)"Error in DMA",(char*)"Transfer");}
haltApplicationWithLED();
return;
}
/******************************************************************************
* @fn dma_init
*
* @brief
* Initializes the DMA transfer application example.
*
* Parameters:
*
* @param APPLICATION *a
* Main application
*
* @return void
*
******************************************************************************/
#ifdef COMPLETE_APPLICATION
void dma_init(APPLICATION *a)
{
a->menuText = (char*)"DMA";
a->description = (char*)"Data transfer";
a->main_func = dma_main;
}
#endif