📄 dsk5402_dma_ad50.c
字号:
/*
* Copyright 2002 by Texas Instruments Incorporated.
* All rights reserved. Property of Texas Instruments Incorporated.
* Restricted rights to use, duplicate or disclose this code are
* granted through contract.
*
*/
/*
* ======== dsk5402_dma_ad50.c ========
*
* DMA interrupt-driven low-level streaming device driver for TI
* 5402 DSK. Uses the C54x Chip Support Library.
*
* Configuration:
* DMA channel 4 RX
* DMA channel 5 TX
*/
#include <std.h>
#include <csl.h>
#include <csl_dma.h>
#include <csl_mcbsp.h>
#include "dsk5402_dma_ad50.h"
/*
* Public driver setup data object. Used if the user passes NULL as
* setup() argument, or by the user to modify the default parameters.
*/
DSK5402_DMA_AD50_Setup DSK5402_DMA_AD50_SETUP = {
AD50_DEFAULTPARAMS, /* default codec parameters */
};
DMA_Handle C54XX_DMA_MCBSP_hDmaRx;
DMA_Handle C54XX_DMA_MCBSP_hDmaTx;
MCBSP_Handle C54XX_DMA_MCBSP_hMcbsp;
/*
* ======== DSK5402_DMA_AD50_setup ========
*
* Driver setup() function, called by the user after the init() function
* above. Either the address of a driver setup object is passed, or NULL,
* in which case the function will use the default setup object, defined
* above.
* Initializes the DMA, McBSPs connected to the codec, and the codec.
*/
Void DSK5402_DMA_AD50_setup(DSK5402_DMA_AD50_Setup *setup)
{
static Bool curinit = FALSE;
/* CSL to handle the DMA Channels 4 and 5 */
static DMA_Config dmaMcbspRx = {
0x0000, /* Channel Priority (0x0000 or 0x0001) */
DMA_DMMCR_RMK(
DMA_DMMCR_AUTOINIT_OFF,
DMA_DMMCR_DINM_ON,
DMA_DMMCR_IMOD_HALF_AND_FULL,
DMA_DMMCR_CTMOD_ABU,
DMA_DMMCR_SIND_NOMOD, // don't modify src addr.
DMA_DMMCR_DMS_DATA,
DMA_DMMCR_DIND_POSTINC, // post increment dst. addr.
DMA_DMMCR_DMD_DATA
), /* DMMCR */
DMA_DMSFC_RMK(
DMA_DMSFC_DSYN_REVT1,
DMA_DMSFC_DBLW_OFF,
DMA_DMSFC_FRAMECNT_OF(0)
), /* DMSFC */
(DMA_AdrPtr)0x0041,/* Source Address Register (DMSRC) - Numeric */
NULL, /* Destination Address Register (DMDST) - Symbolic */
0x0000 /* Element Count Register (DMCTR) */
};
static DMA_Config dmaMcbspTx = {
0x0000, /* Channel Priority (0x0000 or 0x0001) */
DMA_DMMCR_RMK(
DMA_DMMCR_AUTOINIT_OFF,
DMA_DMMCR_DINM_OFF,
DMA_DMMCR_IMOD_HALF_AND_FULL,
DMA_DMMCR_CTMOD_ABU,
DMA_DMMCR_SIND_POSTINC, // post incr. src. addr.
DMA_DMMCR_DMS_DATA,
DMA_DMMCR_DIND_NOMOD, // don't modify dst address
DMA_DMMCR_DMD_DATA
), /* DMMCR */
DMA_DMSFC_RMK(
DMA_DMSFC_DSYN_XEVT1,
DMA_DMSFC_DBLW_OFF,
DMA_DMSFC_FRAMECNT_OF(0)
), /* DMSFC */
NULL, /* Source Address Register (DMSRC) - Symbolic */
(DMA_AdrPtr)0x0043, /* Destination Address Register (DMDST) */
0x0000 /* Element Count Register (DMCTR) */
};
/* CSL handle to the McBSP1. The McBSP is shared between the two channels */
static MCBSP_Config mcbspCfg0 = {
MCBSP_SPCR1_RMK(
MCBSP_SPCR1_DLB_OFF, /* DLB = 0 */
MCBSP_SPCR1_RJUST_RZF, /* RJUST = 0 */
MCBSP_SPCR1_CLKSTP_DISABLE, /* CLKSTP = 0 */
MCBSP_SPCR1_DXENA_NA, /* DXENA = 0 */
MCBSP_SPCR1_RINTM_FRM, /* RINTM = 2 */
MCBSP_SPCR1_RRST_ENABLE /* RRST = 1 */
),
MCBSP_SPCR2_RMK(
MCBSP_SPCR2_FREE_YES, /* FREE = 1 */
MCBSP_SPCR2_SOFT_NO, /* SOFT = 0 */
MCBSP_SPCR2_FRST_RESET, /* FRST = 0 */
MCBSP_SPCR2_GRST_RESET, /* GRST = 0 */
MCBSP_SPCR2_XINTM_XRDY, /* XINTM = 0 */
MCBSP_SPCR2_XRST_ENABLE /* XRST = 1 */
),
MCBSP_RCR1_RMK(
MCBSP_RCR1_RFRLEN1_OF(0), /* RFRLEN1 = 0 */
MCBSP_RCR1_RWDLEN1_16BIT /* RWDLEN1 = 2 */
),
MCBSP_RCR2_RMK(
MCBSP_RCR2_RPHASE_SINGLE, /* RPHASE = 0 */
MCBSP_RCR2_RFRLEN2_OF(0), /* RFRLEN2 = 0 */
MCBSP_RCR2_RWDLEN2_DEFAULT, /* RWDLEN2 = 0 */
MCBSP_RCR2_RCOMPAND_MSB, /* RCOMPAND = 0 */
MCBSP_RCR2_RFIG_YES, /* RFIG = 0 */
MCBSP_RCR2_RDATDLY_0BIT /* RDATDLY = 0 */
),
MCBSP_XCR1_RMK(
MCBSP_XCR1_XFRLEN1_OF(0), /* XFRLEN1 = 0 */
MCBSP_XCR1_XWDLEN1_16BIT /* XWDLEN1 = 2 */
),
MCBSP_XCR2_RMK(
MCBSP_XCR2_XPHASE_SINGLE, /* XPHASE = 0 */
MCBSP_XCR2_XFRLEN2_OF(0), /* XFRLEN2 = 0 */
MCBSP_XCR2_XWDLEN2_DEFAULT, /* XWDLEN2 = 0 */
MCBSP_XCR2_XCOMPAND_MSB, /* XCOMPAND = 0 */
MCBSP_XCR2_XFIG_YES, /* XFIG = 0 */
MCBSP_XCR2_XDATDLY_0BIT /* XDATDLY = 0 */
),
MCBSP_SRGR1_RMK(
MCBSP_SRGR1_FWID_OF(0), /* FWID = 0 */
MCBSP_SRGR1_CLKGDV_OF(0) /* CLKGDV = 0 */
),
MCBSP_SRGR2_RMK(
MCBSP_SRGR2_GSYNC_FREE, /* FREE = 0 */
MCBSP_SRGR2_CLKSP_RISING, /* CLKSP = 0 */
MCBSP_SRGR2_CLKSM_0, /* CLKSM = 1 */
MCBSP_SRGR2_FSGM_DXR2XSR, /* FSGM = 0 */
MCBSP_SRGR2_FPER_OF(0) /* FPER = 0 */
),
MCBSP_MCR1_DEFAULT,
MCBSP_MCR2_DEFAULT,
MCBSP_PCR_RMK(
MCBSP_PCR_XIOEN_SP, /* XIOEN = 0 */
MCBSP_PCR_RIOEN_SP, /* RIOEN = 0 */
MCBSP_PCR_FSXM_EXTERNAL, /* FSXM = 0 */
MCBSP_PCR_FSRM_EXTERNAL, /* FSRM = 0 */
MCBSP_PCR_CLKXM_INPUT, /* CLKXM = 0 */
MCBSP_PCR_CLKRM_INPUT, /* CLKRM = 0 */
MCBSP_PCR_FSXP_ACTIVELOW, /* FSXP = 1 */
MCBSP_PCR_FSRP_ACTIVELOW, /* FSRP = 1 */
MCBSP_PCR_CLKXP_RISING, /* CLKXP = 0 */
MCBSP_PCR_CLKRP_FALLING /* CLKRP = 0 */
),
MCBSP_RCERA_DEFAULT,
MCBSP_RCERB_DEFAULT,
MCBSP_XCERA_DEFAULT,
MCBSP_XCERB_DEFAULT,
};
static volatile ioport unsigned port04; /* for CPLD CTRL 2 */
if (curinit) {
return;
}
curinit = TRUE;
/* use default parameters if none are given */
if (setup == NULL) {
setup = &DSK5402_DMA_AD50_SETUP;
}
/* Open DMA and MCBSP */
C54XX_DMA_MCBSP_hDmaRx = DMA_open(DMA_CHA4, DMA_OPEN_RESET);
C54XX_DMA_MCBSP_hDmaTx = DMA_open(DMA_CHA5, DMA_OPEN_RESET);
C54XX_DMA_MCBSP_hMcbsp = MCBSP_open(MCBSP_PORT1, MCBSP_OPEN_RESET);
/* Set DMA to continue transfer even during emulation stop */
DMA_FSET(DMPREC, FREE, 1);
/* Setup config for DMA and MCBSP */
DMA_config(C54XX_DMA_MCBSP_hDmaRx, &dmaMcbspRx);
DMA_config(C54XX_DMA_MCBSP_hDmaTx, &dmaMcbspTx);
MCBSP_config(C54XX_DMA_MCBSP_hMcbsp, &mcbspCfg0);
/*
* DSK5402 board setup ...
* Select McBSP1 mapped to Audio Codec (CPLD Register)
* and FC bit = 0 (secondary control off)
*/
port04 &= 0xf5;
/* start the McBSP */
MCBSP_start(C54XX_DMA_MCBSP_hMcbsp, MCBSP_XMIT_START|MCBSP_RCV_START, 0x0);
/* set codec parameters (this will also initialize the codec) */
AD50_setParams( C54XX_DMA_MCBSP_hMcbsp, &(setup->ad50) );
}
/*
* ======== startDma ========
*/
Void startDma(Ptr bufpi, Ptr bufpo, Uns nmaus)
{
/* Program address in appropriate DMA channel and start transfer. */
DMA_RSETH(C54XX_DMA_MCBSP_hDmaRx, DMDST, (Uint16)bufpi);
DMA_RSETH(C54XX_DMA_MCBSP_hDmaRx, DMCTR, (nmaus));
DMA_start(C54XX_DMA_MCBSP_hDmaRx);
/*
* This code serves 2 purposes:
* (1) Prime the Reciever -- DMA won't fire unless it sees
* RRDY but become 1
* (2) Emulator Stop - Catch Condition
* Condition true if DSP is halted and MCBSP provides event to
* DMA while DMA is stopped. Manual read to restart DMA.
*/
if ( MCBSP_rrdy(C54XX_DMA_MCBSP_hMcbsp) ) {
MCBSP_read(C54XX_DMA_MCBSP_hMcbsp);
}
DMA_RSETH(C54XX_DMA_MCBSP_hDmaTx, DMSRC, (Uint16)bufpo + 1); // +1 to align input & output channel, see note below
DMA_RSETH(C54XX_DMA_MCBSP_hDmaTx, DMCTR, (nmaus));
DMA_start(C54XX_DMA_MCBSP_hDmaTx);
/*
* This code serves 2 purposes:
* (1) Prime the Transmitter -- DMA won't fire unless it sees
* XRDY but become 1
* (2) Emulator Stop - Catch Condition
* DMA while DMA is stopped. Manual write to restart DMA.
*/
if ( MCBSP_xrdy(C54XX_DMA_MCBSP_hMcbsp) ) {
MCBSP_write(C54XX_DMA_MCBSP_hMcbsp, 0x0); // note: here we prime the McBSP Tx channel, at the same time
} // the McBSP Rx channel performs the 1st read, via DMA ch4.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -