Hello,
my problem is close to this one : http://e2e.ti.com/support/embedded/tirtos/f/355/t/117092.aspx.
First, my configuration is "OMAP L138 with PSP drivers 1.30.01"
The DSP drives 4 stereo ADCs (PCM1803A) . They communicate in I2S through McASP.
ADCs are slaves and send data on 24bits.
Acquisition works fine except about every tenth startup, left channels (odd) and right channels (even) are swapped : chan1 <-> chan2, chan3 <-> chan4 ...
Swap doesn't seem to change during runtime, only at startup.
Here is my McASP configuration :
===================================================================================
#define NO_CHANNELS 8 #define MCASP_SIZE_BUFFER 2048 #define NO_BUFFERS 3 static Mcasp_HwSetupData sMcaspSetup = { .mask = 0x00FFFFFF, .fmt = ( CSL_MCASP_RFMT_RDATDLY_1BIT << CSL_MCASP_RFMT_RDATDLY_SHIFT ) | ( CSL_MCASP_RFMT_RRVRS_MSBFIRST << CSL_MCASP_RFMT_RRVRS_SHIFT ) | ( CSL_MCASP_RFMT_RPAD_RPBIT << CSL_MCASP_RFMT_RPAD_SHIFT ) | ( 23 << CSL_MCASP_RFMT_RPBIT_SHIFT ) | ( CSL_MCASP_RFMT_RSSZ_24BITS << CSL_MCASP_RFMT_RSSZ_SHIFT ) | ( CSL_MCASP_RFMT_RBUSEL_VBUSP << CSL_MCASP_RFMT_RBUSEL_SHIFT ) | ( CSL_MCASP_RFMT_RROT_NONE << CSL_MCASP_RFMT_RROT_SHIFT ) , .frSyncCtl = ( CSL_MCASP_AFSRCTL_RMOD_I2S << CSL_MCASP_AFSRCTL_RMOD_SHIFT ) | ( CSL_MCASP_AFSRCTL_FRWID_WORD << CSL_MCASP_AFSRCTL_FRWID_SHIFT ) | ( CSL_MCASP_AFSRCTL_FSRM_INTERNAL << CSL_MCASP_AFSRCTL_FSRM_SHIFT ) | ( CSL_MCASP_AFSRCTL_FSRP_FALLINGEDGE << CSL_MCASP_AFSRCTL_FSRP_SHIFT) , .tdm = 0x00000003, .intCtl = ( CSL_MCASP_RINTCTL_RSTAFRM_DISABLE << CSL_MCASP_RINTCTL_RSTAFRM_SHIFT ) | ( CSL_MCASP_RINTCTL_RDATA_DISABLE << CSL_MCASP_RINTCTL_RDATA_SHIFT ) | ( CSL_MCASP_RINTCTL_RLAST_DISABLE << CSL_MCASP_RINTCTL_RLAST_SHIFT ) | ( CSL_MCASP_RINTCTL_RDMAERR_DISABLE << CSL_MCASP_RINTCTL_RDMAERR_SHIFT ) | ( CSL_MCASP_RINTCTL_RCKFAIL_DISABLE << CSL_MCASP_RINTCTL_RCKFAIL_SHIFT ) | ( CSL_MCASP_RINTCTL_RSYNCERR_DISABLE << CSL_MCASP_RINTCTL_RSYNCERR_SHIFT) | ( CSL_MCASP_RINTCTL_ROVRN_DISABLE << CSL_MCASP_RINTCTL_ROVRN_SHIFT ) , .stat = 0x000001FF, // RSTAT reset any existing status bits .evtCtl = ( CSL_MCASP_REVTCTL_RDATDMA_ENABLE << CSL_MCASP_REVTCTL_RDATDMA_SHIFT) , { // Diviseur pour AHCLKR : 24 MHz(AUXCLK) / 384(PCM1803) / 62.5kHz = 1 .clkSetupHiClk = ( CSL_MCASP_AHCLKRCTL_HCLKRM_INTERNAL << CSL_MCASP_AHCLKRCTL_HCLKRM_SHIFT ) | ( CSL_MCASP_AHCLKRCTL_HCLKRP_NOTINVERTED << CSL_MCASP_AHCLKRCTL_HCLKRP_SHIFT) | ( 0 << CSL_MCASP_AHCLKRCTL_HCLKRDIV_SHIFT ) , // Div par 1 // Diviseur pour ACLKR : 24 MHz (AHCLKR) / 48 bits / 62.5kHz = 8 .clkSetupClk = // ( CSL_MCASP_ACLKRCTL_CLKRP_RISINGEDGE << CSL_MCASP_ACLKRCTL_CLKRP_SHIFT ) | ( CSL_MCASP_ACLKRCTL_CLKRM_INTERNAL << CSL_MCASP_ACLKRCTL_CLKRM_SHIFT ) | ( 7 << CSL_MCASP_ACLKRCTL_CLKRDIV_SHIFT ) , // Div par 8 .clkChk = 0 } }; /// Paramètres du canal McASP Mcasp_ChanParams mcaspChanParams = { .noOfSerRequested = 4, // number of serializers .indexOfSersRequested = { Mcasp_SerializerNum_9, Mcasp_SerializerNum_10, Mcasp_SerializerNum_11, Mcasp_SerializerNum_12, }, .mcaspSetup = &sMcaspSetup, .isDmaDriven = TRUE, .channelMode = Mcasp_OpMode_TDM, // TDM MODE .wordWidth = Mcasp_WordLength_24, // word width .userLoopJobBuffer = NULL, .userLoopJobLength = 0, .edmaHandle = 0, .gblCbk = sMcAspErr, .noOfChannels = 2, .dataFormat = Mcasp_BufferFormat_MULTISER_MULTISLOT_SEMI_INTERLEAVED_1, .enableHwFifo = TRUE, .isDataPacked = FALSE }; #pragma DATA_ALIGN(sMcaspBuffer, CACHE_ALIGN); static int sMcaspBuffer[NO_BUFFERS][MCASP_SIZE_BUFFER*NO_CHANNELS]; Mcasp_Params mcaspParams; /** * Initialize driver */ void user_mcAspDrvInit() { Mcasp_init(); mcaspParams = Mcasp_PARAMS; mcaspParams.hwiNumber = 8; mcaspParams.pscPwrmEnable = FALSE; // Configure le mode asynchrone sinon AFSR n'est pas commandé mcaspParams.mcaspHwSetup.tx.clk.clkSetupClk = 0x40; } /** * Create SIO */ static void sMcAspBoot() { SIO_Attrs sioAttrs; mcaspChanParams.edmaHandle = hEdma[0]; sioAttrs = SIO_ATTRS; sioAttrs.nbufs = NO_BUFFERS; // Ping-pong sioAttrs.align = CACHE_ALIGN; // Optimisation avec le cache sioAttrs.model = SIO_ISSUERECLAIM; // Driver plus léger sHw.audio = SIO_create("/dioMcasp", SIO_INPUT, MCASP_SIZE_BUFFER*NO_CHANNELS*sizeof(int), &sioAttrs); assert( sHw.audio); SIO_ctrl(sHw.audio, Mcasp_IOCTL_STOP_PORT, 0); } /** * Start acquisition */ void startMcAsp() { int i; for(i=0;i<NO_BUFFERS;++i) { giveBuf(sMcaspBuffer[i]); } SIO_ctrl(sHw.audio, Mcasp_IOCTL_START_PORT, 0); } int* waitBuf() { int* buf; int retour; retour = SIO_reclaim(sHw.audio, (Ptr*)&buf, 0); assert(retour == MCASP_SIZE_BUFFER*NO_CHANNELS*sizeof(int)); return buf; } void giveBuf(int* buf) { int retour; assert(((unsigned int)buf)%CACHE_ALIGN == 0); retour = SIO_issue(sHw.audio, buf, MCASP_SIZE_BUFFER*NO_CHANNELS*sizeof(int), 0); assert(retour == SYS_OK); }
I tried to set userLoopJobLength to "no_of_ser=4" x "no_of_slots=2" x "size_of_slot=4" = 32, but that doesn't solve my problem.
Do I do anything wrong during initialization ?
Thanks for your help,
Romain
Edit 1 : Before calling SIO_create, AFSR is not driven. After calling SIO_create, AFSR is driven at 24MHz ! It is finaly driven at 62.5kHz only after sending Mcasp_IOCTL_START_PORT. Is it the standard behaviour ?