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

Issue with DSPIC33FJ12MC202 as I2C Slave

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



Joined: 26 May 2007
Posts: 14

View user's profile Send private message

Issue with DSPIC33FJ12MC202 as I2C Slave
PostPosted: Tue Nov 03, 2015 5:56 pm     Reply with quote

Hello,

I'm having some trouble getting a DSPIC33FJ12MC202 to act as an I2C slave (not acknowledging data and not entering the interrupt). The I2C master is a FTDI FT4222 chip where the SCK and SDA lines are pulled up using 4.7k resistors. I have the SDA pin connected to pin 14 and the SCK pin connected to pin 15 (alternate pins). I know the chip is working because I have been debugging other IO within the circuit. I also have a logic analyzer connected to the I2C bus and the master appears to be sending the appropriate data (0x05 0x00 0x01 0x02 for testing purposes. I've tried different addresses but nothing seems to work).

Below is a snippet of my code. I am using CCS 5.049. Does anybody see anything obvious?

Code:

#include <33FJ12MC202.h>

#device ICD=TRUE
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES ALTI2C1                  //I2C1 mapped to ASDA1/ASCL1 pins
#FUSES NOJTAG                   //JTAG disabled

#device ICSP=1
#use delay(clock=80MHz,crystal=20000000)


#use i2c(SLAVE, ADDRESS=0x05, I2C1, FORCE_HW, SLOW, stream=I2C_PORT1)

#INT_SI2C
void  si2c_isr(void)
{
   BYTE i2cState, incomingData;
   i2cState = i2c_isr_state();
 
   if(i2cState<0x80)                 //master is sending data
   {
      if( (i2cState<I2C_BUFFER_SIZE) && (i2cBufferFull == false) )
      {
         incomingData = i2c_read();
         i2cBuffer[i2cState] = incomingData;
      }
      else
      {
         i2cBufferFull = true;
      }
   }
   else if (i2cState == 0x80) //master is requesting data
   {               

   }
}

void main()
{


   enable_interrupts(INT_SI2C);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      //TODO: User Code
      MoveMotor_Positive(2000, 0);
      delay_ms(1000);
     
      if(i2cBufferFull == true)
      {
         //Interact wtih the buffer
         i2cBufferFull = false;
         memset(i2cBuffer,0,I2C_BUFFER_SIZE);
      }
   }

}

_________________
Eric
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 03, 2015 6:40 pm     Reply with quote

Quote:
#use i2c(SLAVE, ADDRESS=0x05, I2C1, FORCE_HW, SLOW, stream=I2C_PORT1)

1. Slave addresses should be even numbers, and should be in 8-bit
address format.
2. They should not be in the reserved range. The lowest slave address
you can legally use is 0x10.

See section 7.3.11 (page 49) in the dsPIC33 manual for Inter-Integrated
Circuitâ„¢ (I2Câ„¢) for a table of reserved addresses:
http://ww1.microchip.com/downloads/en/DeviceDoc/70000195f.pdf
The addresses are in Philips 7-bit format, so add a 0 to the end of
the 7 bits, and mentally convert to hex. For example, HS Mode Master
code is 0000 1xx. "x" can be 0 or 1. So this becomes 0000 1110,
and converting to hex, it is 0x0E. So the next higher address is the start
of the unreserved slave addresses, and that is 0x10. So your #use i2c()
statement now becomes:
Code:
#use i2c(SLAVE, ADDRESS=0x10, I2C1, FORCE_HW, SLOW, stream=I2C_PORT1)
peer9802



Joined: 26 May 2007
Posts: 14

View user's profile Send private message

PostPosted: Wed Nov 04, 2015 3:50 am     Reply with quote

Thanks PCM Programmer,

I tried this, along with a few other addresses, and nothing seems to work. I also commented out the I2C stuff and tested the pins as general IO to verify they are actually functioning. They do.

I should add the PIC24 project wizard did not allow me to setup hardware I2C on this chip (the section was disabled) so I added the #use I2C code manually. I'm not sure if this is a IDE bug or intentional...
_________________
Eric
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 04, 2015 3:29 pm     Reply with quote

I don't have the PCD compiler so I can't test this for you, but my advice is:

1. Instead of your slave code, use this CCS example file:
Quote:
c:\program files\picc\examples\ex_slave.c

2. Verify that the alternate i2c module pins are working. You could do
this by using another PIC as the master (instead of the FTDI chip), and
by running the i2c bus scanner program. See if the scanner finds the
dsPIC33 slave. It should see a device at address 0xA0.
http://www.ccsinfo.com/forum/viewtopic.php?t=49713

3. If the slave is working, then run this code in the master PIC:
http://www.ccsinfo.com/forum/viewtopic.php?t=32368&start=3
This will test the ex_slave.c code.
Ttelmah



Joined: 11 Mar 2010
Posts: 19494

View user's profile Send private message

PostPosted: Thu Nov 05, 2015 5:18 am     Reply with quote

There are some generic problems with the I2C handling as posted.
First on state 0x80, you have to read the byte (without releasing ACK), then write the new data (and release). Look at the example slave handler.
A slave does not have a clock rate for I2C. The compiler should ignore this, but I have seen it result in incorrect values in the configuration registers.
I always feel if you are naming streams you should use the names, rather than 'relying' that the compiler will refer to the correct device.
There appears to be no handling for state zero or one.
Remember state 0, happens on the initial address byte. It should not be stored. Then in standard I2C, state 1, is the register address, and again should be retrieved separately. I've found the PIC peripheral can give strange results if you try to operate without using a register address.
Also as written, if the buffer full flag gets set, the handler won't read the byte received, which then leaves problems. The code should always read received bytes, even if it then decides to throw them away....
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