This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EDMA and McASP and FIFO on C6748

Other Parts Discussed in Thread: OMAP-L138

I have used EDMA3 on MCASP and RFIFO to acquire and sorts 4 channels coming from an ADC. The signal is stored in 2 buffers in flip flop mode. This works properly

Now, I want to use the EDMA on the same application to send data to a stereo DAC and using the WFIFO. And it does not work. The transmitter raiseserrors as if the WFIFO was never filled. To write by DMA in the WFIFO I use the same adress as for the RFIFO (0x01D02000). Is it Ok?

I have tried to force the 1st DMA transfer by setting the relevant bit int the ESR but nothing happens

I have tried also to write 1 time ine XBUF4 (transmitter that I used) at start of transmit but it does not change anything

My initializations for TX are described here :

  //------ CONFIGURATION FOR TX

  //program use of fifo

  //Bit 16 : XENA : 0 Read fifo is disabled before programmaing

  //Bit 15-8 : XNUMEVT : 2 Read word count per DMA event.

  //           When receive fifo contains 8 words then an AREVT (receive DMA event) is generated

  //Bits 7-0 : XNUMDMA : 1 : Read word count per transfer 1 because only 1 serializer is active

  aMcASPFifoRegs->WFIFOCTL =  ((NB_CHANNEL_TX)<<8) | 1;

  //Enable Tx FIFO

  CSL_FINST(aMcASPFifoRegs->WFIFOCTL, AFIFO_WFIFOCTL_WENA, ENABLED);

  while ((aMcASPFifoRegs->WFIFOCTL & CSL_AFIFO_WFIFOCTL_WENA_MASK)!= CSL_AFIFO_WFIFOCTL_WENA_MASK);

 

  // Transmit format unit bit mask register : all the bits are transfered

  MCASP->XMASK      = 0xFFFFFFFF;

 

  // Transmit bit stream format register

  // Bits 0 à 2 : 000 XROT (right rotation value for receive) : no rotation

  // Bit 3 :0 XBUSEL (select whether write to peripheral configuration port or DMA port) : write to DMA port

  // Bits 4 à 7 : 1111 : XSSZ(transmit slot size) : 24 bits

  // Bits 8 à 12 : 00000 : XPBIT (bit used to pad the extra bits) : 0

  // Bits 13 à 14 : 00 XPAD (Pad value for extra bits not belonging to the word) : 0

  // Bit 15 : 1 XRVRS (Transmit serial bitstream order) : bitstream in MSB first

  // Bits 16-17 : 00 XDATDLY (Transmit bit delay) : 0 bit delay between frame sync and receive data bit

  // Bits 18-31 : 0 Reserved

  MCASP->XFMT       = 0x000080F0;              // MSB first, align left, slot=32bits, 0-bit delay, no rotation

 

  // Receive Frame sync control register

  //Bit 0 : 0 FSXP (transmit frame sync polarity) rising edge on frame sync

  //Bit 1 : 1 FSXM (receive frame sync generation) internally generated transmit frame sync

  //Bit 2-3 : 00 Reserved

  //Bit 4 : 1 FXWID (Transmit frame sync width select bit) : single word

  //Bits 5-6 : 00 Reserved

  //Bits 7 to 15 : 2 XMOD (transmit frame sync mode select) 2 slot TDM

  //Bits 16 to 31 : reserved

  MCASP->AFSXCTL    = 0x00000112;

 

  //Transmit clock control register

  //Bits 0 à 4 : 00011 CLKXDIV (Transmit bit clock divide ratio from AHCLKR to ACLKR) Divide by 4

  //Bit 5 : 1 CLKXM (Transmit bit clock source) Internal

  //Bit 6 : 1 ASYNC : Separate clock and frame sync used bu transmitter and receiver

  //Bit 7 : 1 CLKXP (Transmit bit stream clock polarity) : shift out data on falling edge of serial clock

  //Bits 8 to 31 : reserved

  MCASP->ACLKXCTL   = 0x000000E3;              // rising edge, clkrm external, /1 CLKRDIV

 

  //Transmit high frequency clock control register

  //Bits 0 à 11 : 0 HCLKXDIV (Receive high frequency divide ratio from AUXCLK to AHCLKX) : 1

  //Bits 12-13 : reserved

  //Bits 14 : 0 HCLKXP (receive bitstream high frequency clock polarity) not inverted

  //Bit 15 : 0 HCLKXM (receive high frequency clock source) external source

  //bits 16 to 31 : reserved

  MCASP->AHCLKXCTL  = 0x00000000;

 

  //transmit TDM time slot register

  //Masks the time slot to transmit : 0 & 1

  MCASP->XTDM       = 0x00000003;

 

  //Transmit interrupt control register

  MCASP->XINTCTL    = 0x00000000; // disabled because we use DMA

 

  //transmit clock check control register

  //Bits 0 to 3 : 0010 XPS (transmit clock check prescaler value): McASP system clock divided by 4

  //Bits 4 to 7 : reserved

  //Bits 8 to 15 : 0 XMIN (transmit clock minimum boundary) 0

  //Bits 16 to 23 : FF XMAX (transmit clock maximum boundary)

  //Bits 24 to 31 : 0 XCNT (transmit clock count value)

  MCASP->XCLKCHK    = 0x00FF0002;

 

  //Enable the transmitter to the DAC

  MCASP->SRCTL4    = 0x0009;

 

 

    //Configure DMA for Tx

    //It can be done 1 time at creation of McASP but we do not have pointers on Tx buffer

    EDMA_ConfigureMcASPTx(m_poOutputBuffer, (int *)m_poOutputBuffer->GetAdressElement(0), (int *)m_poOutputBuffer->GetAdressElement(1), SIZE_BLOCK_AUDIO);

 

    //Enable the audio clocks, verifying each bit is properly set.

    SETBIT(MCASP->XGBLCTL, XHCLKRST);

    while (!CHKBIT(MCASP->XGBLCTL, XHCLKRST)) {}

 

    SETBIT(MCASP->XGBLCTL, XCLKRST);

    while (!CHKBIT(MCASP->XGBLCTL, XCLKRST)) {}

 

    //Start DMA

    EDMA_StartMcASPTx();

 

    //Clear all the status bits

    MCASP->XSTAT = 0x0000FFFF;        // Clear all

 

    //Activate the serializer

    SETBIT(MCASP->XGBLCTL, XSRCLR);

    while (!CHKBIT(MCASP->XGBLCTL, XSRCLR)) {}

 

    if(CHKBIT(MCASP->XSTAT, XDATA))

    {

      MCASP->XBUF4 = 0;

    }

   

    //Reset the state machine of transmitter

    SETBIT(MCASP->XGBLCTL, XSMRST);

    while (!CHKBIT(MCASP->XGBLCTL, XSMRST)) {}

 

    //Reset frame sync generator

    SETBIT(MCASP->XGBLCTL, XFRST);

    while (!CHKBIT(MCASP->XGBLCTL, XFRST)) {}

 

The class EDMA  constructor realizes the following initializations

 

  //Use DMA control channel 0

  aEdmaccRegs = (CSL_Edma3ccRegsOvly)(CSL_EDMA30CC_0_REGS);

  //McASP0 Control Registers

  mcaspRegs = (CSL_McaspRegsOvly) CSL_MCASP_0_CTRL_REGS;  //OMAP-L138 McASP Configuration Register Pointer Instance

 

  //McASP AFIFO Control Registers

  afifoRegs = (CSL_AfifoRegsOvly) CSL_MCASP_0_FIFO_REGS;

 

  //McASP DMA Port Registers

  adataRegs = (CSL_AdataRegsOvly) CSL_MCASP_0_DATA_REGS;

 

  // Write EMCR, CCEERCLR, ECR registers to clear the EMR, CCERR, ER

  //  EMCR =  0xFFFFFFFF;  CCERRCLR = 0xFFFFFFFF;     ECR = 0xFFFFFFFF;

  // Clear all the Event in the event Register

  // Disable all the events

  aEdmaccRegs->EECR  = 0xffffffff; // clear events  0 -> 31

  aEdmaccRegs->ECR  = 0xffffffff; // clear events  0 -> 31

  // Clear all the events in the secondary Event Register

  aEdmaccRegs->SECR = 0xffffffff; // clear secondary events  0 -> 31

  //Clear all the events in the event interrupt enable register

  aEdmaccRegs->IECR = 0xffffffff; // disable all interrupts

  //Clear all the pending interrupts

  aEdmaccRegs->ICR  = 0xffffffff; // clear all pending interrupts

 

  // We use shadow region 1 because it it is this region which is linked to interruption

  // and we use DMA 0 and 1

  // Enable Channel 0 - 1 to DSP (Region 1 )

  aEdmaccRegs->DRA[CSL_EDMA3_REGION_1].DRAE =

      CSL_FMKT(EDMA3CC_DRAE_E0, ENABLE)|

      CSL_FMKT(EDMA3CC_DRAE_E1, ENABLE);

 

  // Assign Channel 0 - 1 to Queue 0

  aEdmaccRegs->DMAQNUM[1] =

      CSL_FMKT(EDMA3CC_DMAQNUM_E0, Q0) |

      CSL_FMKT(EDMA3CC_DMAQNUM_E1, Q0);

 

Then, the following method configures he DMA

 

void EDMA::ConfigureMcASPTx(TypeFifoOfBlocksOutputAudio* poOutputBuffer, int * piBufOutputPing, int * piBufOutputPong, int iSizeBlock)

{

  // Save pointer on circular buffer to increment index after each DMA read

  m_poOutputBuffer =  poOutputBuffer;

 

  CSL_FINST(aEdmaccRegs->EECR, EDMA3CC_EECR_E1, CLEAR);

  CSL_FINST(aEdmaccRegs->ECR, EDMA3CC_ECR_E1, CLEAR);

  CSL_FINST(aEdmaccRegs->SECR, EDMA3CC_SECR_E1, CLEAR);

  CSL_FINST(aEdmaccRegs->IECR, EDMA3CC_IECR_I1, CLEAR);

  CSL_FINST(aEdmaccRegs->ICR, EDMA3CC_ICR_I1, CLEAR);

 

  // Initialize PaRAM Transfer Context for Events 1 (Tx)

  InitializeParamMcASPTxEvent1(piBufOutputPing, piBufOutputPong, iSizeBlock);

 

  Task_sleep(20); // if no wait minimum 20 sometimes does not start : 0 in the buffer received by DMA

 

}

 

void EDMA::InitializeParamMcASPTxEvent1 (int * piBufOutputPing, int * piBufOutputPong, int iSizeBlock)

{

 

  // Reset EDMA PaRAM OPT Register

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].OPT = CSL_EDMA3CC_OPT_RESETVAL;

 

  // Config PaRAM OPT

  // Intermediate transfer compete interrupt disable

  // Transfer complete chaining disable

  // Intermediate transfer completion interrupt disable

  // Transfer complete interrupt enable

  // Transfer complete code : 0 unused

  // Transfer complete code mode 0 : A transfer is complete after the data has been transfered

  // FIFO width : 8 bits

  // STATIC : 0 PaRAM set is not static. ParAm is updated or linked after Tr is submitted

  // SYNCDIM : 1 AB synchronized because we use FIFO of McASP

  // DAM : destination adress mode : 0 non constant addressing mode because not supported by C674x

  // SAM : source adress mode : 0 non constant addressing mode because not supported by C674x

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].OPT =

      CSL_FMKT(EDMA3CC_OPT_TCINTEN, ENABLE)   |

      CSL_FMKT(EDMA3CC_OPT_SYNCDIM, ABSYNC)    |

      CSL_FMK(EDMA3CC_OPT_TCC, EDMA_EVENT1);

 

  // Initialize EDMA Event Src (Adress of RFIFO) and Dst Addresses (input pointer)

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].DST = (Uint32) piBufOutputPing;

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC = CSL_MCASP_0_DATA_REGS;

 

  // Set EDMA Event PaRAM A,B,C CNT

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].A_B_CNT =

      CSL_FMK(EDMA3CC_A_B_CNT_ACNT, NUMBER_OF_BYTES_PER_SAMPLE) |  //0004h

      CSL_FMK(EDMA3CC_A_B_CNT_BCNT, NB_CHANNEL_TX); //2 arrays (channels) in a frame

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].CCNT = iSizeBlock; // Size of a block = 32

 

  // Set EDMA Event PaRAM SRC/DST BIDX

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC_DST_BIDX =

      CSL_FMK(EDMA3CC_SRC_DST_BIDX_SRCBIDX,  (iSizeBlock*NUMBER_OF_BYTES_PER_SAMPLE)) |   // The source address between 2 channel is incremented from sizeBlock*4

      CSL_FMK(EDMA3CC_SRC_DST_BIDX_DSTBIDX, 0); //The destination adress is always the same

 

  // Set EDMA Event PaRAM SRC/DST CIDX

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC_DST_CIDX =

      CSL_FMK(EDMA3CC_SRC_DST_CIDX_SRCCIDX, NUMBER_OF_BYTES_PER_SAMPLE) |   // after each read of a sample we go to the next sample, 4 bytes later

      CSL_FMK(EDMA3CC_SRC_DST_CIDX_DSTCIDX, 0); //the destination is always the same the WFIFO

 

  // Set EDMA Event PaRAM LINK to param 34 and BCNTRLD

  aEdmaccRegs->PARAMSET[EDMA_EVENT1].LINK_BCNTRLD =

      CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34] & 0xFFFFu);

 

 

  //**************   Parameter Set 34  *******************//

  //The parameters are identical of those of channel 1

 

  // Reset EDMA PaRAM OPT Register

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].OPT = CSL_EDMA3CC_OPT_RESETVAL;

 

  // Config PaRAM OPT (Identical of parameters of channel 0

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].OPT = aEdmaccRegs->PARAMSET[EDMA_EVENT1].OPT ;

 

  // Initialize EDMA Event Src and Dst Addresses

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].SRC = aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC;

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].DST = (Uint32) piBufOutputPong;

 

  // Set EDMA Event PaRAM A,B,C CNT

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].A_B_CNT = aEdmaccRegs->PARAMSET[EDMA_EVENT1].A_B_CNT;

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].CCNT = aEdmaccRegs->PARAMSET[EDMA_EVENT1].CCNT;

 

  // Set EDMA Event PaRAM SRC/DST BIDX

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].SRC_DST_BIDX = aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC_DST_BIDX;

 

  // Set EDMA Event PaRAM SRC/DST CIDX

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].SRC_DST_CIDX = aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC_DST_CIDX;

 

  // Set EDMA Event PaRAM LINK and BCNTRLD

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34].LINK_BCNTRLD =

      CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35] & 0xFFFFu); // |   // CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64] & 0xFFFFu) |

 

 

  //**************   Parameter Set 35  *******************//

  //The parameters are identical of those of channel 1

 

  // Reset EDMA PaRAM OPT Register

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].OPT = CSL_EDMA3CC_OPT_RESETVAL;

 

  // Config PaRAM OPT (Identical of parameters of channel 0

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].OPT = aEdmaccRegs->PARAMSET[EDMA_EVENT1].OPT ;

 

  // Initialize EDMA Event Src and Dst Addresses

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].SRC = aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC;

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].DST = (Uint32) piBufOutputPing;

 

  // Set EDMA Event PaRAM A,B,C CNT

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].A_B_CNT = aEdmaccRegs->PARAMSET[EDMA_EVENT1].A_B_CNT;

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].CCNT = aEdmaccRegs->PARAMSET[EDMA_EVENT1].CCNT;

 

  // Set EDMA Event PaRAM SRC/DST BIDX

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].SRC_DST_BIDX = aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC_DST_BIDX;

 

  // Set EDMA Event PaRAM SRC/DST CIDX

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].SRC_DST_CIDX = aEdmaccRegs->PARAMSET[EDMA_EVENT1].SRC_DST_CIDX;

 

  // Set EDMA Event PaRAM LINK and BCNTRLD

  aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET35].LINK_BCNTRLD =

      CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&aEdmaccRegs->PARAMSET[EDMA_PARAMETER_SET34] & 0xFFFFu); // |   // CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64] & 0xFFFFu) |

 

}

 

Finally, I call this method to start the transfer

 

void EDMA::StartMcASPTx(void)

{

 

  // Enable channel 1  by event enable set register

  CSL_FINST(aEdmaccRegs->EESR, EDMA3CC_EESR_E1, SET);

 

  // Enable interrupt for channel 1

  CSL_FINST(aEdmaccRegs->IESR, EDMA3CC_IESR_I1, SET);

 

 

}