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.

TMS320F28335: TMS320F28335: Problem about Receve data processing using McBSP and DMA

Part Number: TMS320F28335

Dear team:

I have a problem that receiving data using McBSP with DMA is shifted one channel below 9.375MHz clock.
(For example : Buffer_TX[0] --> Buffer_RX[1], Buffer_TX[1] --> Buffer_RX[2], .... , Buffer_TX[15] --> Buffer_RX[0])
However, operation of 16 channel in 18.75MHz clock or olnly one chanel below 18.75MHz is satisfied.

McBSP is applied SPI master mode with 16channel-16bit-burst in max 18.75 or below MHz serial clock.
DMA is adopted to event trigger method, not pripheral intterrupt.
The Receve & Transmit test is performed by DLB(Data Loop Back) mode.

How can I solve this problem? I want to resolve this issue.

Thank you.
Best regards

       

  • Hi,

    Can you share the McBSP initialization code?

    Thanks

    Vasudha

  • Hi, Team.
    Sure. I share the McBSP and DMA initialization code.
    Would you check my C-source code?

    Thanks.
    Best Regards.
    =============================================================================================
    //- DMA Initila Setting Code void DMAInitialize(void) { EALLOW; DmaRegs.DMACTRL.bit.HARDRESET = 1; asm (" nop"); // Channel 1, McBSPA transmit DmaRegs.CH1.MODE.bit.PERINTSEL = 14; // Peripheral interrupt select 14 = MXEVTA DmaRegs.CH1.MODE.bit.PERINTE = 1; // Enable peripheral interrupt event, 0=Disable, 1=Enable DmaRegs.CH1.MODE.bit.CHINTMODE = 0; // 0=Interrupt at beginning of new transfer, 1 = Interrupt at end of transfer DmaRegs.CH1.MODE.bit.CHINTE = 0; // channel interrupt Enable Bit, 0=Disable, 1=Enable DmaRegs.CH1.MODE.bit.SYNCE = 0; // No sync signal DmaRegs.CH1.MODE.bit.SYNCSEL = 0; // No sync signal DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clear peripheral interrupt event flag DmaRegs.CH1.CONTROL.bit.SYNCCLR = 1; // Clear sync flag DmaRegs.CH1.CONTROL.bit.ERRCLR = 1; // Clear sync error flag DmaRegs.CH1.BURST_SIZE.all = 0; // 5 = 6 word/burst DmaRegs.CH1.SRC_BURST_STEP = 0; // Source Burst Step, 1 = 1step DmaRegs.CH1.DST_BURST_STEP = 0; // Destination Burst Step, 0 = 0step DmaRegs.CH1.TRANSFER_SIZE = 15; // 0 = 1 word/transfer DmaRegs.CH1.SRC_TRANSFER_STEP = 2; // Source Trcansfer Step, 0 = 0step DmaRegs.CH1.DST_TRANSFER_STEP = 0; // Destination Transfer Step, 0 = 0step DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32)& Buffer_TX_A[0]; // Start address = buffer DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32)& Buffer_TX_A[0]; // Not needed unless using wrap function DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32)& McbspaRegs.DXR1.all; // Start address = McBSPA DXR DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32)& McbspaRegs.DXR1.all; // Not needed unless using wrap function DmaRegs.CH1.DST_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want destination wrap DmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want source wrap DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags // Channel 2, McBSPA Receive DmaRegs.CH2.MODE.bit.PERINTSEL = 15; // Peripheral interrupt select 15 = MREVTA DmaRegs.CH2.MODE.bit.PERINTE = 1; // Enable peripheral interrupt event, 0=Disable, 1=Enable DmaRegs.CH2.MODE.bit.CHINTMODE = 0; // 0=Interrupt at beginning of new transfer, 1 = Interrupt at end of transfer DmaRegs.CH2.MODE.bit.CHINTE = 0; // channel interrupt Enable Bit, 0=Disable, 1=Enable DmaRegs.CH2.MODE.bit.SYNCE = 0; // No sync signal DmaRegs.CH2.MODE.bit.SYNCSEL = 0; // No sync signal DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; // Clear peripheral interrupt event flag DmaRegs.CH2.CONTROL.bit.SYNCCLR = 1; // Clear sync flag DmaRegs.CH2.CONTROL.bit.ERRCLR = 1; // Clear sync error flag DmaRegs.CH2.BURST_SIZE.all = 0; // 5 = 6 word/burst DmaRegs.CH2.SRC_BURST_STEP = 0; // Source Burst Step, 0 = 0step DmaRegs.CH2.DST_BURST_STEP = 0; // Destination Burst Step, 1 = 1step DmaRegs.CH2.TRANSFER_SIZE = 15; // 0 = 1 word/transfer DmaRegs.CH2.SRC_TRANSFER_STEP = 0; // Source Transfer Step, 0 = 0step DmaRegs.CH2.DST_TRANSFER_STEP = 2; // Destination Transfer Step, 0 = 0step DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32)& McbspaRegs.DRR1.all; // Start address = McBSPA DRR DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32)& McbspaRegs.DRR1.all; // Not needed unless using wrap function DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32)& Buffer_RX_A[0]; // Start address = Receive buffer (for McBSP-A) DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32)& Buffer_RX_A[0]; // Not needed unless using wrap function DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want destination wrap DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want source wrap DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags // Channel 3, McBSPB transmit DmaRegs.CH3.MODE.bit.PERINTSEL= 16; // Peripheral interrupt select 16 = MXEVTB DmaRegs.CH3.MODE.bit.PERINTE = 1; // Enable peripheral interrupt event, 0=Disable, 1=Enable DmaRegs.CH3.MODE.bit.CHINTMODE = 0; // 0=Interrupt at beginning of new transfer, 1 = Interrupt at end of transfer DmaRegs.CH3.MODE.bit.CHINTE = 0; // channel interrupt Enable Bit, 0=Disable, 1=Enable DmaRegs.CH3.MODE.bit.SYNCE = 0; // No sync signal DmaRegs.CH3.MODE.bit.SYNCSEL = 0; // No sync signal DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1; // Clear peripheral interrupt event flag DmaRegs.CH3.CONTROL.bit.SYNCCLR = 1; // Clear sync flag DmaRegs.CH3.CONTROL.bit.ERRCLR = 1; // Clear sync error flag DmaRegs.CH3.BURST_SIZE.all = 0; // 5 = 6 word/burst DmaRegs.CH3.SRC_BURST_STEP = 0; // Source Burst Step, 1 = 1step DmaRegs.CH3.DST_BURST_STEP = 0; // Destination Burst Step, 0 = 0step DmaRegs.CH3.TRANSFER_SIZE = 15; // 0 = 1 word/transfer DmaRegs.CH3.SRC_TRANSFER_STEP = 2; // Source Transfer Step, 0 = 0step DmaRegs.CH3.DST_TRANSFER_STEP = 0; // Destination Transfer Step, 0 = 0step DmaRegs.CH3.SRC_ADDR_SHADOW = (Uint32)& Buffer_TX_B[0]; // Start address = buffer DmaRegs.CH3.SRC_BEG_ADDR_SHADOW = (Uint32) &Buffer_TX_B[0]; // Not needed unless using wrap function DmaRegs.CH3.DST_ADDR_SHADOW = (Uint32)& McbspbRegs.DXR1.all; // Start address = McBSPA DXR DmaRegs.CH3.DST_BEG_ADDR_SHADOW = (Uint32)& McbspbRegs.DXR1.all; // Not needed unless using wrap function DmaRegs.CH3.DST_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want destination wrap DmaRegs.CH3.SRC_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want source wrap DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags // Channel 4, McBSPB Receive DmaRegs.CH4.MODE.bit.PERINTSEL = 17; // Peripheral interrupt select 17 = MREVTB DmaRegs.CH4.MODE.bit.PERINTE = 1; // Enable peripheral interrupt event, 0=Disable, 1=Enable DmaRegs.CH4.MODE.bit.CHINTMODE = 0; // 0=Interrupt at beginning of new transfer, 1 = Interrupt at end of transfer DmaRegs.CH4.MODE.bit.CHINTE = 0; // channel interrupt Enable Bit, 0=Disable, 1=Enable DmaRegs.CH4.MODE.bit.SYNCE = 0; // No sync signal DmaRegs.CH4.MODE.bit.SYNCSEL = 0; // No sync signal DmaRegs.CH4.CONTROL.bit.PERINTCLR = 1; // Clear peripheral interrupt event flag DmaRegs.CH4.CONTROL.bit.SYNCCLR = 1; // Clear sync flag DmaRegs.CH4.CONTROL.bit.ERRCLR = 1; // Clear sync error flag DmaRegs.CH4.BURST_SIZE.all = 0; // 5 = 6 word/burst DmaRegs.CH4.SRC_BURST_STEP = 0; // Source Burst Step, 0 = 0step DmaRegs.CH4.DST_BURST_STEP = 0; // Destination Burst Step, 1 = 1step DmaRegs.CH4.TRANSFER_SIZE = 15; // 0 = 1 word/transfer DmaRegs.CH4.SRC_TRANSFER_STEP = 0; // Source Transfer Step, 0 = 0step DmaRegs.CH4.DST_TRANSFER_STEP = 2; // Destination Transfer Step, 0 = 0step DmaRegs.CH4.SRC_ADDR_SHADOW = (Uint32)& McbspbRegs.DRR1.all; // Start address = McBSPA DRR DmaRegs.CH4.SRC_BEG_ADDR_SHADOW = (Uint32)& McbspbRegs.DRR1.all; // Not needed unless using wrap function DmaRegs.CH4.DST_ADDR_SHADOW = (Uint32)& Buffer_RX_B[0]; // Start address = Receive buffer (for McBSP-A) DmaRegs.CH4.DST_BEG_ADDR_SHADOW = (Uint32)& Buffer_RX_B[0]; // Not needed unless using wrap function DmaRegs.CH4.DST_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want destination wrap DmaRegs.CH4.SRC_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want source wrap DmaRegs.CH4.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags EDIS; } // - McBSP Initial Setting Code void InitMcbspa(void) { McbspaRegs.SPCR2.all =0x0000; // Reset FS generator, sample rate generator & transmitter McbspaRegs.SPCR2.bit.XINTM =2; // When each transmit frame-synchonization pulse is detect, The McBSP sends a XINT request ot the CPU McbspaRegs.SPCR1.all =0x0000; // Reset Receiver, Right justify word, Digital loopback dis. McbspaRegs.SPCR1.bit.RINTM =2; // When each receive frame-synchonization pulse is detect, The McBSP sends a RINT request ot the CPU McbspaRegs.PCR.all=0x0F08; //(CLKXM=CLKRM=FSXM=FSRM= 1, FSXP = 1) McbspaRegs.PCR.bit.FSRP = 1; // Frame_synchronization pulse FSR is Active Low McbspaRegs.PCR.bit.FSRP = 1; // Frame_synchronization pulse FSR is Active Low McbspaRegs.PCR.bit.FSXP = 1; McbspaRegs.PCR.bit.FSXM = 1; McbspaRegs.PCR.bit.FSRM = 0; // 0 : External 1: Internal McbspaRegs.PCR.bit.CLKXM = 1; McbspaRegs.PCR.bit.SCLKME= 0; McbspaRegs.PCR.bit.FSXP = 1; McbspaRegs.SPCR1.bit.DLB = 1; McbspaRegs.SPCR1.bit.CLKSTP = 2; // Clock Stop Mode without clock delay McbspaRegs.PCR.bit.CLKXP = 0; // CLKXP = 0 : Transmit data is sampled on the rising edge of CLKX McbspaRegs.PCR.bit.CLKRP = 0; // CLKRP = 0 : Receive data is sampled on the falling edge of CLKR McbspaRegs.RCR2.bit.RDATDLY=0; // Receive data delay after Fram synch signal McbspaRegs.XCR2.bit.XDATDLY=0; // Transmitt data delay after Fram synch signal McbspaRegs.RCR1.bit.RWDLEN1=2; // 16-bit word McbspaRegs.XCR1.bit.XWDLEN1=2; // 16-bit word McbspaRegs.SRGR2.all=0x2000; // CLKSM=1, FPER = 1 CLKG periods McbspaRegs.SRGR2.bit.FPER =0x0010; // CLKSM=1, FPER = 1 CLKG periods McbspaRegs.SRGR2.bit.CLKSM =1; McbspaRegs.SRGR2.bit.FSGM = 0; McbspaRegs.SRGR1.bit.CLKGDV = 3; // CLK = 18.75MHz/(McBSP_A_CLKDIV+1) McbspaRegs.SPCR2.bit.GRST=0; // Reset the sample rate generator McbspaRegs.SPCR2.bit.FRST=0; // Frame Sync Generator reset McbspaRegs.SPCR2.bit.XRST=0; // Reset TX for Disable McbspaRegs.SPCR1.bit.RRST=0; // Reset RX for Disable McbspaRegs.SPCR1.bit.RJUST = 0x01; // Sign Extend data into MSPs : clkg_delay_loop(); // Wait at least 2 CLKG cycles McbspaRegs.SPCR2.bit.GRST=1; // Enable the sample rate generator McbspaRegs.SPCR2.bit.FRST=1; // Frame Sync Generator Enable McbspaRegs.SPCR2.bit.XRST=1; // Enable TX from Reset McbspaRegs.SPCR1.bit.RRST=1; // Enable RX from Reset DelayUs(10); } void InitMcbspb(void) { McbspbRegs.SPCR2.all=0x0000; McbspbRegs.SPCR2.bit.XINTM =2; McbspbRegs.SPCR1.all =0x0000; McbspbRegs.SPCR1.bit.RINTM =2; McbspbRegs.PCR.all=0x0F08; McbspbRegs.PCR.bit.FSRP = 1; McbspbRegs.PCR.bit.FSXP = 1; McbspbRegs.PCR.bit.FSXM = 1; McbspbRegs.PCR.bit.FSRM = 0; // 0 : External 1: Internal McbspbRegs.PCR.bit.CLKXM = 1; McbspbRegs.PCR.bit.SCLKME= 0; McbspbRegs.PCR.bit.FSXP = 1; McbspbRegs.SPCR1.bit.DLB = 1; McbspbRegs.SPCR1.bit.CLKSTP = 2; McbspbRegs.PCR.bit.CLKXP = 0; McbspbRegs.PCR.bit.CLKRP = 0; McbspbRegs.RCR2.bit.RDATDLY = 0; McbspbRegs.XCR2.bit.XDATDLY = 0; McbspbRegs.RCR1.bit.RWDLEN1=2; // 16-bit word McbspbRegs.XCR1.bit.XWDLEN1=2; // 16-bit word McbspbRegs.SRGR2.all=0x2000; McbspbRegs.SRGR2.bit.CLKSM =1; McbspbRegs.SRGR2.bit.FSGM = 0; McbspbRegs.SRGR1.bit.CLKGDV = 3; // CLK = 18.75MHz/(McBSP_A_CLKDIV+1) McbspbRegs.SPCR2.bit.GRST=0; // Reset the sample rate generator McbspbRegs.SPCR2.bit.FRST=0; // Frame Sync Generator reset McbspbRegs.SPCR2.bit.XRST=0; // Reset TX for Disable McbspbRegs.SPCR1.bit.RRST=0; // Reset RX for Disable McbspbRegs.SPCR1.bit.RJUST = 0x01; // Sign Extend data into MSPs : 2019.08.28 clkg_delay_loop(); // Wait at least 2 CLKG cycles McbspbRegs.SPCR2.bit.GRST=1; // Enable the sample rate generator McbspbRegs.SPCR2.bit.FRST=1; // Frame Sync Generator Enable McbspbRegs.SPCR2.bit.XRST=1; // Enable TX from Reset McbspbRegs.SPCR1.bit.RRST=1; // Enable RX from Reset DelayUs(10); } // - McBSP and DMA Reset Code void ExtADCReset() { int i=0; McbspaRegs.DXR1.all = (Uint16)(0x0000); // Mode Select(MODE I -> PSEUDO-DFFERENTIAL MODE II) McbspbRegs.DXR1.all = (Uint16)(0x0000); // Mode Select(MODE I -> PSEUDO-DFFERENTIAL MODE II) DelayUs(1); Buffer_RX_A[0] = ((int)(McbspaRegs.DRR1.all)); // McBSP RX Buffer Clear Buffer_RX_B[0] = ((int)(McbspbRegs.DRR1.all)); // McBSP RX Buffer Clear EALLOW; DmaRegs.CH1.CONTROL.bit.SOFTRESET=1; DmaRegs.CH2.CONTROL.bit.SOFTRESET=1; DmaRegs.CH2.CONTROL.bit.PERINTCLR=1; DmaRegs.CH3.CONTROL.bit.SOFTRESET=1; DmaRegs.CH4.CONTROL.bit.SOFTRESET=1; DmaRegs.CH4.CONTROL.bit.PERINTCLR=1; EDIS; DelayUs(1); for(i=0;i<16;i++){ Buffer_RX_A[i]=0; // RX Buffer Clear Buffer_RX_B[i]=0; Buffer_TX_A[i]=0; // TX Buffer Clear Buffer_TX_B[i]=0; } } void InitAD7617() { EALLOW; DmaRegs.CH1.CONTROL.bit.SOFTRESET=1; DmaRegs.CH2.CONTROL.bit.SOFTRESET=1; DmaRegs.CH3.CONTROL.bit.SOFTRESET=1; DmaRegs.CH4.CONTROL.bit.SOFTRESET=1; EDIS; ExtADCReset(); EALLOW; DmaRegs.CH1.CONTROL.bit.RUN = 1; // Start DMA Transmit from McBSP-A DmaRegs.CH2.CONTROL.bit.RUN = 1; // Start DMA Receive from McBSP-A DmaRegs.CH3.CONTROL.bit.RUN = 1; // Start DMA Transmit from McBSP-B DmaRegs.CH4.CONTROL.bit.RUN = 1; // Start DMA Receive from McBSP-B EDIS; DelayUs(10); ExtADCErrorCheck(); }

  • Hi,

    Seungmo Kim said:
    McbspbRegs.SPCR2.bit.XRST=1;         // Enable TX from Reset
        McbspbRegs.SPCR1.bit.RRST=1;         // Enable RX from Reset

    Can you enable the receiver 1st and then Tranmitter like below and try? I have seen this issue with DLB mode.

    McbspbRegs.SPCR1.bit.RRST=1;         // Enable RX from Reset
    McbspbRegs.SPCR2.bit.XRST=1;         // Enable TX from Reset
    

    I am looking into this and will get back shortly.

    Thanks

    Vasudha

  • Dear Vasudha.

    I tred to  debug program as you comment reply (receiver 1st and then Tranmitter Reset).

    But, I'm sorry to say that the situation does not change before.

    Thank you for your  kindly reply.

  • Hi,

    Were you able to resolve the issue. I think the issue is due to the DLB mode.

    Thanks

    Vasudha

  • Hi, Vasudha.
    I have been cheked this problem with datasheet.
    This test condition is DLB=0, SPI Master mode, and RX-TX connected with fibor optic cable.
    - In case SCLK is 18.75MHz : After CLKX signal was low state, the holding time that FSX signal state is low has been within minimum time as datasheet 
    Receive data is OK (ex: Buffer_Tx_A[0] --> Buffer_Rx_A[0])

    - In case SCLK is 9.375MHz below : After CLKX signal was low state, the holding time that FSX signal is low state does not hold within minimum time.
    So, I think this cause receive data channel is shifted. (ex: Buffer_Tx_A[0] --> Buffer_Rx_A[1] )

    It's is just my opinion. 
    Would you comment my though?

    Thanks

    McBSP's Receive Problem.pptx

  • Hi,

    We are looking into this and will get back once we find something.

    Thanks

    Vasudha

  • Hi,

    We are trying to recreate the issue. Can you please let us know if you are seeing this issue only with DLB mode? 

    With DLB = 0 configuration, are McBSPA and McBSPB  configured as SPI master and reciever?

    Thanks

    Vasudha

  • Seungmo,

    Checking back to see if you had an opportunity to try Vasudha's suggestion above?  I'm going to mark as TI thinks resolved, but if you have further info please reply back and we will be alerted.

    Best,

    Matthew