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.

TMS320C5535: Configuring TMS320C5535 as I2C slave interrupt

Part Number: TMS320C5535

I have been attempting to configure a TMS320C5535 as an I2C slave device. I am developing on an ezDSP5535 platform.  It appears I am not setting up the I2C interrupt properly, but at this point have exhausted any ideas from reading the literature. Basically, if I set up my code with the ICOAR at a slave address, I never hit a breakpoint in my ISR for the I2C. However, if I watch the SDA and SCL lines with a logic analyzer, the DSP pulls down the SDA and SCL lines if my master processor sends the slave address. If the master processor sends to other addresses, the SDA and SCL lines are not pulled down by my code and I can successfully observe other I2C activity by the master processor.  In either case, a breakpoint set at the beginning of my I2C interrupt routine is never hit. Can someone please help? Thank you.

4431.main.c
/*****************************************************************************/
/*                                                                           */
/* FILENAME                                                                  */
/* 	 main.c                                                                  */
/*                                                                           */
/* DESCRIPTION                                                               */
/*                                                                           */
/*   Vista Therapeutics, DSP lockin amplifier                                */
/*                                                                           */
/*****************************************************************************/
//Note that I2C interrupt service routines are at end of this file due to weird
//compiler error if csl_intc was used as an include when they were in a separate file


#include "stdio.h"
#include "cslr_cpu.h"
#include "csl_intc.h"
#include "usbstk5505.h"
#include "usbstk5505_gpio.h"
#include "usbstk5505_i2c.h"
#include "aic3204.h"		//keep for now, may include I2C initialization details
#include "PLL.h"
#include "IOpins.h"

#define One_msec_loop 9000   //1 msec loop time for a simple for loop when PLL at 100 MHz
#define twenty_eight_msec 28
#define twelve_usec 110  		//based on 9000 for 1 msec loop time (111 nsec/loop)
#define TrueLowInterval 2	//to reject short logic high glitches, adjust after measuring loop time
#define _40usec 137



inline void SyncADCs(void);
inline void GetADCReadings(void);
interrupt void gpio_isr(void);
interrupt void I2C_ISR(void);


void lockin_I2C_init(void);
void lockin_I2C_test(void);

extern void VECSTART(void);



unsigned Int16 u[12], v[12];

unsigned Int16 NW_drainQ[sizeNW_drain];
unsigned Int16 NW_sourceQ[sizeNW_source];
int cntADC;



static volatile Uint8 current_yn[_48bit];
static volatile Uint8 lockin_drain[_48bit];


/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  main( )                                                                 *
 *                                                                          *
 * ------------------------------------------------------------------------ */
void main( void ) 
{

int i, j, k;



     /* Initialize BSL */
    USBSTK5505_init( );
	
	/* Initialize PLL */
	pll_frequency_setup(100); 

	j = 0;
	k = 0;
	
		//Load them with byte test patterns {1,2,3,4,5,6} and {7,8,9,10,11,12}
	for (i=0; i < 6; i++)
	{
		*(current_yn+i) = i+1;
		*(lockin_drain+i) = i+6;
	}
	
	lockin_I2C_init();
	_enable_interrupts();
		
	lockin_I2C_test();
}



/**************************************************************
 I2C defines: configure as a slave transmitter
 
***************************************************************/
	//slave transmitter address
#define LockinSLA 0x60		    //lockin slave transmitter address is 0x60 - 0x6E, w/ lower 4 bits read from slot at runtime

	//commands
#define ReportSource 0x55		//cmd to lockin to report the source value (actually source*drain/2)
#define ReportDrain 0xAA		//cmd to lockin to report the source value (actually drain*drain/2)
#define ResetLockin 0x22		//cmd to lockin instructing it to reset (which clears old lockin queue and recalculates drain)

volatile int icntr;

static volatile Uint8 * TXP;



void lockin_I2C_init(void)
{
/******************************************************************************
 I2C setup
 Setup is as a slave transmitter
 Guidance is from the TMS320C5535 technical reference manual (SPRUH87D)
 p 317, sec 9.2.12.2 describes how to configure for slave receiver/transmitter
 step by step which is what this section does.
******************************************************************************/

	 IRQ_disableAll();
		
 /* Set the interrupt vector start address */
    IRQ_setVecs((Uint32)(&VECSTART));


	
	IRQ_plug( I2C_EVENT, &I2C_ISR);
	IRQ_clearAll();		//clear any pending interrupts

//step 1 says "enable clock from PSC level".
	SYS_PCGCR1 &= ~SYSCLKDIS;	//system clock active when this bit 0
	SYS_PCGCR1 &= ~I2CCG;		//I2C peripheral clock active when this bit 0
//step 2 reset the I2C
	ICMDR &= ~MDR_IRS;
//step 3
//set slave address, 7-bit
	ICMDR &= ~MDR_XA;
	ICOAR = 0x60; //0x61; //LockinSLA;	//in future, lower 4-bits will be OR-ed with slot ID
//step 4
//ICIMR enables interrupts for specific I2C peripheral occurrences. 
//Only 'AAS', the interrupt for DSP recognizing its own slave address is initially
//enabled. This then sets up a sequence of interrupts being enabled as:
//		-ICRRDY to detect the command byte that follows the slave address
//		-ICXRDY to detect when ICXRDY is ready for new data
//		-SCD: the stop bit is detected, which then sets AAS again for next occurrence
	ICIMR = ICIMR_AAS;
//step 5
//setup of the I2C prescaler (ICPSC register, p. 335 and p309 clocking diagram)
//This set the prescaled module clock which is described
//as requiring a range of 6.7-13.3 MHz. The clock source is totally unclear at this writing.
//I am following the USBSTK5505_I2C_init() code for the constant used which they state is 20
//for a 12 MHz clock. I don't know where this number comes from, it is not sensible for a 100 MHz
//overall clock, but am using it based on the assumption it must be right since there are other
//I2C devices on the ezDSP and they work, e.g. the AIC3204 codec.
//Step 5 however says the prescaled module clock freq = PLL1 output freq / (IPSC + 1)
//The PLL1 output freq is understood to be 100 MHz. A value of 20 gives 4.76 MHz, which is too slow
//for the required range given. By my calculation, PSC should be 7.33 for 12 MHz
	ICPSC = 020;
//step 6
//configure the I2C serial clock freq. Assuming a symmetrical high and low half cycle, 
//the operating freq is (step 5 freq)/(ICC + 10) where is ICC represents both ICCL and ICCH
//Again, there is a discrepancy between the USBSTK5505_I2C_init() code and my calculations.
//The code calls out a value of 20 for a SCL of 20 KHz. If step 5 is 12 MHz, this gives SCL
//of 400 KHz. If step 5 is 4.76 MHz, this gives SCL of 158.75 KHz. (p 326)
	ICCLKL = 20;
	ICCLKH = 20;
//step 7
//Configure the mode register ICMDR (p. 329)
	ICMDR = 0;
	ICMDR |= RM;   //data words continuously rec'd/transmitted until STP bit manually set
	ICMDR |= MDR_STT;  //monitor bus and transmit/rec'v in response to master commands
//step 8
	ICSTR = ICSTR;	//clear any pending interrupt flags by writing 1 to them
	while ( ICIVR )	//zero ICIVR by reading it 
		;
		
	ICDXR = current_yn[0];	//keep XSMT=0 from pulling SDA/SCA lines low
//release I2C from reset
	ICMDR |= MDR_IRS;
//step 9 
//clear any interrupts present
	ICSTR = ICSTR;	//clear any pending interrupt flags by writing 1 to them
	while ( ICIVR )	//zero ICIVR by reading it 
		;
//step 10
//Detect start condition and own address
		ICMDR |= MDR_STT;   //this was done in step 7 as well


		//enable CPU interrupts
	_enable_interrupts();
	//IRQ_globalEnable();
	
	icntr = 0;
	TXP = &lockin_drain[0];

}

void lockin_I2C_test(void)
{
		//verify ability to transmit over I2C as a slave transmitter
	icntr = 0;
	TXP = &lockin_drain[0];
	while (1)
	{
		SYS_GPIO_DATAOUT0 |= SetPin15;

		/*
		for (i=0; i < 2000; i++)
			for (j=0; j < One_msec_loop; j++)
				;
		*/
		//printf("icntr= %d\n", icntr);
	}
}

interrupt void I2C_ISR(void)
{	
	SYS_GPIO_DATAOUT0 &= ClearPin15;
		//determine the source of the interrupt
	if ( ICSTR & ICSTR_AAS )
	{
			//slave address rec'd
		icntr = 1;

			TXP = &current_yn[1];

	}
	else if ( ICSTR & ICXRDY )
	{
			//transmit requested data
		ICDXR = *(TXP+icntr++);
		if ( icntr == 6 )
			ICIMR = ICIMR_SCD;		
	}
	else if ( ICSTR & ICSTR_SCD)	//stop bit
		ICIMR = ICIMR_AAS;
	
		//clear the pending interrupt just processed
	ICSTR = ICSTR;
	
	SYS_GPIO_DATAOUT0 |= SetPin15;
	_enable_interrupts();
		
}



/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  End of main.c                                                           *
 *                                                                          *
 * ------------------------------------------------------------------------ */
usbstk5505.hIOpins.haic3204.hcsl_intc.hcslr_cpu.hPLL.h
usbstk5505_i2c.c
/*****************************************************************************/
/*                                                                           */
/* FILENAME                                                                  */
/* 	 usbstk5505_i2c.c                                                        */
/*                                                                           */
/* DESCRIPTION                                                               */
/*   Header file for i2c communications with codec on TMS320C5505 USB Stick.*/
/*                                                                           */
/*****************************************************************************/
/*
 *
 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
 * 
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

/*
 *  Copyright 2009 by Spectrum Digital Incorporated.
 *  All rights reserved. Property of Spectrum Digital Incorporated.
 */

/*
 *  I2C implementation
 *
 */
#include "usbstk5505_i2c.h"

static Int32 i2c_timeout = 0x7fff;

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_init( )                                                            *
 *                                                                          *
 *      Enable and initalize the I2C module                                 *
 *      The I2C clk is set to run at 20 KHz                                 *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 USBSTK5505_I2C_init( )
{
    I2C_MDR = 0x0400;             // Reset I2C
    I2C_PSC   = 20;               // Config prescaler for 12MHz
    I2C_CLKL  = 20;               // Config clk LOW for 20kHz
    I2C_CLKH  = 20;               // Config clk HIGH for 20kHz
    
    I2C_MDR   = 0x0420   ;        // Release from reset; Master, Transmitter, 7-bit address
    
    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_close( )                                                           *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 USBSTK5505_I2C_close( )
{
    I2C_MDR = 0;                      // Reset I2C
    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_reset( )                                                           *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 USBSTK5505_I2C_reset( )
{
    USBSTK5505_I2C_close( );
    USBSTK5505_I2C_init( );
    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_write( i2c_addr, data, len )                                       *
 *                                                                          *
 *      I2C write in Master mode                                            *
 *                                                                          *
 *      i2c_addr    <- I2C slave address                                    *
 *      data        <- I2C data ptr                                         *
 *      len         <- # of bytes to write                                  *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 USBSTK5505_I2C_write( Uint16 i2c_addr, Uint8* data, Uint16 len )
{
    Int32 timeout, i;

		//I2C_IER = 0x0000;
        I2C_CNT = len;                    // Set length
        I2C_SAR = i2c_addr;               // Set I2C slave address
        I2C_MDR = MDR_STT                 // Set for Master Write
                  | MDR_TRX
                  | MDR_MST
                  | MDR_IRS
                  | MDR_FREE;

        USBSTK5505_wait(10);              // Short delay

        for ( i = 0 ; i < len ; i++ )
        {
            I2C_DXR = data[i];            // Write

            timeout = i2c_timeout;
            do
            {
                if ( timeout-- < 0  )
                {
                    USBSTK5505_I2C_reset( );
                    return -1;
                }
            } while ( ( I2C_STR & STR_XRDY ) == 0 );// Wait for Tx Ready
        }

        I2C_MDR |= MDR_STP;             // Generate STOP

		USBSTK5505_waitusec(100);

        return 0;

}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_read( i2c_addr, data, len )                                        *
 *                                                                          *
 *      I2C read in Master mode                                             *
 *                                                                          *
 *      i2c_addr    <- I2C slave address                                    *
 *      data        <- I2C data ptr                                         *
 *      len         <- # of bytes to write                                  *
 *                                                                          *
 *      Returns:    0: PASS                                                 *
 *                 -1: FAIL Timeout                                         *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 USBSTK5505_I2C_read( Uint16 i2c_addr, Uint8* data, Uint16 len )
{
    Int32 timeout, i;

    I2C_CNT = len;                    // Set length
    I2C_SAR = i2c_addr;               // Set I2C slave address
    I2C_MDR = MDR_STT                 // Set for Master Read
              | MDR_MST
              | MDR_IRS
              | MDR_FREE;

    USBSTK5505_wait( 10 );            // Short delay

    for ( i = 0 ; i < len ; i++ )
    {
        timeout = i2c_timeout;

        //Wait for Rx Ready 
        do
        {
            if ( timeout-- < 0 )
            {
                USBSTK5505_I2C_reset( );
                return -1;
            }
        } while ( ( I2C_STR & STR_RRDY ) == 0 );// Wait for Rx Ready

        data[i] = I2C_DRR;            // Read
    }

    I2C_MDR |= MDR_STP;               // Generate STOP

	USBSTK5505_waitusec(10);
    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  End of usbstk5505_i2c.c                                                 *
 *                                                                          *
 * ------------------------------------------------------------------------ */



I've also attached the source files, but the I2C initialization and interrupt setup code is as follows:

void lockin_I2C_init(void)
{
/******************************************************************************
 I2C setup
 Setup is as a slave transmitter
 Guidance is from the TMS320C5535 technical reference manual (SPRUH87D)
 p 317, sec 9.2.12.2 describes how to configure for slave receiver/transmitter
 step by step which is what this section does.
******************************************************************************/

     IRQ_disableAll();
        
 /* Set the interrupt vector start address */
    IRQ_setVecs((Uint32)(&VECSTART));


    
    IRQ_plug( I2C_EVENT, &I2C_ISR);
    IRQ_clearAll();        //clear any pending interrupts

//step 1 says "enable clock from PSC level".
    SYS_PCGCR1 &= ~SYSCLKDIS;    //system clock active when this bit 0
    SYS_PCGCR1 &= ~I2CCG;        //I2C peripheral clock active when this bit 0
//step 2 reset the I2C
    ICMDR &= ~MDR_IRS;
//step 3
//set slave address, 7-bit
    ICMDR &= ~MDR_XA;
    ICOAR = 0x60; //0x61; //LockinSLA;    //in future, lower 4-bits will be OR-ed with slot ID
//step 4
//ICIMR enables interrupts for specific I2C peripheral occurrences.
//Only 'AAS', the interrupt for DSP recognizing its own slave address is initially
//enabled. This then sets up a sequence of interrupts being enabled as:
//        -ICRRDY to detect the command byte that follows the slave address
//        -ICXRDY to detect when ICXRDY is ready for new data
//        -SCD: the stop bit is detected, which then sets AAS again for next occurrence
    ICIMR = ICIMR_AAS;
//step 5
//setup of the I2C prescaler (ICPSC register, p. 335 and p309 clocking diagram)
//This set the prescaled module clock which is described
//as requiring a range of 6.7-13.3 MHz. The clock source is totally unclear at this writing.
//I am following the USBSTK5505_I2C_init() code for the constant used which they state is 20
//for a 12 MHz clock. I don't know where this number comes from, it is not sensible for a 100 MHz
//overall clock, but am using it based on the assumption it must be right since there are other
//I2C devices on the ezDSP and they work, e.g. the AIC3204 codec.
//Step 5 however says the prescaled module clock freq = PLL1 output freq / (IPSC + 1)
//The PLL1 output freq is understood to be 100 MHz. A value of 20 gives 4.76 MHz, which is too slow
//for the required range given. By my calculation, PSC should be 7.33 for 12 MHz
    ICPSC = 020;
//step 6
//configure the I2C serial clock freq. Assuming a symmetrical high and low half cycle,
//the operating freq is (step 5 freq)/(ICC + 10) where is ICC represents both ICCL and ICCH
//Again, there is a discrepancy between the USBSTK5505_I2C_init() code and my calculations.
//The code calls out a value of 20 for a SCL of 20 KHz. If step 5 is 12 MHz, this gives SCL
//of 400 KHz. If step 5 is 4.76 MHz, this gives SCL of 158.75 KHz. (p 326)
    ICCLKL = 20;
    ICCLKH = 20;
//step 7
//Configure the mode register ICMDR (p. 329)
    ICMDR = 0;
    ICMDR |= RM;   //data words continuously rec'd/transmitted until STP bit manually set
    ICMDR |= MDR_STT;  //monitor bus and transmit/rec'v in response to master commands
//step 8
    ICSTR = ICSTR;    //clear any pending interrupt flags by writing 1 to them
    while ( ICIVR )    //zero ICIVR by reading it
        ;
        
    ICDXR = current_yn[0];    //keep XSMT=0 from pulling SDA/SCA lines low
//release I2C from reset
    ICMDR |= MDR_IRS;
//step 9
//clear any interrupts present
    ICSTR = ICSTR;    //clear any pending interrupt flags by writing 1 to them
    while ( ICIVR )    //zero ICIVR by reading it
        ;
//step 10
//Detect start condition and own address
        ICMDR |= MDR_STT;   //this was done in step 7 as well


        //enable CPU interrupts
    _enable_interrupts();
    //IRQ_globalEnable();
    
    icntr = 0;
    TXP = &lockin_drain[0];

}

And the ISR code is as follows:

interrupt void I2C_ISR(void)
{    
    SYS_GPIO_DATAOUT0 &= ClearPin15;
        //determine the source of the interrupt
    if ( ICSTR & ICSTR_AAS )
    {
            //slave address rec'd
        icntr = 1;

            TXP = &current_yn[1];

    }
    else if ( ICSTR & ICXRDY )
    {
            //transmit requested data
        ICDXR = *(TXP+icntr++);
        if ( icntr == 6 )
            ICIMR = ICIMR_SCD;        
    }
    else if ( ICSTR & ICSTR_SCD)    //stop bit
        ICIMR = ICIMR_AAS;
    
        //clear the pending interrupt just processed
    ICSTR = ICSTR;
    
    SYS_GPIO_DATAOUT0 |= SetPin15;
    _enable_interrupts();
        
}

  • Hi Ron,

    I've forwarded this to the c55x software experts. Their feedback should be posted here.

    BR
    Tsvetolin Shulev

  • Thank you Tsvetolin. Do you know how long they generally take to respond? This design issue is in the critical path to finishing this project. Is there a direct way to contact them?
  • Ron,
    Could you please take a look at this I2C slave implementation on the C5545. This example is between an MSP430 and the C5545 Booster Pack, but it gives and example on how things should be setup. The C5535 and 45 are similar devices.

    C:\ti\c55_lp\c55_csl_3.07\demos\out_of_box\c5545\c5545bp_software_01.01.00.00\source_code\c55xx_diagnostics\board\diag\i2c_dsp_msp_test\dsp_slave_msp_master\src\i2c_dsp_slave_msp_master.c

    Hope this helps get past the issue.

    Lali
  • Thank you, I will look at it. However, has *anyone* looked at the code I supplied? This is not a hobby for us, this is a critical path element of a product development effort and it has been nearly two weeks for a reply that gives me a homework assignment instead of an actual direct analysis of the problem in my system which has been my experience in the past. If this example does not solve my problem, is there a phone number or a direct email address of an FAE who can help RAPIDLY expedite this problem for our company?

  • I just looked... is this a path on your hard drive? There is no way to get to this.
  • Ron,

    Do you have the C55x CSL installed on your PC?
    Yes, this is a path on my HD after the CSL has been installed.
    software-dl.ti.com/.../index_FDS.html

    Lali
  • This does NOT resolve my issue. Please look at my initial *detailed* question with accompanying code. I need to have an I2C interrupt service slave requests for data and it needs to execute quickly. As I stated, it seems clear my I2C interrupt is not executing, but something must be right about my I2C setup because if the ICOAR address is sent by the master, the SCL and SDA data lines get pulled down. If the ICOAR gets set to a different address than the one that's set, I2C traffic from the master is not disrupted. I suspect the lines get pulled down because the ICDXR register is empty because the I2C interrupt doesn't trip and re-load it (ICDXR is pre-loaded in my setup code). Additionally, this reference code uses calls to a "black box" CSL_FINS function w/ no visibility to the register bit twiddling it is doing inside. I have waded through about a dozen TI reference manuals comprising thousands of pages. I am at the end of my patience with TI. Can I please be given direct contact info for an FAE with direct knowledge of how to do this???
  • Ron,

    Apologies for the frustrations. E2E is the best route to get support, but clearly has not solved your problem. Let me take a closer look at your code and follow-up.

    Are you basing your code on the CSL that I reffered to above?

    Lali
  • Lali,

    Thank you for your help. There are comments throughout the code and particularly in the I2C setup section for virtually each line describing the page and section # in each SPRU document the information came from.
  • Ron,

    Ok, understood.
    Just for future reference, would advise using the C5000 CSL as your development code base since it is better supported and has drivers, etc for the various peripherals.

    Also, to clarify, you have other I2C devices on the bus that can be successfully accessed by the master processor, but just the C5535 cannot be accessed?

    Lali
  • Yes, that's correct. There's a DAC on the line which works fine with concurrent I2C commands from the master uP on the same lines. The 5535 appears to respond when it's slave address arrives (have it set to 0x60) by pulling the SDA and SCL lines down, but the ISR breakpoint is not tripped indicating the I2C ISR is not fully set up right. If I set the ICOAR to a different number (0x61), the SDA and SCL lines don't get pulled down.

  • Ron,

    You enabled receive interrupts (ICIMR = ICIMR_AAS)? What is the definition of _enable_interrupts() in your code?

    If you take a look at the CSL example I was referring to earlier, here are the CSL steps to configure slave mode.

    static TEST_STATUS run_i2c_mspmst_dspslv_test(void *testArgs)
    {
    	Int16  retVal;
    
    	Uint16  index, count;
    
    	/* Initialize I2C module */
    	retVal = I2C_init(CSL_I2C0);
    	if(retVal != CSL_SOK)
    	{
    		C55x_msgWrite("I2C Init Failed!!\n\r");
    		return (TEST_FAIL);
    	}
    
    	/* I2C in reset state */
    	CSL_FINS(CSL_I2C_0_REGS->ICMDR,I2C_ICMDR_IRS,0);
    
    	/* I2C in Out of reset state */
    	CSL_FINS(CSL_I2C_0_REGS->ICMDR,I2C_ICMDR_IRS,1);
    
    	/* I2C Set Mode as Slave */
    	CSL_FINS(CSL_I2C_0_REGS->ICMDR,I2C_ICMDR_MST,0);
    
    	/* I2C Set Address mode as 7-bit */
    	CSL_FINS(CSL_I2C_0_REGS->ICMDR,I2C_ICMDR_XA,0);
    
    	/* I2C Set own Address */
    	CSL_FINS(CSL_I2C_0_REGS->ICOAR,I2C_ICOAR_OADDR,I2C_SLAVE_ADDRESS);
    
    	/* Enable Receive Interrupt */
    	CSL_FINS(CSL_I2C_0_REGS->ICIMR,I2C_ICIMR_ICRRDY,1);
    
    	/*Setting the Bus to Busy state*/
    	CSL_FINS(CSL_I2C_0_REGS->ICSTR,I2C_ICSTR_BB,1);
    
    	/*Setting the Data Ready bit to not Ready*/
    	CSL_FINS(CSL_I2C_0_REGS->ICSTR,I2C_ICSTR_ICRRDY,0);
    
    	C55x_msgWrite("Waiting for the MSP to transfer data...\n\n\r");
    
        /*Wait till the Bus is free for transfer */
        do {
          response=CSL_FEXT (CSL_I2C_0_REGS->ICSTR,I2C_ICSTR_BB);
        }while((response & 0x1)!=0x0);
    
        /*Receive 64 bytes/Page Data from the Master*/
        for(i=0;i<I2C_SLV_DATA_SIZE;i++) {
    		do {/*Check if Receive Data Register is Ready */
    		response=CSL_FEXT(CSL_I2C_0_REGS->ICSTR,I2C_ICSTR_ICRRDY);
    		}while((response & 0x01)==0);
    	    /*Read data from Receive Data Register */
    		i2cSlaveDataBuf[i] = CSL_FEXT(CSL_I2C_0_REGS->ICDRR,I2C_ICDRR_D);
    	}
    
        C55x_msgWrite("Data Received from Master:\n\r");
    	for (index = 0; index < I2C_SLV_DATA_SIZE; )
    	{
    		for (count = 0; count < I2C_SLV_DATA_BLOCK_SIZE; count++)
    		{
    			C55x_msgWrite("0x%x\t", i2cSlaveDataBuf[index+count]);
    		}
    		C55x_msgWrite("\n\r");
    
    		index += I2C_SLV_DATA_BLOCK_SIZE;
    
    		C55x_delay_msec(800);
    	}
    
    	/* Compare the data received */
    	/* For ease of verification it is assumed that master sends 16 bytes of data
    	 * from 0 to 15. Same data should be sent by master test implementation for
    	 * successful execution of the test */
    	for (index = 0; index < I2C_SLV_DATA_SIZE; index++)
    	{
    		if(i2cSlaveDataBuf[index] != index)
    		{
    			C55x_msgWrite("\n\rData Received from Master Mismatched with Expected Data at Offset %d\n\r", index);
    			return (TEST_FAIL);
    		}
    	}
    
    	C55x_msgWrite("\n\rData Received from Master Matched with Expected Data!\n\r");
    
    	/* Reset the I2C Module */
    	CSL_FINS(CSL_I2C_0_REGS->ICMDR,I2C_ICMDR_IRS,0);
    
    	return (TEST_PASS);
    
    }

    Also, I have attached a .out file of the same DSP(Slave)-MSP430(master) with address 0x60 configured in the binary. Do you think you could try this on your setup to see if the DSP responds? Not sure if it will work, just an experiment.

    its tough to debug your code since its not using any CSL calls and just raw pokes of the registers based on the TRM. Also, is there a way to reproduce it? We typically go on what the APIs that the CSL spikes out and recommend customers to use those APIs.

    Lali

    /cfs-file/__key/communityserver-discussions-components-files/791/4466.i2c_5F00_dsp_5F00_slave_5F00_msp_5F00_master.out