📄 afe.c
字号:
#elif AFE_MCBSP == 1
#define DMASYNC_XEVT DMASYNC_XEVT1
#else
#define DMASYNC_XEVT DMASYNC_XEVT2
#endif
#if (AFE_TX_FORMAT == 24) // Send two 24-bit words
DMA_SUBREG_WRITE(DMA_CHANNEL5, DMGDA_SUBADDR, DXR2_ADDR(AFE_MCBSP)); // DMA Global Destination Address
// Set up DMA to synchronize transfer with MCBSP transmit complete.
// Send 1 frame in double-word mode.
#define DMA_SYNC_WRITE_ADC2 ((DMASYNC_XEVT<<DSYN)|(DBLW_DBL<<DBLW)|((1-1)<<FRAMECOUNT))
// Set up DMA Tx Channel to write commands to the ADC from an ADC command list.
DMA_init( DMA_CHANNEL5, // u16 channel
(u32)(upADCCmdListAddr+1), // u16 source= 2nd entry in ADC Command List
DXR2_ADDR(AFE_MCBSP), // u16 destination = ADC MCBSP Transmit reg
(uArraySize-1-1), // u16 count (extra -1 because of manual tx of 1st element)
DMA_SYNC_WRITE_ADC2, // u16 frame_sync = transmit complete event
DMA_CONTROL_WRITE_ADC2); // u16 control_mode
#else // Send three 16-bit words
DMA_SUBREG_WRITE(DMA_CHANNEL5, DMGDA_SUBADDR, DXR1_ADDR(AFE_MCBSP)); // DMA Global Destination Address
// Set up DMA to synchronize transfer with MCBSP transmit complete.
// Send 1 frame in single-word mode.
#define DMA_SYNC_WRITE_ADC2 ((DMASYNC_XEVT<<DSYN)|(DBLW_SNGL<<DBLW)|((1-1)<<FRAMECOUNT))
// Set up DMA Tx Channel to write commands to the ADC from an ADC command list.
DMA_init( DMA_CHANNEL5, // u16 channel
(u16)(upADCCmdListAddr+1), // u16 source= 2nd entry in ADC Command List
DXR1_ADDR(AFE_MCBSP), // u16 destination = ADC MCBSP Transmit reg
(uArraySize-1-1), // u16 count (extra -1 because of manual tx of 1st element)
DMA_SYNC_WRITE_ADC2, // u16 frame_sync = transmit complete event
DMA_CONTROL_WRITE_ADC2); // u16 control_mode
#endif
//-------------------------------------------------------------------------------------
// ----- Release clock generator from reset and wait 2 clock cycles -----
//-------------------------------------------------------------------------------------
MCBSP_SUBREG_BITWRITE(AFE_MCBSP, SPCR2_SUBADDR, GRST, GRST_SZ, 1); //!!!TEMP!!!
RPTNOP(2*SER_CLK_DIV_SLOW); // Wait 2 cycles of slow serial clock
//-------------------------------------------------------------------------------------
// Release receiver and transmitter from reset.
//-------------------------------------------------------------------------------------
MCBSP_SUBREG_WRITE(AFE_MCBSP, SPCR1_SUBADDR, SPCR1_CTRL);
MCBSP_SUBREG_WRITE(AFE_MCBSP, SPCR2_SUBADDR, (SPCR2_CTRL & (~(1<<FRST)))); // Turn on SPCR2 except for FRST
//-------------------------------------------------------------------------------------
//----- Arm the DMA Engine -----
//-------------------------------------------------------------------------------------
DMPREC |= (AFE_DMA_MASK);
//-------------------------------------------------------------------------------------
//----- Load data transmit register with first word to start transmission -----
//-------------------------------------------------------------------------------------
REG_WRITE32(DXR2_ADDR(AFE_MCBSP), upADCCmdListAddr[0]); // Send first entry in CmdList to ADC
//-------------------------------------------------------------------------------------
// Turn on frame generation, which should start sending word we just loaded in DXR1.
//-------------------------------------------------------------------------------------
MCBSP_SUBREG_BITWRITE(AFE_MCBSP, SPCR2_SUBADDR, FRST, FRST_SZ, 1);
//-------------------------------------------------------------------------------------
// The DMA transfer is now running. We can now return to the main code and wait for
// the transfer-complete interrupt from the DMA engine.
//-------------------------------------------------------------------------------------
//----------------- Start DMAXfer
return;
}
#endif
#if COMPILE_MODE == DSP_COMPILE
//==========================================================================================
// Function: DMAReadAFE()
//
// Description: Use the DMA engine and MCBSP to quickly read the AFE Rx signal.
//
// Revision History:
//==========================================================================================
void DMAReadAFE(u16 uRxBuffAddr, u16 uArraySize)
{
#define DBLW_SNGL 0
#define DBLW_DBL 1
#define AFE_RX_DMA_MASK (EN<<DE4) // Enable DMA channel 4(Rx Data)
//----- Disable the DMA Engine while we configure it -----
DMPREC &= ~(AFE_RX_DMA_MASK);
// Configure MCBSP for automatic periodic Frame Sync generation
/****************************************************************/
/* Place ports in reset - setting XRST & RRST to 0 */
/* and turning off clock generator and frame sync generator */
/****************************************************************/
MCBSP_SUBREG_WRITE(AFE_MCBSP, SPCR1_SUBADDR, 0x0000);
MCBSP_SUBREG_WRITE(AFE_MCBSP, SPCR2_SUBADDR, 0x0000);
// ----- Set the serial clock speed for these transfers -----
MCBSP_SUBREG_WRITE(AFE_MCBSP, SRGR1_SUBADDR, SRGR1_CTRL_FAST);
// ----- Configure the MCBSP to transmit periodic frame syncs automatically
MCBSP_SUBREG_WRITE(AFE_MCBSP, SRGR2_SUBADDR, SRGR2_CTRL_DMA);
// Generate an interrupt to the DSP at the end of the block transfer.
// Same source address from data space, post-increment destination address in data space.
// Use ABU (auto-buffering) mode.
#define DMA_CONTROL_READ_ADC2 ( (0<<AUTOINIT) | (1<<DINM) | (0<<IMOD) | (1<<CTMOD) \
| (0<<SIND) | (1<<DMS) | (1<<DIND) | (1<<DMD) )
#if AFE_MCBSP == 0
#define DMASYNC_REVT DMASYNC_REVT0
#elif AFE_MCBSP == 1
#define DMASYNC_REVT DMASYNC_REVT1
#else
#define DMASYNC_REVT DMASYNC_REVT2
#endif
#if (AFE_RX_FORMAT == 24) // Read two 24-bit words
// Set up DMA to synchronize transfer with MCBSP receive complete.
// Read 1 frame in double-word mode.
#define DMA_SYNC_READ_ADC2 ((DMASYNC_REVT<<DSYN)|(DBLW_DBL<<DBLW)|((1-1)<<FRAMECOUNT))
// // Read 2 frames in single-word mode.
// #define DMA_SYNC_READ_ADC2 ((DMASYNC_REVT2<<DSYN)|(DBLW_SNGL<<DBLW)|((2-1)<<FRAMECOUNT))
// // Read 1 frame in single-word mode.
// #define DMA_SYNC_READ_ADC2 ((DMASYNC_REVT2<<DSYN)|(DBLW_SNGL<<DBLW)|((1-1)<<FRAMECOUNT))
// Set up DMA Rx Channel to read sensor measuremement from the ADC into upRawLocal[];
DMA_init( DMA_CHANNEL4, // u16 channel,
/* DRR1_ADDR(AFE_MCBSP), // u16 source= ADC MCBSP Data Receive register */
DRR2_ADDR(AFE_MCBSP), // u16 source= ADC MCBSP Data Receive register
uRxBuffAddr, // u16 dest= Raw readings array
(uArraySize), // u16 count
DMA_SYNC_READ_ADC2, // u16 frame_sync = receive complete event
DMA_CONTROL_READ_ADC2); // u16 control_mode
#else // Read three 16-bit words
// Set up DMA to synchronize transfer with MCBSP receive complete.
// Read 1 frame in single-word mode.
#define DMA_SYNC_READ_ADC2 ((DMASYNC_REVT<<DSYN)|(DBLW_SNGL<<DBLW)|((1-1)<<FRAMECOUNT))
// Set up DMA Rx Channel to read sensor measuremement from the ADC into upRawLocal[];
DMA_init( DMA_CHANNEL4, // u16 channel,
DRR1_ADDR(AFE_MCBSP), // u16 source= hi word of MCBSP Data Receive reg
uRxBuffAddr, // u16 dest= Raw readings array
(uArraySize-1), // u16 count
DMA_SYNC_READ_ADC2, // u16 frame_sync = receive complete event
DMA_CONTROL_READ_ADC2); // u16 control_mode
#endif
//-------------------------------------------------------------------------------------
// ----- Release clock generator from reset and wait 2 clock cycles -----
//-------------------------------------------------------------------------------------
MCBSP_SUBREG_BITWRITE(AFE_MCBSP, SPCR2_SUBADDR, GRST, GRST_SZ, 1); //!!!TEMP!!!
RPTNOP(2*SER_CLK_DIV_SLOW); // Wait 2 cycles of slow serial clock
//-------------------------------------------------------------------------------------
// Release receiver and transmitter from reset.
//-------------------------------------------------------------------------------------
MCBSP_SUBREG_WRITE(AFE_MCBSP, SPCR1_SUBADDR, SPCR1_CTRL);
MCBSP_SUBREG_WRITE(AFE_MCBSP, SPCR2_SUBADDR, (SPCR2_CTRL & (~(1<<FRST)))); // Turn on SPCR2 except for FRST
//-------------------------------------------------------------------------------------
//----- Arm the DMA Engine -----
//-------------------------------------------------------------------------------------
DMPREC |= (AFE_RX_DMA_MASK);
// //-------------------------------------------------------------------------------------
// //----- Load data transmit register with first word to start transmission -----
// //-------------------------------------------------------------------------------------
// REG_WRITE(DXR12_ADDR, upADCCmdListAddr[0]); // Send first entry in CmdList to ADC
//
// //-------------------------------------------------------------------------------------
// // Turn on frame generation, which should start sending word we just loaded in DXR1.
// //-------------------------------------------------------------------------------------
// MCBSP_SUBREG_BITWRITE(AFE_MCBSP, SPCR2_SUBADDR, FRST, FRST_SZ, 1);
//
//-------------------------------------------------------------------------------------
// The DMA transfer is now running. We can now return to the main code and wait for
// the transfer-complete interrupt from the DMA engine.
//-------------------------------------------------------------------------------------
//----------------- Start DMAXfer
return;
}
#endif
//==========================================================================================
// Function: FillIdleBuffer()
//
// Description: This function copies data from an integer source buffer to the
// idle buffer in a format compatible with the AFE (Analog Front End).
//
// Revision History:
//==========================================================================================
void FillIdleBuffer(void)
{
u16 i; // Loop counter
u16 temp;
u16* pDest = IdleBuffArray;
static u16 AFEctrl1Old = 0x8000; // Old copy of AFE control var 1
static u16 AFEctrl2Old = 0x8000; // Old copy of AFE control var 2
static i16 IdleArray[IDLE_BUFFER_LEN] = {0,0};
// Fill the idle buffer if either control word has changed
if ( (AFEctrl1 != AFEctrl1Old) || (AFEctrl2 != AFEctrl2Old) )
{
#if COMPILE_MODE == MEX_COMPILE
for(i = 0; i<IDLE_BUFFER_LEN; i++ )
{
*pDest++ = IdleArray[i];
}
#else // DSP_COMPILE
#if (SEND_TWICE == TRUE)
// Transmit three 16-bit values
// Fill Temp Transmit buffer with real data interleaved between control words
// Send same data word twice, with different control words
for(i = 0; i<IDLE_BUFFER_LEN; i++ )
{
temp = IdleArray[i];
*pDest++ = temp;
*pDest++ = (AFEctrl1 << 8) + ((temp>>8)&0x00ff);
*pDest++ = ((temp&0x00ff) << 8) + AFEctrl2;
}
#else // SEND_TWICE == FALSE
// Transmit three 16-bit values
// Fill Temp Transmit buffer with real data interleaved between control words
for(i = 0; i<IDLE_BUFFER_LEN; i+=2 )
{
temp = IdleArray[i]; // Grab first Tx value and send it
*pDest++ = temp;
temp = IdleArray[i+1]; // Spread second Tx value over the next two words
*pDest++ = (AFEctrl1 << 8) + ((temp>>8)&0x00ff);
*pDest++ = ((temp&0x00ff) << 8) + AFEctrl2;
}
#endif
#endif
}
AFEctrl1Old = AFEctrl1;
AFEctrl2Old = AFEctrl2;
return;
}
//==========================================================================================
// Function: FillAFETxBuffCplx()
//
// Description: This function copies data from a complex source buffer to a destination
// buffer while modifying the destination data format to be compatible
// with the AFE (Analog Front End).
//
// Revision History:
//==========================================================================================
TXDATA* FillAFETxBuffCplx(TXDATA* pDest, iCplx* pSrc, u16 uCnt)
#if COMPILE_MODE == MEX_COMPILE
{
u16 i; // Loop counter
for( i = 0; i < uCnt; i++ )
{
*pDest++ = (pSrc++)->re; // Copy the real part of the source into the dest
}
return(pDest);
}
#else
{
u16 i; // Loop counter
i16 temp;
WaitForTxBufferFree(pDest, uCnt); // Wait until DMA is not using destination memory segment
// Transmit three 16-bit values
// Fill Temp Transmit buffer with real data interleaved between control words
for(i = 0; i<(uCnt/2); i++ )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -