📄 buffer.c
字号:
//buffer_init
#include "Buffer.h"
#include <services/services.h>
#include "ImgTool4BFx.h"
/*********************************************************************
*Functions defined in this file have similar functionality.
*But for easy understanding of the dataflow different functions
*are created
**********************************************************************/
/************************************************************************
Function:BufferSDtoL1
Description:
************************************************************************/
/*
extern enum {
waiting_for_callback_to_happen,
callback_happened
} Callback_Flag[2];
*/
extern ADI_DMA_DESCRIPTOR_LARGE gDst0Buffers[5]; // descriptors where data is written to
extern ADI_DMA_DESCRIPTOR_LARGE gSrc0Buffers[5]; // descriptors where data is written from
extern ADI_DMA_DESCRIPTOR_LARGE gDst1Buffers[5]; // descriptors where data is written to
extern ADI_DMA_DESCRIPTOR_LARGE gSrc1Buffers[5]; // descriptors where data is written from
extern ADI_DMA_CHANNEL_HANDLE dma_s0_chan_handle; // source DMA channel handle
extern ADI_DMA_CHANNEL_HANDLE dma_d0_chan_handle; // destination DMA channel handle
extern ADI_DMA_CHANNEL_HANDLE dma_s1_chan_handle; // source DMA channel handle
extern ADI_DMA_CHANNEL_HANDLE dma_d1_chan_handle; // destination DMA channel handle
extern volatile int gDesDmaDoneFlag[2];
extern ADI_DCB_HANDLE Callback_Handle;
extern ADI_DMA_MANAGER_HANDLE gDMAManagerHandle; // handle to the DMA Manager
/*
void ConfigDst2DTransPara(ADI_DMA_2D_TRANSFER *transDst2D, void *addr, u16 XCount, s16 XModify, u16 YCount, s16 YModify )
{
transDst2D->StartAddress = addr;
transDst2D->XCount = XCount;
transDst2D->XModify = XModify;
transDst2D->YCount = YCount;
transDst2D->YModify = YModify;
}
void FastConfigDst2DAddr(ADI_DMA_2D_TRANSFER *transDst2D, void *addr)
{
transDst2D->StartAddress = addr;
}
void ConfigSrc2DTransPara(ADI_DMA_2D_TRANSFER *transSrc2D, void *addr, u16 XCount, s16 XModify, u16 YCount, s16 YModify )
{
transSrc2D->StartAddress = addr;
transSrc2D->XCount = XCount;
transSrc2D->XModify = XModify;
transSrc2D->YCount = YCount;
transSrc2D->YModify = YModify;
}
void FastConfigSrc2DAddr(ADI_DMA_2D_TRANSFER *transSrc2D, void *addr)
{
transSrc2D->StartAddress = addr;
}
// This is the callback function for the DMA.
void Memory_Callback0(void *AppHandle, u32 Event, void *pArg)
{
// watch for errors
if (Event == ADI_DMA_EVENT_ERROR_INTERRUPT) {
// ezErrorCheck(1);
return;
}
Callback_Flag[0] = callback_happened;
}
void Memory_Callback1(void *AppHandle, u32 Event, void *pArg)
{
// watch for errors
if (Event == ADI_DMA_EVENT_ERROR_INTERRUPT) {
// ezErrorCheck(1);
return;
}
Callback_Flag[1] = callback_happened;
}
*/
// callback function called by DCB
void Descriptor_Callback0( void *AppHandle, u32 Event, void *pArg)
{
switch(Event) {
case ADI_DMA_EVENT_DESCRIPTOR_PROCESSED:
gDesDmaDoneFlag[0] = 1; // Tell main() that the DMA is done.
break;
case ADI_DMA_EVENT_INNER_LOOP_PROCESSED: // this is only used with 2-D DMA
break;
case ADI_DMA_EVENT_OUTER_LOOP_PROCESSED: // we're not using this feature of DMA
break;
case ADI_DMA_EVENT_ERROR_INTERRUPT: // this is a common error when debugging DMA applications
break;
default: // unexpected events
// ezErrorCheck(1);
break;
}
}
void Descriptor_Callback1( void *AppHandle, u32 Event, void *pArg)
{
switch(Event) {
case ADI_DMA_EVENT_DESCRIPTOR_PROCESSED:
gDesDmaDoneFlag[1] = 1; // Tell main() that the DMA is done.
break;
case ADI_DMA_EVENT_INNER_LOOP_PROCESSED: // this is only used with 2-D DMA
break;
case ADI_DMA_EVENT_OUTER_LOOP_PROCESSED: // we're not using this feature of DMA
break;
case ADI_DMA_EVENT_ERROR_INTERRUPT: // this is a common error when debugging DMA applications
break;
default: // unexpected events
// ezErrorCheck(1);
break;
}
}
void Descriptor_Start(int handleId)
{
if(handleId==0)
{
gDesDmaDoneFlag[0] = 0;
adi_dma_Queue( dma_s0_chan_handle, (ADI_DMA_DESCRIPTOR_HANDLE)&gSrc0Buffers[0]);
adi_dma_Queue( dma_d0_chan_handle, (ADI_DMA_DESCRIPTOR_HANDLE)&gDst0Buffers[0]);
adi_dma_Control( dma_s0_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)TRUE);
adi_dma_Control( dma_d0_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)TRUE);
}
else
{
gDesDmaDoneFlag[1] = 0;
adi_dma_Queue( dma_s1_chan_handle, (ADI_DMA_DESCRIPTOR_HANDLE)&gSrc1Buffers[0]);
adi_dma_Queue( dma_d1_chan_handle, (ADI_DMA_DESCRIPTOR_HANDLE)&gDst1Buffers[0]);
adi_dma_Control( dma_s1_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)TRUE);
adi_dma_Control( dma_d1_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)TRUE);
}
}
void Descriptor_Wait(int handleId)
{
if(handleId==0)
{
while(gDesDmaDoneFlag[0] == 0); // Wait for the DMA to finish
adi_dma_Control( dma_s0_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)FALSE);
adi_dma_Control( dma_d0_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)FALSE);
}
else
{
while(gDesDmaDoneFlag[1] == 0); // Wait for the DMA to finish
adi_dma_Control( dma_s1_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)FALSE);
adi_dma_Control( dma_d1_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)FALSE);
}
}
void DesBufferSetup(
int handleId,
int buffsNum, // number of buffers (descriptors) to use in each direction
int Read0Write1,
int Dma1D02D1, // 0 = 1-dimensional DMA, 1 = 2-dimensional DMA
int XCount, int XModify, // number of elements in each buffer (descriptor)
int YCount, int YModify,
int bytes_per_element) // number of bytes in each element (1, 2, or 4)
{
ADI_DMA_CONFIG_REG config;
int i, j, k;
// careful not to confuse 0,1,2 values with 1, 2, and 4 bytes
if(bytes_per_element == 1) config.b_WDSIZE = 0; // 0=8bits (1 byte)
else if(bytes_per_element == 2) config.b_WDSIZE = 1; // 1=16bits (2 bytes)
else if(bytes_per_element == 4) config.b_WDSIZE = 2; // 2=32bits (4 bytes)
config.b_DMA2D = Dma1D02D1; // 0 = 1-dimensional DMA, 1 = 2-dimensional DMA
if(Read0Write1==1)
{
config.b_WNR = 1; // 0 = memory read, 1 = memory write
}
else
{
// The source uses slightly different config register settings
config.b_WNR = 0; // 0=memory read, 1=memory write
config.b_DI_EN = 0; // don't interrupt on outbound data
}
if(handleId==0)
{
if(Read0Write1==1)
{
for (i = 0; i < buffsNum; i++)
{ // set up all the buffers (descriptors) for writing TO memory
// DestinationBuffers[i].StartAddress = ; // SDRAM
gDst0Buffers[i].Config = config; // the config register we set up earlier
gDst0Buffers[i].XCount = XCount;
gDst0Buffers[i].XModify = XModify;
gDst0Buffers[i].YCount = YCount; // this is for 2-dimensional DMA only
gDst0Buffers[i].YModify = YModify; // this is for 2-dimensional DMA only
if (i == (buffsNum-1))
{
gDst0Buffers[i].CallbackFlag = TRUE; // interrupt on the last descriptor only
gDst0Buffers[i].pNext = NULL; // the last descriptor always points to zero!
} else
{
gDst0Buffers[i].CallbackFlag = FALSE; // don't interrupt on intermediate descriptors
gDst0Buffers[i].pNext = &gDst0Buffers[i+1]; // point to the next buffer in the chain
}
}
}
else
{
for (i = 0; i < buffsNum; i++)
{ // set up all the buffers (descriptors) for writing FROM memory
//SourceBuffers[i].StartAddress = (void *)(SOURCE_DATA_START * i * ELEMENTS * BYTES_PER_ELEMENT); //SDRAM
gSrc0Buffers[i].Config = config; // the config register we set up earlier
gSrc0Buffers[i].XCount = XCount;
gSrc0Buffers[i].XModify = XModify;
gSrc0Buffers[i].YCount = YCount; // this is for 2-dimensional DMA only
gSrc0Buffers[i].YModify = YModify; // this is for 2-dimensional DMA only
if (i == (buffsNum-1)) // Notice we only use interrupts in the destination DMA
gSrc0Buffers[i].pNext = NULL; // the last descriptor always points to zero!!
else
gSrc0Buffers[i].pNext = &gSrc0Buffers[i+1]; // point to the next buffer in the chain
}
}
} // if handleId==0
else
{
if(Read0Write1==1)
{
for (i = 0; i < buffsNum; i++)
{ // set up all the buffers (descriptors) for writing TO memory
// DestinationBuffers[i].StartAddress = ; // SDRAM
gDst1Buffers[i].Config = config; // the config register we set up earlier
gDst1Buffers[i].XCount = XCount;
gDst1Buffers[i].XModify = XModify;
gDst1Buffers[i].YCount = YCount; // this is for 2-dimensional DMA only
gDst1Buffers[i].YModify = YModify; // this is for 2-dimensional DMA only
if (i == (buffsNum-1))
{
gDst1Buffers[i].CallbackFlag = TRUE; // interrupt on the last descriptor only
gDst1Buffers[i].pNext = NULL; // the last descriptor always points to zero!
} else
{
gDst1Buffers[i].CallbackFlag = FALSE; // don't interrupt on intermediate descriptors
gDst1Buffers[i].pNext = &gDst1Buffers[i+1]; // point to the next buffer in the chain
}
}
}
else
{
for (i = 0; i < buffsNum; i++)
{ // set up all the buffers (descriptors) for writing FROM memory
//SourceBuffers[i].StartAddress = (void *)(SOURCE_DATA_START * i * ELEMENTS * BYTES_PER_ELEMENT); //SDRAM
gSrc1Buffers[i].Config = config; // the config register we set up earlier
gSrc1Buffers[i].XCount = XCount;
gSrc1Buffers[i].XModify = XModify;
gSrc1Buffers[i].YCount = YCount; // this is for 2-dimensional DMA only
gSrc1Buffers[i].YModify = YModify; // this is for 2-dimensional DMA only
if (i == (buffsNum-1)) // Notice we only use interrupts in the destination DMA
gSrc1Buffers[i].pNext = NULL; // the last descriptor always points to zero!!
else
gSrc1Buffers[i].pNext = &gSrc1Buffers[i+1]; // point to the next buffer in the chain
}
}
}
}
void DesDmaSetAddr(int handleId, int Src0Dst1, int arrId, void *addr)
{
if(handleId==0)
{
if(Src0Dst1==0)
{
gSrc0Buffers[arrId].StartAddress = addr;
}
else
{
gDst0Buffers[arrId].StartAddress = addr;
}
}
else
{
if(Src0Dst1==0)
{
gSrc1Buffers[arrId].StartAddress = addr;
}
else
{
gDst1Buffers[arrId].StartAddress = addr;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -