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.

Problem in McBSP SPI interface with ADC ADS7945EVM

Hi all,

   I am using C6713DSK to interface with a 2-channel ADC ADS7945EVM, through McBSP0 in SPI mode. However, I have encountered problem in switching between the 2 ADC channels. According to the ADS7945EVM user's guide and datasheet, the McBSP as the SPI master need to send 0x0000 or 0xFFFF to the ADC to select channel 0 or 1 respectively. I have come up with an interrupt service routine for RRDY to read from the 1st channel and then toggle the channel selection to read from the 2nd channel for the next interrupt, but when I monitor the MOSI pin on oscilloscope, the channel selection signal is not toggling consistently for every frame sync, most of the time it takes 2 frame sync to toggle. I'm wondering if it is that my ISR has exceeded the interval between 2 interrupt call, but apparently the total instruction cycle of my ISR can't be that long. Here is my code including the McBSP setting, main function and the ISR for RRDY, the program is built by DSP bios. Is it that the way that I am toggling the channel selection signal is wrong, or there are more efficient ways of doing it?       

#include "mcbsp_interruptcfg.h"
#include <stdio.h>
#include <math.h>
#include <csl.h>
#include <csl_mcbsp.h>
#include "dsk6713.h"
#include "dsk6713_dip.h"
#include "DAC_input.c"
/* create a config structure */
static MCBSP_Config ConfigLoopback = {    
/* Serial Port Control Register (SPCR) */  

MCBSP_SPCR_RMK(              
    MCBSP_SPCR_FREE_YES,                    
    MCBSP_SPCR_SOFT_YES,                                  
    MCBSP_SPCR_FRST_YES,     
    MCBSP_SPCR_GRST_YES,     
    MCBSP_SPCR_XINTM_XRDY,    
    MCBSP_SPCR_XSYNCERR_NO,        
    MCBSP_SPCR_XRST_YES,     
    MCBSP_SPCR_DLB_OFF,      
    MCBSP_SPCR_RJUST_RZF,    
    MCBSP_SPCR_CLKSTP_DELAY,     
    MCBSP_SPCR_DXENA_OFF,    
    MCBSP_SPCR_RINTM_RRDY,        
    MCBSP_SPCR_RSYNCERR_NO,    
    MCBSP_SPCR_RRST_YES   ),      

/*  Receive Control Register (RCR) */  

MCBSP_RCR_RMK(        
    MCBSP_RCR_RPHASE_SINGLE,         
    MCBSP_RCR_RFRLEN2_OF(0),     
    MCBSP_RCR_RWDLEN2_8BIT,    
    MCBSP_RCR_RCOMPAND_MSB,    
    MCBSP_RCR_RFIG_YES,     
    MCBSP_RCR_RDATDLY_1BIT,    
    MCBSP_RCR_RFRLEN1_OF(0),         
    MCBSP_RCR_RWDLEN1_16BIT,        // Receive element length in phase 1(RWDLEN1) (16 bit)    
    MCBSP_RCR_RWDREVRS_DISABLE/  ),  

/* Transmit Control Register (XCR) */  

MCBSP_XCR_RMK(                    
    MCBSP_XCR_XPHASE_SINGLE,    
    MCBSP_XCR_XFRLEN2_OF(0),    
    MCBSP_XCR_XWDLEN2_8BIT,     
    MCBSP_XCR_XCOMPAND_MSB,         
    MCBSP_XCR_XFIG_YES,     
    MCBSP_XCR_XDATDLY_1BIT,    
    MCBSP_XCR_XFRLEN1_OF(0),     
    MCBSP_XCR_XWDLEN1_16BIT,        // Transmit element length in phase 1(XWDLEN1) (16 bit)    
    MCBSP_XCR_XWDREVRS_DISABLE   ),    

/*serial port sample rate generator register(SRGR) */  

MCBSP_SRGR_RMK(       
    MCBSP_SRGR_GSYNC_FREE,        
    MCBSP_SRGR_CLKSP_RISING,    
    MCBSP_SRGR_CLKSM_INTERNAL,    
    MCBSP_SRGR_FSGM_FSG,    
    MCBSP_SRGR_FPER_OF(18),        // Frame period(FPER)
(19 bit clock)        
    MCBSP_SRGR_FWID_OF(0),        // Frame width(FWID)
(1 bit clock)    
    MCBSP_SRGR_CLKGDV_OF(2)        // Sample rate generator clock divider(CLKGDV) (37.5 MHz)  
),    

MCBSP_MCR_DEFAULT, /* Using default value of MCR register */  
MCBSP_RCER_DEFAULT,/* Using default value of RCER register */  
MCBSP_XCER_DEFAULT,/* Using default value of XCER register */    

/* serial port pin control register(PCR) */  

MCBSP_PCR_RMK(         
    MCBSP_PCR_XIOEN_SP,    
    MCBSP_PCR_RIOEN_SP,     
    MCBSP_PCR_FSXM_INTERNAL,        
    MCBSP_PCR_FSRM_EXTERNAL,     
    MCBSP_PCR_CLKXM_OUTPUT,    
    MCBSP_PCR_CLKRM_INPUT,     
    MCBSP_PCR_CLKSSTAT_0,     
    MCBSP_PCR_DXSTAT_0,       
    MCBSP_PCR_FSXP_ACTIVELOW,         
    MCBSP_PCR_FSRP_ACTIVEHIGH,     
    MCBSP_PCR_CLKXP_RISING,     
    MCBSP_PCR_CLKRP_FALLING   )
};

/* Global parameters */
MCBSP_Handle hMcbsp;
Uint16 x_buf[500];     // buffer for channel 0
Uint16 x_buf1[500];    // buffer for channel 1
Uint16 n=0;
char signal=0;        // variable used for channel selection

/* Function Prototype */
void rintHWI (void);

/* ---------------------------------------------------------------------------*/  

void main() {

  /* Initialize CSL and BSL */  
  DSK6713_init();
  DSK6713_DIP_init();
  CSL_init();  

  /* set MCBSP0 and MCBSP1 off board */
  DSK6713_rset(DSK6713_MISC,0x03);

  /* Open up serial port 0 */
  hMcbsp = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET);

  /* Sets up McBSP port 0  */
  MCBSP_config(hMcbsp,&ConfigLoopback);  

  /* Starts McBSP0 */
  MCBSP_start(hMcbsp, MCBSP_RCV_START | MCBSP_XMIT_START |               
          MCBSP_SRGR_START| MCBSP_SRGR_FRAMESYNC, 0x00001000);

  /* Interrupt setup */
  IRQ_globalDisable(); // globally disable interrupt
  IRQ_enable(IRQ_EVT_RINT0); // enable receiver0 interrupt event
  IRQ_globalEnable(); // globally enable interrupt
 
  /* wait until the transmitter is ready for a sample then write to it */
  while (!MCBSP_xrdy(hMcbsp));      
  MCBSP_write(hMcbsp,0x00000000);  // select channel 0 in the 1st read
 
}

/* Interrupt routine when rrdy is set */
void rintHWI (void)  
  {

  if (signal == 0)   // read from channel 0
  {  
  x_buf[n] = MCBSP_read(hMcbsp);   // read and save in the 1st buffer

  MCBSP_write(hMcbsp,0x0000FFFF);   // read from channel 1 in the next interrupt call
 
  signal = 1;       // toggle the channel selection
 
  DSK6713_wait(1);    
  }

  else             // read from channel 1
  {  
  x_buf1[n] = MCBSP_read(hMcbsp);   // read and save in the 2nd buffer

  MCBSP_write(hMcbsp,0x00000000);   // read from channel 0 in the next interrupt call
 
  signal = 1;       // toggle the channel selection
 
  DSK6713_wait(1);    

  n++;

  if (n>499)
  n=0;
  }
 
  }

Furthermore, if I change the transmit frame sync signal generation to DXR-to-XSR copy, no frame sync signal is observed at the oscilloscope. Can anyone tell me why is this happening? Your help is highly appreciated, cheers


Neo

  • Dear Yun,
    We are working on your post.
  • Dear Sir,

           Is there any clue available to my problem?

           Thank you.

    Regards,

    Yun

     

  • Hi,

    You must set XDATDLY=RDATDLY=1.  You must also set FSGM=0.  These requirements are stated in Section 9.1 of the McBSP Reference Guide as below.  Please review the information carefully.

    http://www.ti.com/lit/ug/spru580g/spru580g.pdf

    Also, have you changed clock bit polarity? If not, try change the clock bit polarity and check.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • Dear Sir,

    Thank you for your response, sorry for the long silence from me. I have already set all the McBSPs registers according to the McBSP reference guide, but the channel selection signal is still not toggling correctly. In fact, I have realized that even with 1 channel (that is, sending only either 0xFFFF or 0x0000), the data that I obtain from the McBSP DRR is only sampled at about 900 kSPS, which is only half of 2 MSPS as stated by the ADS7945EVM specification.

    I am suspecting that the total execution cycle of my interrupt routine might be too long that it has missed some DRR data ready interrupt call. Therefore, I have ventured into direct memory access of the DRR through EDMA channel in order to reduce the CPU MIPs. However, the code is has not been working correctly when the McBSP is running in SPI mode. Here I have included the code for you to check the settings of the McBSP and EDMA channel or even try run. I have not used DSP/Bios for this program, and has avoided interrupt service to simplify the code, just to make sure that the McBSP in SPI mode is working well with the EDMA channel.

    Furthermore, is there any example of McBSP in SPI mode working with EDMA for C6713dsk? I have tried to search but cannot find any, it will be really helpful to have a working example for me to see working configuration.
    Have already totally run out of idea on this problem, will be absolutely thankful if the Gurus and Masterminds out there can show me the way. Thank you.


    #include <stdio.h>
    #include <math.h>

    #include <csl.h>

    #include <csl_edma.h>
    #include <csl_mcbsp.h>

    #include "dsk6713.h"
    #include "dsk6713_dip.h"
    #include "DAC_input.c"


    #define BUFFSIZE 500


    Uint16 x_bufRcv[BUFFSIZE];
    Uint16 x_bufXmt[BUFFSIZE];
    MCBSP_Handle hMcbsp;
    EDMA_Handle hEdmaXmt;
    EDMA_Handle hEdmaRcv;
    void initEdma(void);
    /* create a config structure for digital loopback mode */


    EDMA_Config gEdmaConfigXmt = {
    EDMA_OPT_RMK(
    EDMA_OPT_PRI_LOW, // Priority
    EDMA_OPT_ESIZE_16BIT, // Element size
    EDMA_OPT_2DS_NO, // 2 dimensional source
    EDMA_OPT_SUM_INC, // Src update mode
    EDMA_OPT_2DD_NO, // 2 dimensional dest
    EDMA_OPT_DUM_NONE, // Dest update mode
    EDMA_OPT_TCINT_NO, // Cause EDMA interrupt
    EDMA_OPT_TCC_OF(0), // Transfer Complete Code
    EDMA_OPT_LINK_NO, // Enable link parameters
    EDMA_OPT_FS_NO // Use frame sync
    ),
    EDMA_SRC_OF(x_bufXmt), // src address
    EDMA_CNT_OF(BUFFSIZE), // Count = buffer size
    EDMA_DST_OF(0), // dest address
    EDMA_IDX_OF(0), // frame/element index value
    EDMA_RLD_OF(0) // reload
    };

    EDMA_Config gEdmaConfigRcv = {
    EDMA_OPT_RMK(
    EDMA_OPT_PRI_LOW, // Priority
    EDMA_OPT_ESIZE_16BIT, // Element size
    EDMA_OPT_2DS_NO, // 2 dimensional source
    EDMA_OPT_SUM_NONE, // Src update mode
    EDMA_OPT_2DD_NO, // 2 dimensional dest
    EDMA_OPT_DUM_INC, // Dest update mode
    EDMA_OPT_TCINT_NO, // Cause EDMA interrupt
    EDMA_OPT_TCC_OF(0), // Transfer Complete Code
    EDMA_OPT_LINK_NO, // Enable link parameters
    EDMA_OPT_FS_NO // Use frame sync
    ),
    EDMA_SRC_OF(0), // src address
    EDMA_CNT_OF(BUFFSIZE), // Count = buffer size
    EDMA_DST_OF(x_bufRcv), // dest address
    EDMA_IDX_OF(0), // frame/element index value
    EDMA_RLD_OF(0) // reload
    };

    static MCBSP_Config ConfigLoopback = {



    /* Serial Port Control Register (SPCR) */

    MCBSP_SPCR_RMK(



    MCBSP_SPCR_FREE_YES,

    MCBSP_SPCR_SOFT_YES,

    MCBSP_SPCR_FRST_YES,

    MCBSP_SPCR_GRST_YES,

    MCBSP_SPCR_XINTM_XRDY,

    MCBSP_SPCR_XSYNCERR_NO,

    MCBSP_SPCR_XRST_YES,

    MCBSP_SPCR_DLB_OFF,

    MCBSP_SPCR_RJUST_RZF,

    MCBSP_SPCR_CLKSTP_DELAY,

    MCBSP_SPCR_DXENA_OFF,

    MCBSP_SPCR_RINTM_RRDY,

    MCBSP_SPCR_RSYNCERR_NO,

    MCBSP_SPCR_RRST_YES

    ),



    /* Receive Control Register (RCR) */

    MCBSP_RCR_RMK(

    MCBSP_RCR_RPHASE_SINGLE,

    MCBSP_RCR_RFRLEN2_OF(0),

    MCBSP_RCR_RWDLEN2_8BIT,

    MCBSP_RCR_RCOMPAND_MSB,

    MCBSP_RCR_RFIG_YES,

    MCBSP_RCR_RDATDLY_1BIT,

    MCBSP_RCR_RFRLEN1_OF(0),

    MCBSP_RCR_RWDLEN1_16BIT,

    MCBSP_RCR_RWDREVRS_DISABLE

    ),



    /* Transmit Control Register (XCR) */

    MCBSP_XCR_RMK(



    MCBSP_XCR_XPHASE_SINGLE,

    MCBSP_XCR_XFRLEN2_OF(0),

    MCBSP_XCR_XWDLEN2_8BIT,

    MCBSP_XCR_XCOMPAND_MSB,

    MCBSP_XCR_XFIG_YES,

    MCBSP_XCR_XDATDLY_1BIT,

    MCBSP_XCR_XFRLEN1_OF(0),

    MCBSP_XCR_XWDLEN1_16BIT,

    MCBSP_XCR_XWDREVRS_DISABLE

    ),



    /*serial port sample rate generator register(SRGR) */

    MCBSP_SRGR_RMK(



    MCBSP_SRGR_GSYNC_FREE,

    MCBSP_SRGR_CLKSP_RISING,

    MCBSP_SRGR_CLKSM_INTERNAL,

    MCBSP_SRGR_FSGM_DXR2XSR,

    MCBSP_SRGR_FPER_OF(18),

    MCBSP_SRGR_FWID_OF(0),

    MCBSP_SRGR_CLKGDV_OF(2)

    ),



    MCBSP_MCR_DEFAULT, /* Using default value of MCR register */

    MCBSP_RCER_DEFAULT,/* Using default value of RCER register */

    MCBSP_XCER_DEFAULT,/* Using default value of XCER register */



    /* serial port pin control register(PCR) */

    MCBSP_PCR_RMK(



    MCBSP_PCR_XIOEN_SP,

    MCBSP_PCR_RIOEN_SP,

    MCBSP_PCR_FSXM_INTERNAL,

    MCBSP_PCR_FSRM_EXTERNAL,

    MCBSP_PCR_CLKXM_OUTPUT,

    MCBSP_PCR_CLKRM_INPUT,

    MCBSP_PCR_CLKSSTAT_0,

    MCBSP_PCR_DXSTAT_0,

    MCBSP_PCR_FSXP_ACTIVELOW,

    MCBSP_PCR_FSRP_ACTIVEHIGH,

    MCBSP_PCR_CLKXP_RISING,

    MCBSP_PCR_CLKRP_FALLING

    )

    };


    /* ---------------------------------------------------------------------------*/

    void main() {

    //int y[500];
    Uint16 n=0;


    /* Initialize the chip support library, must when using CSL */

    DSK6713_init();
    DSK6713_DIP_init();
    CSL_init();


    /* set MCBSP0 and MCBSP1 off board */
    DSK6713_rset(DSK6713_MISC,0x03);

    /* Let's open up serial port 1 */

    hMcbsp = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET);


    for (n=0; n<=BUFFSIZE; n++){

    x_bufXmt[n] = 0xFFFF;
    }


    /* We'll set it up for digital loopback, 32bit mode. We have */

    /* to setup the sample rate generator to allow self clocking. */

    MCBSP_config(hMcbsp,&ConfigLoopback);


    initEdma();
    /* Now that the port is setup, let's enable it in steps. */

    MCBSP_start(hMcbsp, MCBSP_RCV_START | MCBSP_XMIT_START |

    MCBSP_SRGR_START| MCBSP_SRGR_FRAMESYNC,

    0x00001000);


    /* wait until the transmitter is ready for a sample then write to it */
    while (!MCBSP_xrdy(hMcbsp));
    MCBSP_write(hMcbsp,0x0000FFFF);

    while (1){

    }


    }


    void initEdma(void)
    {

    hEdmaRcv = EDMA_open(EDMA_CHA_REVT0, EDMA_OPEN_RESET);

    gEdmaConfigRcv.src = MCBSP_getRcvAddr(hMcbsp);
    EDMA_config(hEdmaRcv, &gEdmaConfigRcv);


    hEdmaXmt = EDMA_open(EDMA_CHA_XEVT0, EDMA_OPEN_RESET);

    gEdmaConfigXmt.dst = MCBSP_getXmtAddr(hMcbsp);
    EDMA_config(hEdmaXmt, &gEdmaConfigXmt);


    EDMA_enableChannel(hEdmaRcv);
    EDMA_enableChannel(hEdmaXmt);
    }