#include "board.h"
//LPC_CREG->DMAMUX
#define DMAMUX_PER10_SCT_DMA_R0 (2 << 20)// Selects DMA to peripheral connection for DMA peripheral 10.
//LPC_GPDMA->CH[0].CONTROL
#define TRANSFER_SIZE(0x04 << 0) // A write to this field sets the size of the transfer when the DMA Controller is the flow controller.
#defineSRC_BURST_SIZE_1(0x00 << 12) // Source burst size 0=1, 1=4, 2=8, 3=16, 4=32, 5=64,6=128, 7=256
#defineSRC_BURST_SIZE_4(0x01 << 12) // Source burst size 0=1, 1=4, 2=8, 3=16, 4=32, 5=64,6=128, 7=256
#defineSRC_BURST_SIZE_8(0x02 << 12) // Source burst size 0=1, 1=4, 2=8, 3=16, 4=32, 5=64,6=128, 7=256
#defineDST_BURST_SIZE_1(0x00 << 15) // Destination burst size 0=1, 1=4, 2=8, 3=16, 4=32, 5=64,6=128, 7=256
#defineDST_BURST_SIZE_4(0x01 << 15) // Destination burst size 0=1, 1=4, 2=8, 3=16, 4=32, 5=64,6=128, 7=256
#defineDST_BURST_SIZE_8(0x02 << 15) // Destination burst size 0=1, 1=4, 2=8, 3=16, 4=32, 5=64,6=128, 7=256
#define SRC_WIDTH_8(0x00 << 18) // Byte (8-bit)
#define SRC_WIDTH_16(0x01 << 18) // HalfWord (16-bit)
#define SRC_WIDTH_32(0x02 << 18) // Word (32-bit)
#define DST_WIDTH_8(0x00 << 21) // Byte (8-bit)
#define DST_WIDTH_16(0x01 << 21) // halfWord (16-bit)
#define DST_WIDTH_32(0x02 << 21) // Word (32-bit)
//Remark: Only Master1 can access a peripheral. Master0 can only access memory.
#define SRC_USE_AHB_0(0x00 << 24) // AHB Master 0 selected for source transfer.
#define SRC_USE_AHB_1(0x01 << 24) // AHB Master 1 selected for source transfer.
#define DST_USE_AHB_0(0x00 << 25) // AHB Master 0 selected for destination transfer.
#define DST_USE_AHB_1(0x01 << 25) // AHB Master 1 selected for destination transfer.
#define SRC_INCREMENT_ENABLE(1 << 26) // The source address is incremented after each transfer
#define SRC_INCREMENT_DISABLE(0 << 26) // The source address is not incremented after each transfer
#define DST_INCREMENT_ENABLE(1 << 27) // The destination address is incremented after each transfer
#define DST_INCREMENT_DISABLE(0 << 27) // The destination address is not incremented after each transfer
#define TERMINALCT_INT_DISABLE (0 << 31) // The terminal count interrupt is disabled
#define TERMINALCT_INT_ENABLE (1 << 31) // The terminal count interrupt is enabled
//LPC_GPDMA->CH[0].CONFIG
#define DMA_ENABLE(1 << 0)
#define DMA_DISABLE(0 << 0)
#define SRCPERIPHERAL_SCT_DMA_R0(0x0A << 1)// SSP0 transmit/I2S0 DMA request 2/SCT DMA request 0
#define DESTPERIPHERAL_SCT_DMA_R0(0x0A << 6)// SSP0 transmit/I2S0 DMA request 2/SCT DMA request 0
#define FLOWCONTROL_M2P_PCTRL(0x05 << 11)// Memory to peripheral (peripheral control)
#define FLOWCONTROL_M2P_DMACTRL(0x01 << 11)// Memory to peripheral (DMA control)
#define FLOWCONTROL_M2M_DMACTRL(0x00 << 11)// Memory to peripheral (DMA control)
#define TERMINAL_COUNT_INTERRUPT_MASK_ENABLE(0x01 << 15) // When cleared, this bit masks out the terminal count interrupt of the relevant channel
#define TERMINAL_COUNT_INTERRUPT_MASK_DISABLE(0x00 << 15) // When cleared, this bit masks out the terminal count interrupt of the relevant channel
#define HALT_DISABLE(0 << 18)// Halt disable = enable DMA Request
#define HALT_ENABLE(1 << 18)// This value can be used with the Active and Channel Enable bits to cleanly disable a DMA channel
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
#define SOURCEARRAYSIZE (256)
/**
* @brief GPDMA Linker List Item structure type definition
*/
typedef struct {
uint32_t SRCADDR;/**< Source Address */
uint32_t DSTADDR;/**< Destination address */
uint32_t NextLLI;/**< Next LLI address, otherwise set to '0' */
uint32_t CONTROL;/**< GPDMA Control of this LLI */
} GPDMA_LLI_Type;
static GPDMA_LLI_Type DMA_LLI_ARRAY[200];
/* Source and destination DMA areas */
static uint32_t source[SOURCEARRAYSIZE], dest[SOURCEARRAYSIZE];
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
static void setupDMATrigger(void)
{
/* Initialize GPDMA controller */
Chip_Clock_EnableOpts(CLK_MX_DMA, true, true, 1); //Start the clock of DMA
//Disable DMA
LPC_GPDMA->CONFIG &= ~1;
/* Clear all DMA interrupt and error flag */
LPC_GPDMA->INTTCCLEAR = 0xFF; //clears channel terminal count interrupt
LPC_GPDMA->INTERRCLR = 0xFF; //clears channel error interrupt.
/* Clear all DMA interrupt and error flag */
LPC_GPDMA->INTTCCLEAR = 0xFF; //clears channel terminal count interrupt
LPC_GPDMA->INTERRCLR = 0xFF; //clears channel error interrupt.
LPC_GPDMA->CH[0].SRCADDR = (uint32_t) &source;
//DMA_LLI_ARRAY[0].SRCADDR = (uint32_t) &LPC_ADCHS->FIFO_OUTPUT;
LPC_GPDMA->CH[0].DESTADDR = (uint32_t) &LPC_SCT->MATCHREL;
//DMA_LLI_ARRAY[0].DSTADDR = (uint32_t) &dest;
LPC_GPDMA->CH[0].LLI = 0;
LPC_GPDMA->CH[0].CONTROL = (8 & 0xFFF) //Number of Transfers (2 Transfers with 4 bursts of 32 bits)
|0x1 << 12 //burst size 0=1, 1=4, 2=8, 3=16, 4=32, 5=64,6=128, 7=256
|0x1 << 15
|0x2 << 18 //Transfer width 0=8bits, 1=16bits, 2=32bits
|0x2 << 21 //Transfer width 0=8bits, 1=16bits, 2=32bits
|0x0 << 24 //0 - AHB_0 (Just Memory), 1 - AHB_1(Memory+Peripherals)
|0x1 << 25 //0 - AHB_0 (Just Memory), 1 - AHB_1(Memory+Peripherals)
|0x1 << 26 // source increment
|0x0 << 27 // dest not increment
|0x0 << 31; //Disable Interrupt
LPC_GPDMA->CH[0].CONFIG |= DMA_ENABLE
|DESTPERIPHERAL_SCT_DMA_R0
|0x01 << 11 //Memory2Peripheral - DMA Control
|( (1 & 0x01) << 15)
|HALT_DISABLE;
/* Enable GPDMA interrupt */
NVIC_EnableIRQ(DMA_IRQn);
//Just to make easy the identification of changes
LPC_SCT->MATCHREL[0].U = (uint32_t) 0x7FFFFFFF;
LPC_SCT->MATCHREL[1].U = (uint32_t) 0x7FFFFFFF;
LPC_SCT->MATCHREL[2].U = (uint32_t) 0x7FFFFFFF;
LPC_SCT->MATCHREL[3].U = (uint32_t) 0x7FFFFFFF;
LPC_SCT->MATCHREL[4].U = (uint32_t) 0x7FFFFFFF;
LPC_SCT->MATCHREL[5].U = (uint32_t) 0x7FFFFFFF;
LPC_SCT->MATCHREL[6].U = (uint32_t) 0x7FFFFFFF;
LPC_SCT->MATCHREL[7].U = (uint32_t) 0x7FFFFFFF;
//Enable DMA
LPC_GPDMA->CONFIG |= 1;
}
/* Put some varying data in the source buffer */
static void fillSourceBuff(void)
{
int i;
static uint32_t seed;
for (i = 0; i < SOURCEARRAYSIZE; i++) {
seed = i + 1;
source = seed;
dest = 0x7FFFFFFF;
dest = i;
}
}
/*****************************************************************************
* Public functions
****************************************************************************/
/**
* @briefDMA interrupt handler
* @returnNothing
*/
void DMA_IRQHandler(void)
{
Board_LED_Toggle(0);
LPC_SCT->MATCHREL;
if (Chip_GPDMA_Interrupt(LPC_GPDMA, 0) == SUCCESS) {
Chip_GPDMA_ClearIntPending(LPC_GPDMA, GPDMA_STATCLR_INTTC, 0);
}else{
Chip_GPDMA_ClearIntPending(LPC_GPDMA, GPDMA_STATCLR_INTERR, 0);
}
}
/**
* @briefMain routine for DMA timer trigger example
* @returnNothing
*/
int main(void)
{
SystemCoreClockUpdate();
Board_Init();
/* Setup source data */
fillSourceBuff();
/* Setup DMA for memory to memory transfer on timer match event */
setupDMATrigger();
/* Idle in background waiting for DMA events */
int i = 0;
while (1) {
LPC_GPDMA->SOFTBREQ = 1<<10;
i++;
LPC_GPDMA->SOFTBREQ = 1<<10;
i++;
}
return 0;
}
|