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 support@ccsinfo.com

I2C Master & Slave with 2 PIC's SOLVED
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Sat Jan 11, 2020 2:29 am     Reply with quote

Hi everybody

From PCM programmer:
Quote:
1. Don't run both programs at 64 MHz. Run the master at 4 MHz
and the slave at 16 MHz.

I have 16 MHz crystals for both master and slave on the board. Disabled PLL of the master so master run at 16MHz, slave at 64MHz.
Quote:
4. Don't run i2c FAST mode. Run it at 100 KHz.

Changed to Slow 100 KHz
With this two changes, sending/receiving 2 data bytes everything works OK, slave not hanging Smile
Thank you again PCM programmer.
Tried with both master and slave at 64MHz and Slow 50000, the slave hangs.

I will try now to send/receive more bytes with Master at 16MHz, Slave at 64MHz

Best wishes
Joe
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Sat Jan 11, 2020 3:29 am     Reply with quote

Hi

Update:
Write/read 8 bytes or more works fine, slave not hang Smile
Read 8 bytes or more works fine, slave not hang Smile
The Master works at 16MHz, Slave at 64MHz.
Master Slow=100000
Thank you again for all who posted on this topic

How I can make the program to work if both Master and slave works at 64MHz?
Master Slow=100000 is OK in the program, but the I2C is just part of the program and I need the master to work at 64MHz for some other functions.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Jan 11, 2020 4:08 am     Reply with quote

Normal thing is to add a slight delay between sending the read address
and reading the first byte.
The slave has to respond to the address interrupt, then load the byte to
send, before the master can start to read. Typically allow perhaps 60 machine
cycles here (5uSec should be enough). It's always easier to have the slave
running faster than the master because of this.
Most of the other operations should self synchronise.
This is a difference with a 'software controlled' slave, to one where
all the operations are being done by hardware.

Generally, when a chip is run faster it becomes more sensitive to RFI,
and any 'shortcomings' in the layout. So you really do need to be careful
with the supply decoupling etc.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Sat Jan 11, 2020 4:37 pm     Reply with quote

Thank you Ttelmah

The program blocks that need high Master speed were working on PIC18F2520 at 32MHz when maximum speed of the microcontroller is 40MHz.
The reason to change to PIC18F26K22:
* To add the I2C communication instead of rs232 serial communication between the Master and Slave.
* To have rs232 master communication with two external (not on board) devices on separate rs232 hardware each, not one rs232 for the Slave and two external device.
* To change speed to 64MHz for the high speed program parts, to get double accuracy.

Originally the high speed program blocks, written in assembler, were working on PIC16F876 at 16MHz.
I changed to CCS C for the PIC18F2520 as at 32MHz CCS C give me better performances than assembler at 16MHz and much more easy maintenance.

As you advised:
* Will check how the I2C works with the delay you proposed.
* I will improve the power supply decoupling for testing.
* I will improve the power supply decoupling as the system works in heavy RFI & EMI environment.
* I will build a new board with 8MHz crystal for Master and 16MHz for the slave to work at 32MHz Master and 64MHz Slave.
Not best solution as I am losing the accuracy I wanted to get working the Master at 64MHz.

Any additional advice is very welcome Smile
Thank you again and best wishes
Joe
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Mon Jan 13, 2020 1:17 am     Reply with quote

Hi

An update:
* I improve the power supply decoupling
* I added the delay Ttelmah advised.
Both Master and Slave running at 64MHz
At Slow=100000 the slave hangs on different data values
I added additional delays as bellow:
Code:
//write data to Slave PIC
        i2c_start();
        i2c_write(0xB0);//Slave address with write
      delay_us(5);
        i2c_write(data0);
      delay_us(5);
        i2c_write(data1);
      delay_us(5);
        i2c_write(data2);
      delay_us(5);
        i2c_write(data3);
      delay_us(5);
        i2c_write(data4);
      delay_us(5);
        i2c_write(data5);
      delay_us(5);
        i2c_write(data6);
      delay_us(5);
        i2c_write(data7);
      delay_us(5);
        i2c_stop();
//read back data from the Slave PIC
        delay_us(1000); //ensure the Slave has had time to complete the write
        i2c_start();
        i2c_write(0xB1);//Slave address with read
      delay_us(5);
        slaverpt0 = i2c_read();
      delay_us(5);
        slaverpt1 = i2c_read();
      delay_us(5);
        slaverpt2 = i2c_read();
      delay_us(5);
        slaverpt3 = i2c_read();
      delay_us(5);
        slaverpt4 = i2c_read();
      delay_us(5);
        slaverpt5 = i2c_read();
      delay_us(5);
        slaverpt6 = i2c_read();
      delay_us(5);
        slaverpt7 = i2c_read(0);
      delay_us(5);
        i2c_stop();
      I2C26K22SnewdataF=1; 


I made long testing of write/read and read and I had the Slave hangs after 1679, 1342, 1903 and 2269 write/read with read from time to time.
I tested also with FAST=400000 and Slave hangs after approximately 150 write/read and a few read.

I have two questions:
* It is OK to insert the delays before & after each write or read?
* If Slow=50000 the I2C will work at 50000 BPS?

Best wishes
Joe
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Mon Jan 13, 2020 2:16 am     Reply with quote

Additional update:

Both Master and Slave running at 64MHz
At Slow=50000
I tested for 6,000 write/read and read and I had no Slave hang Smile

I will add watchdog timer and test what happening if Slave hangs

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jan 13, 2020 7:28 am     Reply with quote

OK.. What is your pull up resistor value on the bus?.
The slew rate available is controlled by this.
This is dependant on the capacitance of the bus, supply voltage, and the
speed you require.
With your bus going to two devices, the bus capacitance will be higher
than for a single device. Unlikely to be less than perhaps 100pF if the wires
are more than a very few cm long. So for a bus at this capacitance level at
100KHz at 3.3v for a device only supporting the minimum drive current,
we have:

Rp(min) = Vdd-0.4v/0.003 = 966R
Now the max value depends on the slew rate that must be met and is:

Rp(max) = Tr/0.8473 * Cb

Where Cb is the bus capacitance and Tr is the rise time allowed. Standard
mode (50KHz) requires a rise time of 1uSec, while fast mode at 400KHz
requires 300nSec. So with a 50pF bus capacitance, we get:

Rp(max 400K) = 300E-9/0.84673 * 100E-12 = 3K5R

So to run at 400K you need pull up resistors between 1K and 3.3K
(for standard E12 values).

If your resistors are above this, it explains why you have problems
when you increase the speed.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Jan 13, 2020 8:07 am     Reply with quote

His original post says 5 volts (I just checked, cause I'm old and gets confused easily'..... Smile
Mind you he may have changed things in 4 pages.....
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jan 13, 2020 8:40 am     Reply with quote

OK. Fair enough. I thought I remember him switching to a DsPIC at
some point....

The change to 5v, simply increases the size of Rp(min) for the higher voltage.
Becomes 1300R.
However the Rp(max) doesn't change. So the resistor range to do 400KHz
gets narrower (the reason it doesn't change is that the bus levels are
defined as percentages of the supply rail).
At 400K, resistors a lot smaller than most people start with.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Mon Jan 13, 2020 4:42 pm     Reply with quote

Hi Ttelmah and Temtronic

I am working with 5V from the beginning. Never used something else.
From my post at January 8:
Quote:
After getting my new boards and assemble them with two PIC18F26K22 and a 24C512 EEPROM and adapting the I2C programs to the PIC18F26K22 I started testings to be sure that everything works OK.
On the I2C lines I have 2K7 pull-up resistors (on SCL and SDA lines).

Started from the beginning with 2K7 resistor on SCL and SDA.
I never used DsPIC.
My compiler:
CCS PCH C Compiler, Version 5.062
The lines on the board are:
* 15 mm between Master and 24FC512
* 45 mm between Master and Slave
The board is 2 layers with copper pour both sides.
The lines are 12.5 mill

I can change the resistors to smaller if necessary by building a new board.

Thank you and best wishes
Joe
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Mon Jan 13, 2020 9:38 pm     Reply with quote

Hi

I tested 4000 write/read and read:
WDT enabled with reset at 16ms
Master and Slave at 64MHz
Code:
#use I2C(MASTER, Fast=400000, I2C1, STREAM=I2CPORT)//I2C1 hardware used

I had Slave reset at write/read or read as bellow:
364, 579, 739, 2036, 2865, 3158, 3650, 3771, 3843.
I can work with it as above, but I will use:
Code:
#use I2C(MASTER, Slow=50000, I2C1, STREAM=I2CPORT)//I2C1 hardware used

as this speed is more than enough for my project.

If somebody have additional remarks or advice I will be happy to try to implement them.

Thanks again to everybody that helped me to get here Smile

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Jan 14, 2020 1:31 am     Reply with quote

There is one other thing you can do to improve the reliability.

Basically on the master, read the input_state of the SDA line before
starting a transaction. If this is not '1', then the I2C bus is hung.

If it is '0', disable the I2C.
1)
Then clock SCL low and release it.
Test SDA again. If still '0' loop back to '1)'.
If now '1', tri-state the SCL line, and re-enable the I2C.

This is the standard 'I2C' recovery sequence for a peripheral that
has missed a bit.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Tue Jan 14, 2020 2:53 pm     Reply with quote

Hi Ttelmah

I will implement what you are proposing and will post the implementation.

with Slow 50000, I made one more test of 10,000 read/write and read and I had one Slave hung after 7,132 lines, WDT reset the Slave and everything continued OK.

Thank you and best wishes
Joe
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Fri Jan 31, 2020 5:38 pm     Reply with quote

Back again on this topic

After integrating the I2C Master with other program blocks, I have some errors NOT with the I2C but other blocks of the program that are interrupt triggered.

When I2C reading the Slave 9 bytes ones in 2000ms the errors are negligible but reading ones in 200ms the errors are much more.

I am posting the LST of the read and write:
Quote:
.................... i2c_write(slavedata0);
00BF4: MOVFF 68,AF
00BF8: RCALL 0944
*
00944: BCF FC6.7
00946: BCF F9E.3
00948: MOVFF AF,FC9
0094C: MOVLW 02
0094E: BTFSC FC6.7
00950: BRA 095C
00952: BTFSS F9E.3
00954: BRA 0952
00956: MOVLW 00
00958: BTFSC FC5.6
0095A: MOVLW 01
0095C: MOVWF 01
0095E: RETURN 0
///////////////////////////////////////////////////////
.................... slaverpt0 = i2c_read();
00CB0: MOVLW 01
00CB2: MOVWF 00
00CB4: RCALL 0988
*
00988: BCF FC6.6
0098A: BSF FC5.3
0098C: BTFSC FC5.3
0098E: BRA 098C
00990: BTFSC 00.0
00992: BCF FC5.5
00994: BTFSS 00.0
00996: BSF FC5.5
00998: BSF FC5.4
0099A: BTFSC FC5.4
0099C: BRA 099A
0099E: MOVFF FC9,01
009A2: RETURN 0

The delay LST:

Quote:
.................... delay_us(5);
00CA6: MOVLW 1A
00CA8: MOVWF 00
00CAA: DECFSZ 00,F
00CAC: BRA 0CAA
00CAE: NOP


I understand the assembler of the LST.
My question is what will happen if an interrupt occurs while the program is in the middle of executing one of the above?
It will go out to serve the interrupt or will serve the interrupt when the execution is ended?

EDIT: In the past for the Master/Slave I was using rs232 in the program and had no errors.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Jan 31, 2020 11:35 pm     Reply with quote

The interrupt will occur as normal.
The 'exception', would be if you have either a delay, or an I2C
transaction inside any interrupt. If you do, the compiler will give you
a warning that 'interrupt disabled to prevent reentrancy', and interrupts
will be disabled round each of the matching code in the main.
Much more important though is latency. If you have for example a timer
interrupt in your slave, it will not be guaranteed to react to the I2C
interrupt untill it comes out of this. Result the latency shoots up.
Depending on what interrupts you are actually using, you can add the
line:

#device HIGH_INTS=TRUE

near rhe start of your code, and have the I2C interrupt coded as

#INT_SPI HIGH

This interrupt can then interrupt other interrupts, getting rid of this
extra latency.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3, 4, 5, 6  Next
Page 4 of 6

 
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