EFR32MG13p-LDMA学习笔记(single-software)
single-software
此example用来演示 Single Transfer descriptor: Transfers TOTAL_BYTES of data and then stops
示例非常好玩,可以实现数组的倒序功能。
example code
#include <stdio.h>
#include "em_chip.h"
#include "em_device.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_ldma.h"
/* DMA channel used for the examples */
#define LDMA_CHANNEL 0
#define LDMA_CH_MASK 1 << LDMA_CHANNEL
/* Memory to memory transfer buffer size and constant for GPIO PRS */
#define BUFFER_SIZE 127
#define TRANSFER_SIZE (BUFFER_SIZE - 1)
/* Buffer for memory to memory transfer */
uint16_t srcBuffer[BUFFER_SIZE]; //源数据
uint16_t dstBuffer[BUFFER_SIZE]; //目的数据
/***************************************************************************//**
* @brief
* LDMA IRQ handler.
******************************************************************************/
void LDMA_IRQHandler( void )
{
uint32_t pending;
/* Read interrupt source */
pending = LDMA_IntGet();
/* Clear interrupts */
LDMA_IntClear(pending);
/* Check for LDMA error */
if ( pending & LDMA_IF_ERROR ){
/* Loop here to enable the debugger to see what has happened */
while (1);
}
}
/***************************************************************************//**
* @brief
* Initialize the LDMA controller for single direct register transfer
******************************************************************************/
void initLdma(void)
{
uint32_t i;
/* Initialize buffers for memory transfer */
for (i = 0; i < BUFFER_SIZE; i++){
srcBuffer[i] = i;
dstBuffer[i] = 0;
}
LDMA_Init_t init = LDMA_INIT_DEFAULT;
LDMA_Init( &init );
/* Writes directly to the LDMA channel registers */
LDMA->CH[LDMA_CHANNEL].CTRL =
LDMA_CH_CTRL_SIZE_HALFWORD //传输单位为2字节,因为源数据和目的数据都是uin16_t的
+ LDMA_CH_CTRL_REQMODE_ALL //REQMODE为ALL,也就是一次LDMA请求需要传输(TRANSFER_SIZE + 1)个SIZE单位的数据
+ LDMA_CH_CTRL_BLOCKSIZE_UNIT4 //如果REQMODE为BLOCK,那么一次LDMA请求需要传输的数据为BLOCKSIZE个SIZE单位的数据
+ (TRANSFER_SIZE << _LDMA_CH_CTRL_XFERCNT_SHIFT); //如果REQMODE为ALL,那么一次LDMA请求需要传输的数据为(TRANSFER_SIZE + 1)个SIZE单位的数据
LDMA->CH[LDMA_CHANNEL].SRC = (uint32_t)&srcBuffer; //设置源地址为源数组的首地址
LDMA->CH[LDMA_CHANNEL].DST = (uint32_t)&dstBuffer[BUFFER_SIZE -1];//设置目的地址为目的数组的尾地址
LDMA->CH[LDMA_CHANNEL].CFG = 1 << 21; //设置目的数组的访问顺序为降序
/* Enable interrupt and use software to start transfer */
LDMA->CH[LDMA_CHANNEL].REQSEL = ldmaPeripheralSignal_NONE;//关闭所有外设的LDMA请求
LDMA->IFC = LDMA_CH_MASK; //清除中断
LDMA->IEN = LDMA_CH_MASK; //使能中断
/* Enable LDMA Channel */
LDMA->CHEN = LDMA_CH_MASK; //使能LDMA通道
/* Request transfer */
LDMA->SWREQ |= LDMA_CH_MASK;//software LDMA请求
}
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void)
{
/* Chip errata */
CHIP_Init();
/* Init DCDC regulator if available */
EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_DEFAULT;
EMU_DCDCInit(&dcdcInit);
/* Initialize LDMA */
initLdma();
while (1)
{
EMU_EnterEM1();
}
}