CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

dspic33 i2c slave resets on bad i2c address

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

dspic33 i2c slave resets on bad i2c address
PostPosted: Fri Aug 17, 2012 9:25 am     Reply with quote

I'm using a dsPIC33FJ128MC804 as an i2c slave. To test it, I'm using a pickit serial analyzer. The application is simple, it emulates eeprom: write a 16-bit address, read as many bytes back as needed.

It all works perfectly when there is a single master (pickit analyzer) and single slave (my dspic33 device) and both are set to the same address. I understand the i2c protocol, and it's doing exactly what I expect when actually moving data around on the bus. (By the way, the pickit analyzer refers to addresses with 8-bits, so i2c addr 0x54 is treated as 0xA8 to write and 0xA9 to read.)

But if the master (pickit analyzer) sends messages on a different address, the slave (my dspic33 device) resets. It should ignore the incorrect address and simply do nothing.

The WDT is disabled. Setting a breakpoint at the start of the i2c interrupt never causes a break. When running with the ICD3 debugger, the code breaks at address zero, i.e. reset. When running standalone, the device restarts.

A couple of snippets of code:

in the .h file:
Code:

//i2c - this device is an i2c slave, external device is master
#use i2c(force_hw,slave,i2c1,restart_wdt,stream=sI2C)


my interrupt routine:
Code:

#int_si2c
void I2C_isr(void)
   {
   i2c_state = i2c_isr_state();                     // is actually i2c packet byte count

   if((i2c_state == 0 ) || (i2c_state == 0x80))   // first byte, with or without write bit set, is i2c address
     i2c_read(sI2C);                                       // read i2c address, always a match so no need to compare

   if(i2c_state >= 0x80)                           // if write bit is set, send dmx channel data
      {
      i2c_write(sI2C,dmxInput[(i2c_dmxAddr + i2c_state - 0x80) & 511]); // dmx address + byte count, write bit cleared, limit range to 511
      }

   else if (i2c_state > 0)                        // if write bit is set, send dmx channel data
      {
      i2c_data = i2c_read(sI2C);
      switch (i2c_state)
         {
         case 1:                                 //first byte is MSB of dmx address
            i2c_dmxAddrH = i2c_data & 1;      //limit to 0 or 1, dmx channels only use 9 bits, this is the 9th
            break;
         case 2:                                 //second byte is LSB of dmx address
            i2c_dmxAddrL = i2c_data;            
            i2c_dmxAddr = ((unsigned int16)i2c_dmxAddrH * 256) + i2c_dmxAddrL;   //construct the full dmx address
            break;
         }
      }
   }

(The variables are declared at the top of code to be global, for easier debugging.)

As i said, this all works perfectly. The problem is when the address used by the master is wrong. The slave should simply ignore it, but instead the device resets.

Am I doing something wrong? Or is this a CCS problem?

Thank you for your time!
Jim
jeremiah



Joined: 20 Jul 2010
Posts: 1354

View user's profile Send private message

PostPosted: Fri Aug 17, 2012 3:04 pm     Reply with quote

You are not setting your slave address based on the code you provided. Look at #use i2c() in the manual for details.
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

PostPosted: Fri Aug 17, 2012 3:56 pm     Reply with quote

Sorry, the i2c address is being set near the beginning of Main. Here are some additional code snippets to eliminate ambiguity:

Code:

   unsigned int8 i2cAddr = 0xa8;


Code:

   I2C_SlaveAddr(sI2C,i2cAddr >> 1);   //specified pickit address is 8-bit format (incl. write bit as bit0)
   enable_interrupts(INT_si2c);


Jim
jeremiah



Joined: 20 Jul 2010
Posts: 1354

View user's profile Send private message

PostPosted: Sat Aug 18, 2012 9:05 am     Reply with quote

Next thing to check is the status and control registers for your I2C module. Print those out and see what options are turned on by default. I wonder if you have general call turned on for example and are getting bad array accesses.

Furthermore, you really need to read the forum guidelines and the newbies post and post the information they specify as you are not providing us the information we need to help you fully. It's hard to troubleshoot your problem on this end if you don't provide the needed info and code.
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

PostPosted: Sat Aug 18, 2012 9:24 am     Reply with quote

Thanks, jeremiah.

I fully agree with you; in another instance I would be the guy saying the same thing in a reply.

I've already gone down the road you suggest, checking and watching the hardware i2c registers. There's nothing wrong that I can see.

Now I'm tracing through the sequence of asm instructions produced by the compiler, looking for anything that doesn't agree with Microchip's recommended sequence of events for i2c setup.

[whine]
Soon I will give up on this lunacy and write my own i2c routines, just so I know exactly what they are doing -- much as I would do with C30. This has happened to me too many times now: I start a simple little project in CCS C because it should be quick and easy using the built-in routines, then I end up wasting a metric tonne of time trying to debug those built-in routines because they don't work right.
[/whine]

When I started this thread I was hoping someone would point me to an errata note I'd missed, or something else known and documented that causes the symptoms described.

Since that's not the case, I'll continue with my own troubleshooting. When I find the answer, I'll come back here and post an update to help the next guy.

Thanks again,
Jim
jeremiah



Joined: 20 Jul 2010
Posts: 1354

View user's profile Send private message

PostPosted: Sat Aug 18, 2012 11:39 am     Reply with quote

Try a simple program in your project (add fuses and change #use delay() to fit your setup ):

Code:

#case
#include <33FJ128MC804.h>

//put your fuses here

#use delay(clock=22118400) //change to fit your setup


#use i2c(force_hw,slave,I2C1,restart_wdt,address=0xA8,stream=I2C_STREAM)

//set these pins to something available
#pin_select U1TX=PIN_B3
#pin_select U1RX=PIN_B4
#use rs232(UART1,errors,bits=8,stop=1,parity=N,baud=9600)

#INT_IC1
void i2c_isr(){
   unsigned int8 state;
   unsigned int8 value;
   
   state = i2c_isr_state(I2C_STREAM);
   
   if(state <= 0x80){
      value = i2c_read(I2C_STREAM);
   }
   if(state >= 0x80){
      i2c_write(I2C_STREAM,0x12);
   }
}

void main(void){

   printf("\r\nStart\r\n");

   enable_interrupts(INT_IC1);
   enable_interrupts(INTR_GLOBAL);
   
   while(TRUE){
      restart_wdt();
   }

}



Run that and try talking to it with both the a8 address and a wrong address. See if it resets. If it doesn't, then put in your version of the ISR and see if it resets. If it doesn't, add in some other parts of your code.
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Sat Aug 18, 2012 2:44 pm     Reply with quote

Er. The obvious thing is the address.
Comments inline.
Code:

 unsigned int8 i2cAddr = 0xa8; //This is already an 8bit address   

 I2C_SlaveAddr(sI2C,i2cAddr >> 1); 
 //specified pickit address is 8-bit format (incl. write bit as bit0)
 //Get rid of the rotation. The I2C_SlaveAddr function, takes an
 //8bit 'PIC format' address
 enable_interrupts(INT_si2c);


The PIC does not use 7bit address format.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group