Quantcast
Channel: Processors forum - Recent Threads
Viewing all articles
Browse latest Browse all 17527

EDMA and McASP and FIFO on C6748

$
0
0

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

 

voidEDMA::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

 

}

 

voidEDMA::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

 

voidEDMA::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);

 

 

}

 

 


Viewing all articles
Browse latest Browse all 17527

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>