|
|
View previous topic :: View next topic |
Author |
Message |
peer9802
Joined: 26 May 2007 Posts: 14
|
Issue with DSPIC33FJ12MC202 as I2C Slave |
Posted: Tue Nov 03, 2015 5:56 pm |
|
|
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
|
|
Posted: Tue Nov 03, 2015 6:40 pm |
|
|
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
|
|
Posted: Wed Nov 04, 2015 3:50 am |
|
|
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
|
|
Posted: Wed Nov 04, 2015 3:29 pm |
|
|
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: 19561
|
|
Posted: Thu Nov 05, 2015 5:18 am |
|
|
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.... |
|
|
|
|
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
|