📄 edma_rt.c
字号:
#include "edma_rt.h"
#include "mcbsp_rt.h"
#include "DataType.h"
MCBSP_Handle hMcbsp0; // McBSP0 (codec data) handle
MCBSP_Handle hMcbsp1;
GPIO_Handle hGpio;
Int32 gBufferXmtPing[BUFFSIZE]; // Transmit PING buffer
Int32 gBufferXmtPong[BUFFSIZE]; // Transmit PONG buffer
Int32 gBufferRcvPing[BUFFSIZE]; // Receive PING buffer
Int32 gBufferRcvPong[BUFFSIZE]; // Receive PONG buffer
Int32 copybuf[2*BUFFSIZE];
EDMA_Handle hEdmaXmt; // EDMA channel handles
EDMA_Handle hEdmaReloadXmtPing;
EDMA_Handle hEdmaReloadXmtPong;
EDMA_Handle hEdmaRcv;
EDMA_Handle hEdmaReloadRcvPing;
EDMA_Handle hEdmaReloadRcvPong;
Int16 gXmtChan; // TCC codes (see initEDMA())
Int16 gRcvChan;
/*
* EDMA Config data structure
*/
/* Transmit side EDMA configuration */
EDMA_Config gEdmaConfigXmt = {
EDMA_FMKS(OPT, PRI, HIGH) | // Priority
EDMA_FMKS(OPT, ESIZE, 32BIT) | // Element size
EDMA_FMKS(OPT, 2DS, NO) | // 2 dimensional source?
EDMA_FMKS(OPT, SUM, INC) | // Src update mode
EDMA_FMKS(OPT, 2DD, NO) | // 2 dimensional dest
EDMA_FMKS(OPT, DUM, NONE) | // Dest update mode
EDMA_FMKS(OPT, TCINT, YES) | // Cause EDMA interrupt?
EDMA_FMKS(OPT, TCC, OF(0)) | // Transfer complete code
EDMA_FMKS(OPT, LINK, YES) | // Enable link parameters?
EDMA_FMKS(OPT, FS, NO), // Use frame sync?
(Uint32)&gBufferXmtPing, // Src address
EDMA_FMK (CNT, FRMCNT, NULL) | // Frame count
EDMA_FMK (CNT, ELECNT, BUFFSIZE), // Element count
EDMA_FMKS(DST, DST, OF(0)), // Dest address
EDMA_FMKS(IDX, FRMIDX, DEFAULT) | // Frame index value
EDMA_FMKS(IDX, ELEIDX, DEFAULT), // Element index value
EDMA_FMK (RLD, ELERLD, NULL) | // Reload element
EDMA_FMK (RLD, LINK, NULL) // Reload link
};
/* Receive side EDMA configuration */
EDMA_Config gEdmaConfigRcv = {
EDMA_FMKS(OPT, PRI, HIGH) | // Priority
EDMA_FMKS(OPT, ESIZE, 32BIT) | // Element size
EDMA_FMKS(OPT, 2DS, NO) | // 2 dimensional source?
EDMA_FMKS(OPT, SUM, NONE) | // Src update mode
EDMA_FMKS(OPT, 2DD, NO) | // 2 dimensional dest
EDMA_FMKS(OPT, DUM, INC) | // Dest update mode
EDMA_FMKS(OPT, TCINT, YES) | // Cause EDMA interrupt?
EDMA_FMKS(OPT, TCC, OF(0)) | // Transfer complete code
EDMA_FMKS(OPT, LINK, YES) | // Enable link parameters?
EDMA_FMKS(OPT, FS, NO), // Use frame sync?
EDMA_FMKS(SRC, SRC, OF(0)), // Src address
EDMA_FMK (CNT, FRMCNT, NULL) | // Frame count
EDMA_FMK (CNT, ELECNT, BUFFSIZE), // Element count
(Uint32)&gBufferRcvPing, // Dest address
EDMA_FMKS(IDX, FRMIDX, DEFAULT) | // Frame index value
EDMA_FMKS(IDX, ELEIDX, DEFAULT), // Element index value
EDMA_FMK (RLD, ELERLD, NULL) | // Reload element
EDMA_FMK (RLD, LINK, NULL) // Reload link
};
/*
* initEdma() - Initialize the DMA controller. Use linked transfers to
* automatically transition from ping to pong and visa-versa.
*/
void initEdma(void)
{
/* Configure transmit channel */
hEdmaXmt = EDMA_open(EDMA_CHA_XEVT0, EDMA_OPEN_RESET); // get hEdmaXmt handle and reset channel
hEdmaReloadXmtPing = EDMA_allocTable(-1); // get hEdmaReloadXmtPing handle
hEdmaReloadXmtPong = EDMA_allocTable(-1); // get hEdmaReloadXmtPong handle
gEdmaConfigXmt.dst = MCBSP_getXmtAddr(hMcbsp0); // set the desination address to McBSP1 DXR
gXmtChan = EDMA_intAlloc(-1); // get an open TCC
gEdmaConfigXmt.opt |= EDMA_FMK(OPT,TCC,gXmtChan); // set TCC to gXmtChan
EDMA_config(hEdmaXmt, &gEdmaConfigXmt); // then configure the registers
EDMA_config(hEdmaReloadXmtPing, &gEdmaConfigXmt); // and the reload for Ping
gEdmaConfigXmt.src = EDMA_SRC_OF(gBufferXmtPong); // change the structure to have a source of Pong
EDMA_config(hEdmaReloadXmtPong, &gEdmaConfigXmt); // and configure the reload for Pong
EDMA_link(hEdmaXmt,hEdmaReloadXmtPong); // link the regs to Pong
EDMA_link(hEdmaReloadXmtPong,hEdmaReloadXmtPing); // link Pong to Ping
EDMA_link(hEdmaReloadXmtPing,hEdmaReloadXmtPong); // and link Ping to Pong
/* Configure receive channel */
hEdmaRcv = EDMA_open(EDMA_CHA_REVT0, EDMA_OPEN_RESET); // get hEdmaRcv handle and reset channel
hEdmaReloadRcvPing = EDMA_allocTable(-1); // get hEdmaReloadRcvPing handle
hEdmaReloadRcvPong = EDMA_allocTable(-1); // get hEdmaReloadRcvPong handle
gEdmaConfigRcv.src = MCBSP_getRcvAddr(hMcbsp0); // and the desination address to McBSP1 DXR
gRcvChan = EDMA_intAlloc(-1); // get an open TCC
gEdmaConfigRcv.opt |= EDMA_FMK(OPT,TCC,gRcvChan); // set TCC to gRcvChan
EDMA_config(hEdmaRcv, &gEdmaConfigRcv); // then configure the registers
EDMA_config(hEdmaReloadRcvPing, &gEdmaConfigRcv); // and the reload for Ping
gEdmaConfigRcv.dst = EDMA_DST_OF(gBufferRcvPong); // change the structure to have a destination of Pong
EDMA_config(hEdmaReloadRcvPong, &gEdmaConfigRcv); // and configure the reload for Pong
EDMA_link(hEdmaRcv,hEdmaReloadRcvPong); // link the regs to Pong
EDMA_link(hEdmaReloadRcvPong,hEdmaReloadRcvPing); // link Pong to Ping
EDMA_link(hEdmaReloadRcvPing,hEdmaReloadRcvPong); // and link Ping to Pong
/* Enable interrupts in the EDMA controller */
EDMA_intClear(gXmtChan);
EDMA_intClear(gRcvChan); // clear any possible spurious interrupts
// enable EDMA interrupts (CIER)
EDMA_intEnable(gXmtChan);
EDMA_intEnable(gRcvChan); // enable EDMA interrupts (CIER)
EDMA_enableChannel(hEdmaXmt); // enable EDMA channel
EDMA_enableChannel(hEdmaRcv); // enable EDMA channel
/* Do a dummy write to generate the first McBSP transmit event */
MCBSP_write(hMcbsp0, 0x1000<<12);
}
/* ----------------------EDMA Interrupt Service Routines -------------------- */
/*
* edmaHwi() - Interrupt service routine for the DMA transfer. It is
* triggered when a complete DMA receive frame has been
* transferred. The edmaHwi ISR is inserted into the interrupt
* vector table at compile time through a setting in the DSP/BIOS
* configuration under Scheduling --> HWI --> HWI_INT8. edmaHwi
* uses the DSP/BIOS Dispatcher to save register state and make
* sure the ISR co-exists with other DSP/BIOS functions.
*/
interrupt void c_int08(void)
{
static Uint32 pingOrPong = PING; // Ping-pong state variable
static Int16 xmtdone = 0, rcvdone = 0;
/* Check CIPR to see which transfer completed */
if (EDMA_intTest(gXmtChan))
{
EDMA_intClear(gXmtChan);
xmtdone = 1;
}
if (EDMA_intTest(gRcvChan))
{
EDMA_intClear(gRcvChan);
rcvdone = 1;
}
if (xmtdone && rcvdone)
{ if (pingOrPong==PING)
{
processBuffer(PING);
pingOrPong = PONG;
} else
{
processBuffer(PONG);
pingOrPong = PING;
}
rcvdone = 0;
xmtdone = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -