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.

MCBSP duplicated data on DX pin

Other Parts Discussed in Thread: OMAP-L138

hi,

I am using omap-l138 exp kit and I want to use MCBSP port to transmit data to a slave device.

word length is 8 bit, frame length 5 words (5 bytes)

I used the following code to initialize the port (mcbsp_init), and to send data by polling (mcbsp_write).

the problem is that; data on DX pin is duplicated - how?? when I try to send for example (0xF0, 0xCC, 0xAA, 0x88, 0xDD), I get in one frame (0xF0, 0xF0, 0xCC, 0xCC, 0xAA) and the other frame (0xAA, 0x88, 0x88, 0xDD, 0xDD).

first I thought there was some problem with my (mcbsp_write) Fxn, so I switched to interrupt ISR (MCBSP1_TX) but still getting the same result.

so I came to a conclusion that its a problem in the initialization function (I guess) .

would any one tell me why output data is duplicated ?? or what is the problem in (mcbsp_init).

one more thing (MCR) register, should I leave it all zeroes?? I only want to use one channel

#include "cslr_mcbsp.h"
#include "main.h"
#include "evmc6748.h"

#define SETBIT(dest,mask) 	(dest|=mask)
#define CLRBIT(dest,mask) 	(dest&=~mask)
#define CHKBIT(dest,mask)	(dest&=mask)
/*-------PINMUX-------*/
#define PINMUX_MCBSP1_Tx_REG       (1)
#define PINMUX_MCBSP1_Tx_MASK      (0x0F0F0F00)
#define PINMUX_MCBSP1_Tx_VAL       (0x02020200)

//#define PINMUX_MCBSP1_Tx_MASK      (0x0F0f0f00)//GP0
//#define PINMUX_MCBSP1_Tx_VAL       (0x08080800)

#define FPER_shift 16
#define CLKSM_shift 29
#define FSGM_shift 28
#define CLKGDV_shift 0
#define FWID_shift 8
#define XFRLEN1_shift 8
#define NULL 0

#define CLKSM_INTERNAL 1<<29
#define FSGM_DXR2XSR 0 << 28
#define FSGM_FSG 1 << 28

extern int i, rx_cnt;
extern int16_t txbuf[];
extern uint8_t *Tx_ptr, *mcbsp_ptr;
extern int8_t dds_txbuf[2][160][15];

uint32_t MCBSP_init(McbspRegs *mcbsp, uint8_t CLKGDV, uint8_t FPER,
		uint8_t FWID, uint8_t XWDLEN1, uint8_t xferlen) {
	uint32_t rtn = ERR_INVALID_PARAMETER;
	if (mcbsp == MCBSP1) {
		//0x08080800
		EVMC6748_lpscTransition(PSC1, DOMAIN0, LPSC_MCBSP1, PSC_ENABLE);
		EVMC6748_pinmuxConfig(PINMUX_MCBSP1_Tx_REG, PINMUX_MCBSP1_Tx_MASK,
				PINMUX_MCBSP1_Tx_VAL);
	}
//reset mcbsp registers
	mcbsp->SPCR = 0; //hold Tx and Rx parts in reset
	mcbsp->XCR = 0;
	mcbsp->SRGR = 0;
	mcbsp->PCR = 0;

	mcbsp->MCR = 0;

	mcbsp->RCERE0 = 0;
	mcbsp->RCERE1 = 0;
	mcbsp->RCERE2 = 0;
	mcbsp->RCERE3 = 0;

	mcbsp->XCERE0 = 0;
	mcbsp->XCERE1 = 0;
	mcbsp->XCERE2 = 0;
	mcbsp->XCERE3 = 0;

	SETBIT(mcbsp->SRGR, (CLKGDV-1) <<CLKGDV_shift | //
			(FPER-1) <<FPER_shift |//
			(FWID-1) <<FWID_shift |//
			MCBSP_SRGR_CLKSM |//internal input clock
			FSGM_FSG);
	//

	SETBIT(mcbsp->PCR, MCBSP_PCR_FSXP | MCBSP_PCR_CLKXM | MCBSP_PCR_FSXM);

	SETBIT(mcbsp->XCR, XCR_XFIG_IGNORE |XCR_XDATDLY_1bit);
	//| 5 << XWDLEN1_shift);//word length 8 bits |5 words in phase 1 | 1-bit data delay |Single-phase frame.

		SETBIT(mcbsp->XCR, XCR_XWDLEN1_8bit);
	
		SETBIT(mcbsp->XCR, XCR_XFRLEN1_5word);

	for (i = 0; i < 5; i++) { ; }

	SETBIT(mcbsp->SPCR, MCBSP_SPCR_XINTM_XRDY); 	//XINT is driven by XRDY (end-of-word
	SETBIT(mcbsp->SPCR, MCBSP_SPCR_GRST); 	// enable bit clk generator

	for (i = 0; i < 20; i++) {; } // wait for GRST

	SETBIT(mcbsp->SPCR, MCBSP_SPCR_XRST);
	// take Tx portion out of reset
	for (i = 0; i < 5; i++) { ; } //wait to check Transmit synchronization error

	if (CHKBIT(mcbsp->SPCR,MCBSP_SPCR_XSYNCERR)) // if XSYNCERR occured
		CLRBIT(mcbsp->SPCR, MCBSP_SPCR_XRST); 	// disable transmitter to clear the error

	if (!CHKBIT(mcbsp->SPCR,MCBSP_SPCR_XRST))
		SETBIT(mcbsp->SPCR, MCBSP_SPCR_XRST); 	// enable transmitter if it was reset by XSYNCERR

	while (!CHKBIT(mcbsp->SPCR,MCBSP_SPCR_XRDY)) { ; } //wait for MCBSP_SPCR_XRDY
	SETBIT(mcbsp->SPCR, MCBSP_SPCR_FRST);
	// enable frame sync generator

	return (rtn);

}

uint32_t MCBSP_write(McbspRegs *mcbsp, uint8_t *src_buffer, int16_t in_length) {
	uint32_t rtn = ERR_INVALID_PARAMETER;
	uint32_t i;
	uint32_t mcbsp_DXR;

	if ((mcbsp != NULL) && (src_buffer != NULL)) {
     mcbsp_DXR = mcbsp->DXR;

		// transmit data one byte at a time, copy receive data into input buffer.
		for (i = 0; i < in_length; i++) {

			while (!CHKBIT (mcbsp->SPCR,MCBSP_SPCR_XRDY)) { ; }

//          USTIMER_delay(1);
			mcbsp_DXR = *src_buffer;
			src_buffer++;
			mcbsp->DXR = mcbsp_DXR;
			
			if (CHKBIT (MCBSP1->SPCR,MCBSP_SPCR_XSYNCERR)) {
				System_printf("ERROR: %$S", "XSYNCERR");

						}
		}

		rtn = ERR_NO_ERROR;
	}

	return (rtn);
}

void MCBSP1_TX(void) {
	uint32_t DRR_data;

	MCBSP1->DXR = mcbsp_ptr[tx_cnt];
	while (CHKBIT (MCBSP1->SPCR,MCBSP_SPCR_XEMPTY)) { ; }
	tx_cnt++;
	if (tx_cnt > 159)
		tx_cnt = -159;
}

regards...

  • hi,

     I translated the previous code into CSL macros, so it would be easier for you to debug

    #include "main.h"
    #include "evmc6748.h"
    #include "mcbsp.h"
    #include <ti/pspiom/cslr/cslr_mcbsp.h>
    
    /*-------PINMUX-------*/
    #define PINMUX_MCBSP1_Tx_REG       (1)
    #define PINMUX_MCBSP1_Tx_MASK      (0x0F0F0F00)
    #define PINMUX_MCBSP1_Tx_VAL       (0x02020200)
    
    extern uint8_t txbuf2[5];
    
    uint32_t MCBSP_init(McbspRegs *mcbsp, uint8_t CLKGDV, uint8_t FPER, uint8_t FWID, uint8_t XWDLEN1, uint8_t xferlen)
    	{
    	uint32_t rtn = ERR_INVALID_PARAMETER;
    	uint8_t i;
    	if (mcbsp == MCBSP1)
    	{
    		EVMC6748_lpscTransition(PSC1, DOMAIN0, LPSC_MCBSP1, PSC_ENABLE);
    		EVMC6748_pinmuxConfig(PINMUX_MCBSP1_Tx_REG, PINMUX_MCBSP1_Tx_MASK,PINMUX_MCBSP1_Tx_VAL);
    	}
    
    //reset mcbsp registers
    	mcbsp->SPCR=CSL_FMKT(MCBSP_SPCR_FREE,DISABLE)
    				| CSL_FMKT(MCBSP_SPCR_SOFT,DISABLE)
    				| CSL_FMKT(MCBSP_SPCR_FRST,RESET)
    				| CSL_FMKT(MCBSP_SPCR_GRST,RESET)
    				| CSL_FMKT(MCBSP_SPCR_XINTM,FRM)
    				| CSL_FMKT(MCBSP_SPCR_XRST,DISABLE)
    				| CSL_FMKT(MCBSP_SPCR_DLB,DISABLE)
    				| CSL_FMKT(MCBSP_SPCR_RJUST,RZF)
    				| CSL_FMKT(MCBSP_SPCR_CLKSTP,DISABLE_00)
    				| CSL_FMKT(MCBSP_SPCR_DXENA,OFF)
    				| CSL_FMKT(MCBSP_SPCR_RINTM,RRDY)
    				| CSL_FMKT(MCBSP_SPCR_RRST,DISABLE); //hold Tx and Rx parts in reset
    
    	mcbsp->XCR=CSL_FMKT(MCBSP_XCR_XFIG,NO)
    				|CSL_FMKT(MCBSP_XCR_XPHASE,SINGLE_FRM)
    				|CSL_FMKT(MCBSP_XCR_XDATDLY,1BIT);
    
    	switch (XWDLEN1) {
    		case 8:
    			CSL_FINST(mcbsp->XCR,MCBSP_XCR_XWDLEN1,8BIT);
    	//		SETBIT(mcbsp->XCR, XCR_XWDLEN1_8bit);
    			break;
    		case 12:
    			CSL_FINST(mcbsp->XCR,MCBSP_XCR_XWDLEN1,12BIT);
    	//		SETBIT(mcbsp->XCR, XCR_XWDLEN1_12bit);
    			break;
    		case 16:
    			CSL_FINST(mcbsp->XCR,MCBSP_XCR_XWDLEN1,16BIT);
    	//		SETBIT(mcbsp->XCR, XCR_XWDLEN1_16bit);
    			break;
    		case 20:
    			CSL_FINST(mcbsp->XCR,MCBSP_XCR_XWDLEN1,20BIT);
    	//		SETBIT(mcbsp->XCR, XCR_XWDLEN1_20bit);
    			break;
    		case 24:
    			CSL_FINST(mcbsp->XCR,MCBSP_XCR_XWDLEN1,24BIT);
    	//		SETBIT(mcbsp->XCR, XCR_XWDLEN1_24bit);
    			break;
    		case 32:
    			CSL_FINST(mcbsp->XCR,MCBSP_XCR_XWDLEN1,32BIT);
    	//		SETBIT(mcbsp->XCR, XCR_XWDLEN1_32bit);
    			break;
    		}
    	CSL_FINS(mcbsp->XCR,MCBSP_XCR_XFRLEN1,xferlen-1);
    
    	//PROGRAM SAMPLE RATE GENERATOR
    		mcbsp->SRGR=  CSL_FMKT(MCBSP_SRGR_GSYNC,FREE)
    					| CSL_FMKT(MCBSP_SRGR_CLKSP,RISING)
    					| CSL_FMKT(MCBSP_SRGR_CLKSM,INTERNAL)
    					| CSL_FMKT(MCBSP_SRGR_FSGM,FSG)
    					| CSL_FMK(MCBSP_SRGR_CLKGDV, CLKGDV-1)
    					| CSL_FMK(MCBSP_SRGR_FPER, FPER-1)
    					| CSL_FMK(MCBSP_SRGR_FWID, FWID-1);
    		//PCR
    	mcbsp->PCR 	= 0;
    	mcbsp->PCR=	  CSL_FMKT(MCBSP_PCR_FSXP,ACTIVELOW)
    					| CSL_FMKT(MCBSP_PCR_FSXM,INTERNAL)
    					| CSL_FMKT(MCBSP_PCR_CLKXM,OUTPUT);
    
    	mcbsp->MCR 	= 0;
    	mcbsp->RCERE0 = 0;
    	mcbsp->RCERE1 = 0;
    	mcbsp->RCERE2 = 0;
    	mcbsp->RCERE3 = 0;
    	mcbsp->XCERE0 = 0;
    	mcbsp->XCERE1 = 0;
    	mcbsp->XCERE2 = 0;
    	mcbsp->XCERE3 = 0;
    
    	for (i = 0; i < 3; i++) { ; }
    	// enable bit clk generator
    	CSL_FINST(mcbsp->SPCR,MCBSP_SPCR_GRST,CLKG);
    	// enable bit clk generator
    
    	for (i = 0; i <=0 ; i++) { ;} // wait for GRST
    	CSL_FINST(mcbsp->SPCR,MCBSP_SPCR_XRST,ENABLE);	// take Tx portion out of reset
    
    	for (i = 0; i < 1; i++) { ; } //wait to check Transmit synchronization error
    	if	(CSL_FEXT(mcbsp->SPCR, MCBSP_SPCR_XSYNCERR) == CSL_MCBSP_SPCR_XSYNCERR_YES) // if XSYNCERR occured
    		CSL_FINST(mcbsp->SPCR,MCBSP_SPCR_XRST,DISABLE);//// disable transmitter to clear the error
    
    //setup_EDMA();// setup EDMA transfer
    
    	if (CSL_FEXT(mcbsp->SPCR, MCBSP_SPCR_XRST) == CSL_MCBSP_SPCR_XRST_DISABLE)
    		CSL_FINST(mcbsp->SPCR,MCBSP_SPCR_XRST,ENABLE); // enable transmitter if it was reset by XSYNCERR
    
    //mcbsp->DXR=0x0;//send a dummy byte
    while (CSL_FEXT(mcbsp->SPCR, MCBSP_SPCR_XRDY) != CSL_MCBSP_SPCR_XRDY_YES) {;} //wait for XEMPTY
    
    CSL_FINST(mcbsp->SPCR,MCBSP_SPCR_FRST,FSG);	// enable frame sync generator
    
    //EdmaEnableChannel(MCBSP1_TX_PARAM,EDMAQNUM_0);// Enable Channel 5 Event and Assign it to Queue 0
    //mcbsp->MCR|= 1<<16;
    mcbsp->DXR=0x0;//send a dummy byte
    
    	return (rtn);
    
    }
    
    uint32_t MCBSP_write(McbspRegs *mcbsp, uint8_t *src_buffer, int16_t in_length) {
    	uint32_t rtn = ERR_INVALID_PARAMETER;
    	uint32_t i;
    	uint32_t mcbsp_DXR;
    
    	if ((mcbsp != NULL) && (src_buffer != NULL))
    	{
    //      mcbsp_DXR = mcbsp->DXR;
    
    		// transmit data one byte at a time, copy receive data into input buffer.
    		for (i = 0; i < in_length; i++)
    		{
    //          while (CHKBIT (mcbsp->SPCR,MCBSP_SPCR_XEMPTY)){ ;}
    
    			mcbsp_DXR=*src_buffer;
    			src_buffer++;
    			while (CSL_FEXT(mcbsp->SPCR, MCBSP_SPCR_XRDY) != CSL_MCBSP_SPCR_XRDY_YES)
    			{;}
    			         // copy the tmp reg to the real thing.
    			mcbsp->DXR = mcbsp_DXR;
    
    		}
    
    		rtn = ERR_NO_ERROR;
    	}
    
    	return (rtn);
    }
    

    I hope to find a solution for this duplicated outpu

  • I even tried  an Interrupt function, But still getting the same result

    void MCBSP1_tx(void)

    {

    MCBSP1->DXR=txbuf[tx_cnt];

    tx_cnt++;

    if(txcnt>4)

    tx_cnt=0;

    }

    so I guess the problem is with (MCBSP_init) Function, if some one can figure out what my mistake is; I'll really appreciate it

  • when I change (XWDLEN1=32bit) and (FPER-1=40) and (xferlen1=1) every thing looks good.

    but I need to transfer 40 bits as 5 bytes per frame.......

  • Mohammed,

    Try slowing down the bit clock by at least half to see if this is a speed issue. It is not easy to service quickly.

    Regards,
    RandyP

  • hi,

    I tried that, divided the previous bit clock by 2,  but its still the same.

    the initialization code I provided above, did I miss something??

    Regards

  • Please try slowing it down even more and confirm the speed looking at the pin's signal with an oscilloscope.

    It would be good to have a GPIO pin that you can pulse to see exactly when the DSP writes to the DXR so you can correlate that to the bits going out.

    I will not be able to tell anything by reading your code. It will need to be debugged, for which I can make suggestions, if that is acceptable. Try different things to see how it behaves differently. Use 32-bit words, 16-bit words, different frame sizes, and so on.

    The only causes I can think of for this would be running it too fast to be able to respond in time, or having your word-length settings wrong.

    Regards,
    RandyP