Hi,
I developed a custom board with the OMAP L138 and a ADC (ADS1278). Now my goal is read the samples from the ADC with a simple serializer and store in the OMAP shared RAM. I'm using the McASP PSPIOM driver and the TTO EDMA3 LLD driver, but i'm thinking that's something wrong in my configuration order.
I just want to read the ADC samples (8chx24bits=128bits per serializer) in continuous mode from the Mcasp directly to the Shared Ram and in the end call a interruption function (TCC).
AHCLK is external (512KHz) -> ADC CLK
ACLK is internal (128KHz) -> ADC SCLK
AFSR is internal (1KHz) -> ADC Frame Sync '''''''''''|__|''''''''''
1- DSP/BIOS UDEV creation:
bios.UDEV.create("MCASP");
bios.UDEV.instance("MCASP").initFxn = prog.extern("MCASP_DevInit");
bios.UDEV.instance("MCASP").fxnTableType = "IOM_Fxns";
bios.UDEV.instance("MCASP").params = prog.extern("MCASP_Params");
bios.UDEV.instance("MCASP").fxnTable = prog.extern("Mcasp_IOMFXNS");
#define McaspReg_PFUNC (0x1E00FFE0u)
#define McaspReg_PDIR (0xA0000000u)
#define McaspReg_GBLCTL (0x0000001Fu)
#define McaspReg_DITCTL (0x00000000u)
#define McaspReg_DLBCTL (0x00000000u)
#define McaspReg_AMUTE (0x00000000u)
#define McaspReg_SRCTLn (0x00000002u)
#define McaspReg_RMASK (0x00FFFFFFu)
#define McaspReg_RFMT (0x000180B0u)
#define McaspReg_AFSRCTL (0x00000492u)
#define McaspReg_RTDM (0x00000010u)
#define McaspReg_RINTCTL (0x00000020u)
#define McaspReg_RSTAT (0x00000000u)
#define McaspReg_REVTCTL (0x00000000u)
#define McaspReg_ACLKRCTL (0x00000023u)
#define McaspReg_AHCLKRCTL (0x00000000u)
void MCASP_DevInit(){
MCASP_Params = Mcasp_PARAMS;
Mcasp_init();
MCASP_Params.enablecache=TRUE;
MCASP_Params.hwiNumber = 8;
//MCASP_Params.isDataBufferPayloadStructure=FALSE;
// Mcasp Hardware setup global structure
//* * * * * * * * * * * * * * * * * *
MCASP_Params.mcaspHwSetup.glb.pfunc= McaspReg_PFUNC;
MCASP_Params.mcaspHwSetup.glb.pdir= McaspReg_PDIR;
MCASP_Params.mcaspHwSetup.glb.ctl= McaspReg_GBLCTL;
MCASP_Params.mcaspHwSetup.glb.ditCtl= McaspReg_DITCTL;
MCASP_Params.mcaspHwSetup.glb.dlbMode= McaspReg_DLBCTL;
MCASP_Params.mcaspHwSetup.glb.amute= McaspReg_AMUTE;
//MCASP_Params.mcaspHwSetup.glb.serSetup[0]= McaspReg_SRCTLn;
//MCASP_Params.mcaspHwSetup.glb.serSetup[1]= McaspReg_SRCTLn;
//MCASP_Params.mcaspHwSetup.glb.serSetup[2]= McaspReg_SRCTLn;
//MCASP_Params.mcaspHwSetup.glb.serSetup[3]= McaspReg_SRCTLn;
MCASP_Params.mcaspHwSetup.glb.serSetup[4]= McaspReg_SRCTLn;
// Mcasp Hardware setup RX data structure
//* * * * * * * * * * * * * * * * * *
MCASP_Params.mcaspHwSetup.rx.mask= McaspReg_RMASK;
MCASP_Params.mcaspHwSetup.rx.fmt= McaspReg_RFMT;
MCASP_Params.mcaspHwSetup.rx.frSyncCtl= McaspReg_AFSRCTL;
MCASP_Params.mcaspHwSetup.rx.tdm= McaspReg_RTDM;
MCASP_Params.mcaspHwSetup.rx.intCtl= McaspReg_RINTCTL;
MCASP_Params.mcaspHwSetup.rx.stat= McaspReg_RSTAT;
MCASP_Params.mcaspHwSetup.rx.evtCtl= McaspReg_REVTCTL;
MCASP_Params.mcaspHwSetup.rx.clk.clkSetupClk= McaspReg_ACLKRCTL;
MCASP_Params.mcaspHwSetup.rx.clk.clkSetupHiClk= McaspReg_AHCLKRCTL;
// MCASP_Params.mcaspHwSetup.rx.clk.clkChk= McaspReg_RCLKCHK;
// Mcasp Hardware setup TX data structure
//* * * * * * * * * * * * * * * * * *
MCASP_Params.mcaspHwSetup.tx.clk.clkSetupClk |= 0x00000040;
}
2 - EDMA3 Config (After main() startup)
Instance ID - 0 | Region - 0 | Channel - 0 | TCC - 0
OPT 0x81100400
SRC 0x01D02000
A_B_CNT 0x00770001
DST 0x11800000
SRC_DST_BIDX 0x00010000
LINK_BCNTRLD 0x0004FFFF
SRC_DST_CIDX 0x00000000
CCNT 0x00000080
edma_object_t EdmaObj = {NULL, // hEdma: handle to be returned by our edma_config function
EDMA3_DRV_DMA_CHANNEL_ANY, // iChannel: use ANY channel (when sync'ing to a peripheral, you need to pick a specific channel)
EDMA3_DRV_TCC_ANY}; // iTcc: use ANY TCC (when sync'ing to a peripheral, you need to pick a specific channel)
EdmaObj.hEdma=NULL;
EdmaObj.iChannel= 0;
EdmaObj.iTcc= EDMA3_DRV_HW_CHANNEL_EVENT_0;
Edma_handler->Config(&EdmaObj);
Edma_handler->CreateChan(&EdmaObj,(0x01D02000) , (0x11800000));
Edma_handler->Start(EdmaObj);
void CCeEDMA3::Config(edma_object_t *EdmaObj)
{
EDMA3_DRV_Result edma3Result = EDMA3_DRV_SOK;
EDMA3_DRV_GblConfigParams *globalConfig = &sampleEdma3GblCfgParams; //set global config to defaults in sample Params (located in bios_edma3_drv_sample_C6455_cfg.c)
EDMA3_RM_MiscParam miscParam; // used in DRV_create() function to specify master/slave
//used for EDMA3_DRV_open() API and initCfg structure, defined in <edma3_drv.h>
EDMA3_DRV_InitConfig initCfg;
EDMA3_DRV_InstanceInitConfig *instanceConfig = &sampleInstInitConfig; // located in bios_edma3_drv_sample_OMAPL138_cfg.c
// Declare Config structure used to initialize the Driver Instance (needed by DRV_open)
initCfg.isMaster = TRUE;
initCfg.regionId = (EDMA3_RM_RegionId)0u; // user must specify region (LLD/DRV does not support "global" region)
initCfg.drvSemHandle = &OsSem; // OsSem added statically in the .tcf file with an initial count of 1
initCfg.drvInstInitConfig = instanceConfig; // device-specific configuration - resources owned by region 1
initCfg.gblerrCb = NULL; // callback function to catch channel controller errors such as TCC error, queue threshold exceeded, etc.
initCfg.gblerrData = NULL; // any data required by the error callback function
miscParam.isSlave = FALSE; //ARM + DSP, specify who is the master, single-chip = use FALSE
// EDMA3 Driver Create (called only once for each EDMA3 hardware instance)
edma3Result = EDMA3_DRV_create(edma3InstanceId, globalConfig, (void *)&miscParam);
// Open user instance to EDMA Module (hEdma)
EdmaObj->hEdma = EDMA3_DRV_open (edma3InstanceId, &initCfg, &edma3Result); // LFM: (void *) &initCfg
}
void CCeEDMA3::CreateChan(edma_object_t *EdmaObj, unsigned int Src, unsigned int Dst)
{
EDMA3_DRV_Result edma3Result = EDMA3_DRV_SOK; // return value for some driver calls so they can return an error
EDMA3_DRV_PaRAMRegs currentParam; // used for debug purposes in EDMA3_DRV_getPaRAM()
EDMA3_RM_EventQueue eventQ = 0; // both used below in _requestChannel()
EDMA3_RM_TccCallback tccCb = 0;
edma3Result = EDMA3_DRV_requestChannel (EdmaObj->hEdma,
&EdmaObj->iChannel, &EdmaObj->iTcc, eventQ, tccCb, NULL);
EDMA3_DRV_setSrcParams (EdmaObj->hEdma, EdmaObj->iChannel, Src, EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W128BIT);
EDMA3_DRV_setDestParams (EdmaObj->hEdma, EdmaObj->iChannel, Dst, EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W128BIT);
EDMA3_DRV_setSrcIndex(EdmaObj->hEdma, EdmaObj->iChannel, 0, 0);
EDMA3_DRV_setDestIndex(EdmaObj->hEdma, EdmaObj->iChannel, 1, 0);
EDMA3_DRV_setTransferParams(EdmaObj->hEdma, EdmaObj->iChannel, 1,128,128,4,EDMA3_DRV_SYNC_A);
EDMA3_DRV_setOptField (EdmaObj->hEdma,EdmaObj->iChannel, EDMA3_DRV_OPT_FIELD_TCINTEN, EDMA3_DRV_TCINTEN_EN);
EDMA3_DRV_setOptField (EdmaObj->hEdma,EdmaObj->iChannel, EDMA3_DRV_OPT_FIELD_TCC, 0u);
// For debug purposes, get currentParam set so that we can add it to a watch window for debug
EDMA3_DRV_getPaRAM(EdmaObj->hEdma, EdmaObj->iChannel, ¤tParam);
}
void CCeEDMA3::Start(edma_object_t EdmaObj)
{
EDMA3_DRV_Result edma3Result = EDMA3_DRV_SOK;
edma3Result = EDMA3_DRV_enableTransfer(EdmaObj.hEdma, EdmaObj.iChannel, EDMA3_DRV_TRIG_MODE_EVENT);
}
Questions:
Can I build the McASP library without -DMcasp_EDMA_ENABLE and use the TTO EDMA LLB Library with McASP at same time?
Do I need to create and use DIO and SIO API's with McASP Driver?
How I can see the McASP AREVT? How I know that EDMA3 see the event?
What is the right EDMA configuration for McASP receive events? (Is the channel and TCC right?)
How I configure the EDMA TCC interrupt in Bios witout use the ECM Events?
Regards,
Luis Mendes