📄 evm_app.c
字号:
/* The eighth register of CODEC determine the Codec sample rate
* Refrence the following table:
* Sample Rate REG VALUE
* ---------------------------------------------
* 96KHz 0X001D/0X009D
* 48KHz 0X0001/0X0081
* 44.1KHz 0X0023/0X00A3
* 32KHz 0X0019/0X0099
* 24KHz 0X0041/0X00C1
* 16KHz 0X0059/0X00D9
* 8KHz 0X000D/0X008D
* ----------------------------------------------
*/
/*
* Data buffer declarations - the program uses four logical buffers of size
* BUFFSIZE, one ping and one pong buffer on both receive and transmit sides.
*/
#pragma DATA_SECTION (gBufferXmtPing, "buffer_sect");
Int16 gBufferXmtPing[BUFFSIZE]; // Transmit PING buffer
#pragma DATA_SECTION (gBufferXmtPong, "buffer_sect");
Int16 gBufferXmtPong[BUFFSIZE]; // Transmit PONG buffer
#pragma DATA_SECTION (gBufferRcvPing, "buffer_sect");
Int16 gBufferRcvPing[BUFFSIZE]; // Receive PING buffer
#pragma DATA_SECTION (gBufferRcvPong, "buffer_sect");
Int16 gBufferRcvPong[BUFFSIZE]; // Receive PONG buffer
/* Event IDs, global so they can be set in initIrq() and used everywhere */
Uint16 eventIdRcv;
Uint16 eventIdXmt;
Int32 count = 0;
void blinkLED()
{
/* Toggle LED #2 and #3 */
EVM5502_LED_toggle(2);
EVM5502_LED_toggle(3);
}
void blinkLED0()
{
/* Check DIP switch #0 and light LED #0 accordingly, 0 = switch pressed */
if (EVM5502_DIP_get(0) == 0)
/* Switch pressed, togglw LED #0 */
EVM5502_LED_toggle(0);
else
/* Switch not pressed, turn LED #0 off */
EVM5502_LED_off(0);
}
/* ------------------------Helper Functions ----------------------------- */
/*
* initMcbsp() - Initialize the McBSP for codec data transfers using the
* configuration define at the top of this file.
*/
void initMcbsp()
{
/* Open the codec data McBSP */
hMcbsp1 = MCBSP_open(MCBSP_PORT1, MCBSP_OPEN_RESET);
/* Configure the codec to match the AIC23 data format */
MCBSP_config(hMcbsp1, &mcbspCfg1);
/* Clear any garbage from the codec data port */
if (MCBSP_rrdy(hMcbsp1))
MCBSP_read16(hMcbsp1);
/* Start the McBSP running */
MCBSP_start(hMcbsp1, MCBSP_XMIT_START | MCBSP_RCV_START |
MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC, 220);
}
/*
* initIrq() - Initialize and enable the DMA receive interrupt using the CSL.
* The interrupt service routine for this interrupt is hwiDma.
*/
void initIrq(void)
{
// Get Event ID associated with DMA channel interrupt. Event IDs are a
// CSL abstraction that lets code describe a logical event that gets
// mapped to a real physical event at run time. This helps to improve
// code portability.
eventIdRcv = DMA_getEventId(hDmaRcv);
eventIdXmt = DMA_getEventId(hDmaXmt);
// Clear any pending receive channel interrupts (IFR)
IRQ_clear(eventIdRcv);
IRQ_clear(eventIdXmt);
// Enable receive DMA interrupt (IMR)
IRQ_enable(eventIdRcv);
// Make sure global interrupts are enabled
IRQ_globalEnable();
}
/*
* initDma() - Initialize the DMA controller.
*/
void initDma(void)
{
volatile Int16 i;
/* Set transmit and receive buffer addresses in config structures */
dmaCfgReceive.dmacdsal = (DMA_AdrPtr)(((Uint32)(&gBufferRcvPing) << 1) & 0xFFFF);
dmaCfgReceive.dmacdsau = (Uint16)((Uint32)(&gBufferRcvPing) >> 15);
dmaCfgTransmit.dmacssal = (DMA_AdrPtr)(((Uint32)(&gBufferXmtPing) << 1) & 0xFFFF);
dmaCfgTransmit.dmacssau = (Uint16)((Uint32)(&gBufferXmtPing) >> 15);
/* Open DMA channels */
hDmaXmt = DMA_open(DMA_CHA5, DMA_OPEN_RESET);
hDmaRcv = DMA_open(DMA_CHA4, DMA_OPEN_RESET);
/* Configure DMA channels */
DMA_config(hDmaXmt, &dmaCfgTransmit);
DMA_config(hDmaRcv, &dmaCfgReceive);
/* Clear the DMA status registers to receive new interrupts */
i = DMA_RGETH(hDmaRcv, DMACSR);
i = DMA_RGETH(hDmaXmt, DMACSR);
DMA_RSET(DMAGCR, 0x4);
/* Clear any garbage from the codec data port */
if (MCBSP_rrdy(hMcbsp1))
MCBSP_read16(hMcbsp1);
// Start the DMA
DMA_start(hDmaRcv);
DMA_start(hDmaXmt);
}
/*
* copyData() - Copy one buffer with length elements to another.
*/
void copyData(Int16 *inbuf, Int16 *outbuf, Int16 length)
{
Int16 i = 0;
for (i = 0; i < length; i++) {
outbuf[i] = inbuf[i];
}
}
/* ------------------------------- Threads ------------------------------ */
/*
* processBuffer() - Process audio data once it has been received.
*/
void processBuffer(void)
{
Uint32 addr;
Int16 pingPong;
// Wait until transmit DMA is finished too
// while(!IRQ_test(eventIdXmt));
// Pong-pong state passed through mailbox from dmaHwi()
pingPong = SWI_getmbox();
// Determine which ping-pong state we're in
if (pingPong == PING)
{
copyData(gBufferRcvPing, gBufferXmtPing, BUFFSIZE);
// Configure the receive channel for ping input data
addr = ((Uint32)gBufferRcvPing) << 1;
DMA_RSETH(hDmaRcv, DMACDSAL, addr & 0xffff);
DMA_RSETH(hDmaRcv, DMACDSAU, (addr >> 16) & 0xffff);
// Configure the transmit channel for ping output data
addr = ((Uint32)gBufferXmtPing) << 1;
DMA_RSETH(hDmaXmt, DMACSSAL, addr & 0xffff);
DMA_RSETH(hDmaXmt, DMACSSAU, (addr >> 16) & 0xffff);
}
else {
copyData(gBufferRcvPong, gBufferXmtPong, BUFFSIZE);
// Configure the receive channel for pong input data
addr = ((Uint32)gBufferRcvPong) << 1;
DMA_RSETH(hDmaRcv, DMACDSAL, addr & 0xffff);
DMA_RSETH(hDmaRcv, DMACDSAU, (addr >> 16) & 0xffff);
// Configure the transmit channel for pong output data
addr = ((Uint32)gBufferXmtPong) << 1;
DMA_RSETH(hDmaXmt, DMACSSAL, addr & 0xffff);
DMA_RSETH(hDmaXmt, DMACSSAU, (addr >> 16) & 0xffff);
}
// Start the DMA
DMA_start(hDmaRcv);
DMA_start(hDmaXmt);
if ( MCBSP_xrdy(hMcbsp1) )
MCBSP_write16(hMcbsp1, 0);
// MCBSP_read16(hMcbsp1);
}
/* ---------------------- Interrupt Service Routines -------------------- */
/*
* dmaHwi() - Interrupt service routine for the DMA transfer. It is triggered
* when a DMA complete receive frame has been transferred. The
* dmaHwi ISR is inserted into the interrupt vector table at
* compile time through a setting in the DSP/BIOS configuration
* under Scheduling --> HWI --> HWI_INT9. dmaHwi uses the DSP/BIOS
* Dispatcher to save register state and make sure the ISR
* co-exists with other DSP/BIOS functions.
*/
void dmaHwi(void)
{
// Ping-pong state. Initialized to PING initially but declared static so
// contents are preserved as dmaHwi() is called repeatedly like a global.
static Int16 pingOrPong = PING;
// Determine if current state is PING or PONG
if (pingOrPong == PING) {
// Post SWI thread to process PING data
SWI_or(&processBufferSwi, PING);
// Set new state to PONG
pingOrPong = PONG;
}
else {
// Post SWI thread to process PONG data
SWI_or(&processBufferSwi, PONG);
// Set new state to PING
pingOrPong = PING;
}
// Read the DMA status register to clear it so new interrupts will be seen
DMA_RGETH(hDmaRcv, DMACSR);
count++;
}
/* --------------------------- main() function -------------------------- */
/*
* main() - The main user task. Performs application initialization and
* starts the data transfer.
*/
void main()
{
Int16 i;
// Initialize the board support library, must be called first
EVM5502_init();
/* Initialize the LED and DIP switch modules of the BSL */
EVM5502_LED_init();
EVM5502_DIP_init();
// EVM5502_LCD_init();
// Clear buffers
memset((void *)gBufferXmtPing, 0, BUFFSIZE * 4);
AIC23_setParams(&config); // Configure the codec
IRQ_globalDisable(); // Disable global interrupts during setup
initDma(); // Initialize the EDMA controller
initMcbsp(); // Initialize McBSP1 for audio transfers
if (MCBSP_rrdy(hMcbsp1))
MCBSP_read(hMcbsp1);
if (MCBSP_xrdy(hMcbsp1))
MCBSP_write(hMcbsp1, 0x0);
initIrq(); // Initialize interrupts
IRQ_globalEnable(); // Re-enable global interrupts
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -