Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] dsPIC30F I2C not working - INTERRUPT

Status
Not open for further replies.

cjusto

Newbie level 3
Joined
May 11, 2006
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,323
Hello!

I'm working on a project using:
-MPLAB X IDE V3.00, XC16 Compiler
-MPLAB ICD3 (In-Circuit Debugger)
-dsPIC30F3010

I need this PIC (as a slave) to communicate with a chipkit (as a master), but the I2C interrupt is not happening.
After that I tried to use de Debug function, but with no results.

I am able to program the PIC and it runs, oscillator is ok and some outputs I tested are working fine.

The config used is this:

Code:
_FOSC(XT & CSW_FSCM_OFF) ; //_PLL4); 
_FWDT(WDT_OFF);              // Watchdog Timer Enabled/disabled by user software
_FGS(CODE_PROT_OFF & GWRP_OFF );
_FBORPOR(PWRT_64 & MCLR_EN & PBOR_ON & BORV20);
#define FCY 4000000UL
_FICD (ICS_PGD1);

#include <libpic30.h>
#include <xc.h>
#include<i2c.h>
#include "I2CSlaveDrv.h"


in the main function this function is called, and it runs fine:
Code:
void i2c1_init(void)
{
	#if !defined(USE_I2C_Clock_Stretch)
		I2CCON = 0x8000;	//Enable I2C module        
	#else
		I2CCON = 0x9040;	//Enable I2C module, enable clock stretching
	#endif

	I2CADD = 0x50;			// 7-bit I2C slave address must be initialised here. 
    
    IFS0=0;
//	RAMPtr = &RAMBuffer[0];	//set the RAM pointer and points to beginning of RAMBuffer
	Flag.AddrFlag = 0;	//Initlize AddFlag
	Flag.DataFlag = 0;	//Initlize DataFlag
	   
    _SI2CIE = 1;
}


and this is the interrupt function, the one that never worked here:
Code:
void __attribute__((interrupt,no_auto_psv)) _SI2CInterrupt (void)
{
	unsigned char Temp;	//used for dummy read
      
     _RB0 = 1;
    
	if((I2CSTATbits.R_W == 0)&&(I2CSTATbits.D_A == 0))	//Address matched
		{
			Temp = I2CRCV;		//dummy read
			Flag.AddrFlag = 1;	//next byte will be address
		}
	else if((I2CSTATbits.R_W == 0)&&(I2CSTATbits.D_A == 1))	//check for data	
		{
			if(Flag.AddrFlag)
			{
				Flag.AddrFlag = 0;	
				Flag.DataFlag = 1;	//next byte is data
				RAMPtr = RAMPtr + I2CRCV;
				#if defined(USE_I2C_Clock_Stretch)
					I2CCONbits.SCLREL = 1;	//Release SCL1 line
				#endif
			}
			else if(Flag.DataFlag)
			{
				*RAMPtr = (unsigned char)I2CRCV;// store data into RAM
				Flag.AddrFlag = 0;//end of tx
				Flag.DataFlag = 0;
				RAMPtr = &RAMBuffer[0];	//reset the RAM pointer
				#if defined(USE_I2C_Clock_Stretch)
					I2CCONbits.SCLREL = 1;	//Release SCL1 line
				#endif
			}
		}
	else if((I2CSTATbits.R_W == 1)&&(I2CSTATbits.D_A == 0))
	{
		Temp = I2CRCV;
		I2CTRN = *RAMPtr;	//Read data from RAM & send data to I2C master device
		I2CCONbits.SCLREL = 1;	//Release SCL1 line
		while(I2CSTATbits.TBF);//Wait till all 
		RAMPtr = &RAMBuffer[0];	//reset the RAM pointer
	}
	_SI2CIF = 0;	//clear I2C1 Slave interrupt flag
    
    
}


This code is one of the microchips code examples.

Where I am making something wrong?

Any ideia what I can try out?

Thank You.
 

Hi,

Are you sure the chipkit is working ok?
Did you check signal lines, especially slave address?

Klaus
 

Hi,

Are you sure the chipkit is working ok?
Did you check signal lines, especially slave address?

Klaus

Hi Klaus.

thank You for your quick reply.

i've successfully tested this chipkit "talking" to another chipkit.

for the chipkit i'm using mpide, and using it's library example "master writer".
Code:
 Wire.beginTransmission(40); // transmit to device #40

For the address I'm assuming the 40 on the master, and the slave is 0x50, which would be 40 excluding the R/W bit.
besides this I tested other adresses, with no success.

Am I mistaken on this approach?

Thank You.
 

Hi,

One time you talk about 0x50 (this is hex and means 80 decimal).
The other addres you use 40. This is decimal.

Maybe you mix hex and decimal values...

Klaus
 

Hi!

well, i know that 0x50 is 80 in decimal. But I've read somewhere that the address is 0x50 ('1010000'), would mean a 40 in decimal, the same as 0x28 ('101000'), taking out the R/W bit.

Is this a missinterpretation?

Still, i've tried that address already and the interrupt never "triggers".

Thank You.
 

The "confusion" might arise because the data sheet states that peripheral compares the address with the lower 7 bits of the I2CADD register value. Therefore the I2CADD register should contain the actual address (7 or 10 bit as appropriate).
When the I2C bit stream is constructed, the address is in the top 7 bits of the appropriate part of the bit stream with the LSB begin the read/write bit.
Therefore 0x50 would be what is in the bit stream BUT 0x28 is what should be put into the I2CADD register.
I just did a quick check in the Errata for that device and there are a few I2C items but none seem to apply to this situation.
Also, I had a quick look at the FRM I2C section for this device and there are a number of bits in I2CxCONL and I2CxCONH that would appear to control the actual conditions that will trigger the interrupts and I can't see those begin set in your code. There are 191 appearances of the "interrupt" in the FRM and there seems to be a good description of how to set the peripheral up to be an I2C slave.
Susan
 

Hi,

well, i know that 0x50 is 80 in decimal. But I've read somewhere that the address is 0x50 ('1010000'), would mean a 40 in decimal, the same as 0x28 ('101000'), taking out the R/W bit.

You might be correct. But I recommend you to use just one inerpretetion. Not mixing hex and decimal and using only one alignment method, else it leads to confusion.

If two datasheets state the addresses in different format, then describe the In the header of your program.

Klaus
 

Hi!

Thank You for all the help.

at this time I've been able to see this working.

I used 0x10 as slave address. It worked with another dsPIC, instead of my dsPIC30F3010 I used a dsPIC30F3011.
It worked instantly, this means my code was ok.

I've tested with chipkit using both, master writer and master reader, and the interrupt is triggered.

So, may be that as i've read in a post somewhere (I'm trying to find that post) there is a problem on the flag registers on the 30F3010, flaging an overflow wich disables the correct start condition detection.

Thank You,
Cristiano
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top