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 Feb 01, 2020 1:21 am     Reply with quote

Thank you for answering Ttelmah.

The quote in my previous post is from the LST of the Master.
I don't have transaction of I2C inside any interrupt, if I understand correct the I2C Master is not interrupt driven.
I also don't have the warning "interrupt disabled to prevent "reentrancy"
In the main I have delay_us(5) after every read or write.
My questions:
1. The interrupts will be served during the delay_us(5)?
2. The interrupts will be served during i2c_write(slavedata0); or slaverpt0 = i2c_read();?
3. Or the interrupts will be served just after all the I2C routine?
With the controller at 64MHz 1PC=0.0625us and in the software block I have the problem I can have error of +/- 50us.

In the slave, in addition to int_SSP, I have #int_TIMER0 for the flashing led:

Quote:
.................... set_timer0(45536);
*
000D2: MOVLW B1
000D4: MOVWF FD7
000D6: MOVLW E0
000D8: MOVWF FD6
.................... timer20msincF=1;//to increment the 20ms timers
000DA: BSF 1B.0
000DC: BCF FF2.2
000DE: GOTO 0084

and I am out from the handler.

I will add:
#device HIGH_INTS=TRUE in both Master and Slave.
#INT_SPI HIGH in the Slave.

Will report back if have any change.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Feb 01, 2020 4:40 am     Reply with quote

It's the timer interrupt in the slave that will cause problems.
The slave _has_ to respond quickly to the I2C actions. The timer interrupt
even at 64MHz, will actually take about 70 instruction times to execute.
It takes typically about 30 instructions to get 'into' the interrupt handler
and about the same to get out. While the code is in this interrupt, it won't
respond to the I2C.
Make the I2C slave interrupt HIGH priority.

Yes interrupts will be handled inside the delay, and the I2C write.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

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

PostPosted: Sat Feb 01, 2020 4:50 am     Reply with quote

Hi

I added:
#device HIGH_INTS=TRUE in both Master and Slave.
#INT_SSP HIGH in the Slave.
#INT_CCP2 HIGH in the Master as the errors I am getting from the routine connected to this interrupt.

I am getting the same errors like before.
At I2C read every 2000ms I am getting 1 error/4 seconds
At I2C read every 200ms I am getting 2 errors/second

The Master need the data from Slave every 200ms.

I don't know how to go forward.
I will try to read just 2 bytes every 200ms and see what I get.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Feb 01, 2020 7:06 am     Reply with quote

The odds are that your other errors are down to you not understanding
implications of something in the interrupt.
Understand that reads and writes of anything larger than a 'byte', are not
granular, so if an interrupt occurs during a transfer updating such a value
incorrect results will be seen.
You say that your problem is with the CCP interrupt. Post what this does
and what you expect to happen.
There are issues with things you have already posted. The Timer interrupt
code won't give accurate times. You have to _add_ a count to the timer,
not load it with a fixed value. Loading with a fixed value will give
different times depending on how long it takes to get to that point, and
this will be significant, and will vary when other interrupts trigger.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

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

PostPosted: Sat Feb 01, 2020 6:48 pm     Reply with quote

Thank you for answering Ttelmah

Regarding CCP2, from the LST:
Quote:
.................... #INT_CCP2 HIGH
.................... void CCP2_isr()
.................... {
.................... bittime=get_capture(2);
0019E: MOVFF F68,49
001A2: MOVFF F67,48
.................... bittime=bittime/2;//to get results in us as increment is 0.5us
001A6: BCF FD8.0
001A8: RRCF 49,F
001AA: RRCF 48,F
.................... //if bittime<250us is spike and the program skips it
.................... if(bittime>250)
001AC: MOVF 49,F
001AE: BNZ 01B6
001B0: MOVF 48,W
001B2: SUBLW FA
001B4: BC 01BC
.................... {
.................... set_timer1(0);
001B6: CLRF FCF
001B8: CLRF FCE
.................... newbitF=1;
001BA: BSF 4C.0
.................... }
001BC: BCF FA1.0
001BE: GOTO 012E
.................... }

After that is going out from the interrupt handler. As I wrote before, the program tolerates +/- 50us so I don't understand how the error can occur when using I2C.
In the past I was using a complicated rs232 to talk with the Slave and I had no errors without the I2C.

Regarding the Timer interrupt a small error (+3.25us) is not important in my program. It shows this error in MPLAB simulator. If I change to set_timer0(45539); the error is +0.25us in the simulator.
You wrote:
Quote:
You have to _add_ a count to the timer,
not load it with a fixed value.

Can you give me an example how to do that? I will add some additional software blocks that the precise timing is important.

Regarding
Quote:
...reads and writes of anything larger than a 'byte'...
If you write about the I2C, I have no problems there. I get everything accurate.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Feb 02, 2020 12:00 am     Reply with quote

Your bittime variable is 16bit.
If you are reading this outside the interrupt, it can potentially get
changed between accessing the two bytes, unless you make sure
to either use 16bit transfers, disable interrupts round the access, or
'double check' the transfer.
Double checking the transfer is done like:
Code:

int localtime;

do
{
    localtime=bittime;
} while (localtime!=bittime);


This copies bittime into the variable 'localtime', but then tests that
these do match. If not, it repeats the copy. This ensures that it'll only
exit once localtime genuinely does match the updated bittime value.

Then the key thing is you are missing just how long the interrupt
handler really is. In front of what you post, there is the compiler code
to save all the registers, and after it is the code to restore these.
Typically about another 50 instruction counts.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

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

PostPosted: Sun Feb 02, 2020 6:05 am     Reply with quote

Hi Ttelmah

Thank you for being patient and still helping me with this project.

In the program:
Code:
#INT_CCP2 HIGH
void CCP2_isr()
{
   bittime=get_capture(2);
   bittime=bittime/2;//to get results in us as increment is 0.5us
//if bittime<325us is spike and the program skips it
   if(bittime>=325)
   {
      set_timer1(0);
      newbitF=1;
   }
}

The below is called from main:
Code:
void RX (void)
{
   if(newbitF==1)
   {
//------------------------------------------------------
int localtime;
do
{
    localtime=bittime;
} while (localtime!=bittime);
//----------------------------------------------------
      newbitF=0;   //additional code here

I suppose the addition is in the wrong place because the Master hangs.
Where I suppose to insert the addition?

The minimum bit time is 350us so I think that have very low possibility to have a new bittime until the previous is processed as the controller at 64MHz have 16*PC/us but I would like to add your addition to be sure.
By the way, the program worked fine on PIC18F2520 without I2C, just with rs232 and at 32MHz.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Feb 02, 2020 9:30 am     Reply with quote

localtime needs to be declared as the same variable type as bittime.
Because you are on a PIC18, it'll need to be unsigned int16;
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

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

PostPosted: Sun Feb 02, 2020 6:08 pm     Reply with quote

Shame on me missing that (int vs int16)
Works properly after the change but the missing bits while I2C works are still missing.

I don't know what else I can do.

Best wishes
Joe

PS: Emoticons not working for some reason.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Feb 03, 2020 12:35 am     Reply with quote

Missing bits in what?.
Explain what is happening.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

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

PostPosted: Mon Feb 03, 2020 3:22 am     Reply with quote

Sorry for the confusion.

If I2C is enabled every 2000us I have bit time error once in 5 seconds.
If I2C is enabled every 200us I have a bit time error 2 times every second.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Feb 03, 2020 3:40 am     Reply with quote

What do you mean by 'a bit time error'?.
You mean that the value recorded by CCP2 is different from what you
expect?.
What is this being triggered from?. What pulse time is involved?.
How frequently is this updating?.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

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

PostPosted: Mon Feb 03, 2020 4:00 am     Reply with quote

Hi Ttelmah

I am expecting and testing 400us +/-50us changing from '0' to '1' and so on.
If the '0' or '1' not in this window, I increment a counter and send it by serial communication 9600 BPS to the PC terminal.

If I am not using I2C the counter stays at zero.
If I2C is enabled every 2000us I have bit time error once in 5 seconds.
If I2C is enabled every 200us I have a bit time error 2 times every second.

Best wishes
Joe
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Feb 03, 2020 4:44 am     Reply with quote

OK. I'm going to suggest a simple thing. Setup software I2C on the master.
Go back up to your nice fast rate for this.
I suspect you will find it'll all then work fine.

I suspect what is happening, is that when the slave implements clock
stretching (holds SCL low to say it is busy), the master instruction
waiting to complete actually has to hold _inside the instruction_. Result
it doesn't execute 'state 1' of an instruction while this is happening.
Since state 1, is when the processor responds to interrupts, the effect
is that the master momentarily becomes unresponsive to interrupts.
Now I've honestly never seen this, and to result in an incorrect value
it'd have to be for long enough for the capture event to actually be overriden
(which is unlikely). It also seems strange given the speed of your slave device.
However it's the only theory that makes sense....
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

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

PostPosted: Mon Feb 03, 2020 3:30 pm     Reply with quote

Hi Ttelmah

I don't believe Smile
Code:

#use I2C(MASTER, FAST=400000, I2C1, STREAM=I2CPORT)//I2C1 hardware used
#use I2C(MASTER, FAST=400000, I2C1, FORCE_SW, STREAM=I2CPORT)//I2C1 hardware used
#use I2C(MASTER, FAST=400000, I2C1, FOORCE_HW, STREAM=I2CPORT)//I2C1 hardware used

The Master writing 9 bytes, reading 9 from the Slave;
All works at FAST=400000 with NO ANY ERROR!!! Flawless Smile
Tested already for one hour an no even one error!

I DON'T KNOW HOW TO THANK YOU Smile
I can go now fast forward with the project as all the other software blocks I have as reusables.

Best wishes
Joe
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 5 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