View previous topic :: View next topic |
Author |
Message |
alexbilo
Joined: 01 Jun 2004 Posts: 39 Location: Trois-Rivières
|
i2c master hanging |
Posted: Wed Sep 08, 2004 9:41 am |
|
|
Hi,
I implemented an i2c master using the hardware ssp module. Here are my settings :
Code: |
#use delay(clock=40000000,RESTART_WDT)
#fuses H4,NOWDT,WDT128,PUT,BROWNOUT,BORV27,NOWRT,NOLVP,DEBUG
#use i2c(MASTER,SDA=PIN_C4,SCL=PIN_C3,FAST,RESTART_WDT,FORCE_HW)
|
* Notice that I use an ICD2 debugger so I set the DEBUG fuse.
I found that the processor hangs from time to time in the i2c_write() routine while checking the SSPIF flag (to know then the transmission is finished, I assume)
Code: |
0546: BCF FC6.7
0548: BCF F9E.3
054A: MOVFF 42,FC9
054E: MOVLW 02
0550: BTFSC FC6.7
0552: GOTO 0562
**0556: BTFSS F9E.3
0558: GOTO 0556**
055C: MOVLW 00
055E: BTFSC FC5.6
0560: MOVLW 01
0562: MOVWF 01
0564: RETLW 00
|
The instructions between the stars executed in an infinite loop, as if the SSPIF flag is never set.
Any ideas about what can cause this?
Thanks, _________________ Alex |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Sep 08, 2004 9:50 am |
|
|
Hmmm, I'd like to help but my ASM language knowledge is in the toilet. If you posted your 'C' code along with it I might could add my 2 cents worth.
Ronald |
|
|
alexbilo
Joined: 01 Jun 2004 Posts: 39 Location: Trois-Rivières
|
|
Posted: Wed Sep 08, 2004 12:18 pm |
|
|
Sorry about the ASM listing, I just posted this snippet because this is the code for the i2c_write() function. Since this is a built-in function, I cannot access the C code (not even sure there IS C code for these functions).
I can at least tell you that the instructions between the stars probe the SSPIF bit (PIR1, bit3) and it loops until this bit gets set. My problem is exactly the fact that this bit is never set, leading to an infinite loop.
Hope this will help!
Thanks again, _________________ Alex |
|
|
Trampas
Joined: 04 Sep 2004 Posts: 89 Location: NC
|
|
Posted: Wed Sep 08, 2004 2:21 pm |
|
|
Big question! What version of compiler are you running?
I know that the 3.19x or maybe it was 3.201 or something had a bug with the I2C write function that took me several hours to figure out.
Basically I find the I spend 80% of my time tracking down my bugs and about 20% trying to figure out if the bug is mine or the compilers...
Trampas |
|
|
alexbilo
Joined: 01 Jun 2004 Posts: 39 Location: Trois-Rivières
|
|
Posted: Wed Sep 08, 2004 3:44 pm |
|
|
Actually I use v.3.187... Hope this isn't a compiler bug
From the ASM listing and the ICD2 debugger I can see that the problem is this SSPIF that never gets set...
But does this result from a bad configuration from the compiler or a bad i2c_write() condition that prohibit this bit from being set, I don't know. _________________ Alex |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Sep 08, 2004 3:59 pm |
|
|
Could you post your entire I2C routine? This will really help to see where the problem might be. |
|
|
Trampas
Joined: 04 Sep 2004 Posts: 89 Location: NC
|
|
Posted: Wed Sep 08, 2004 4:12 pm |
|
|
OK I know the bug was fixed in 3.191. Here is the code listing for a 16F872
Code: |
.................... i2c_write(ptr[index++]);
0078: MOVF 5E,W
0079: INCF 5E,F
007A: ADDWF 63,W
007B: MOVWF 04
007C: MOVF 00,W
007D: MOVWF 66
007E: MOVF 66,W
007F: MOVWF 13
0080: BSF 14.4
0081: BCF 0C.3
0082: BSF 03.5
0083: BTFSS 14.0
0084: GOTO 087
0085: BCF 03.5
0086: GOTO 082
|
Note the spin is on register 14.0 which is the SSPCON SSPM0...
I really think this was a problem with the compiler! I know I worked for hours on the same problem. I know I share in your frustration because you have spent hours on the problem.
OK I have found that the problem existed in 3.206 here is the same code, compiled with 3.206:
.................... i2c_write(ptr[index++]);
0077: MOVF 5E,W
0078: INCF 5E,F
0079: ADDWF 63,W
007A: MOVWF 04
007B: MOVF 00,W
007C: MOVWF 66
007D: MOVF 66,W
007E: MOVWF 13
007F: BSF 14.4
0080: BCF 0C.3
0081: BTFSS 0C.3
0082: GOTO 081
The 3.206 code was checking the interrupt flag, while the 3.191 code checked the correct register. Note that this problem was reported back on July 30th.
I think what is happening is CCS may have had the bug in the version you are using, then fixed it for 3.191, then reintroduced it for 3.207.
I can here you cursing from here....
Trampas |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Sep 08, 2004 4:45 pm |
|
|
No bigger, forget the CCS function and write you own. That way you will know it will work now and forever. |
|
|
Trampas
Joined: 04 Sep 2004 Posts: 89 Location: NC
|
|
Posted: Wed Sep 08, 2004 5:12 pm |
|
|
Mark,
I can not resist... But you are assuming the compiler does the right thing...
For example I have been using the bit_test() function. Yes I know it is a bad thing and I should write my own bit_test... But in 3.206
bit_test(CMCON,6) checked bit zero...
So you have to be careful when you write your own functions as well.
Trampas |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Sep 08, 2004 6:48 pm |
|
|
Quote: | But you are assuming the compiler does the right thing |
No way! I assume that it is not doing the right thing. That is why I write my own functions. Yep, even a bit test ;) I have taken the Microchip approach and defined the PIC registers and structs as well. That makes bit checking very easy. |
|
|
Guest
|
|
Posted: Wed Sep 08, 2004 7:10 pm |
|
|
That is assuming the compiler compiles your code correctly. For example if you do a bit shift does it produce the correct assembly?
Trampas |
|
|
alexbilo
Joined: 01 Jun 2004 Posts: 39 Location: Trois-Rivières
|
|
Posted: Wed Sep 08, 2004 9:31 pm |
|
|
I must admit that this looks like a compiler bug. Anyway I'll make sure by replacing this routine by my own (which, of course, cannot be wrong... ...). I hope that, as Trampas pointed, I can at least rely on the built-in bit manipulation functions!
I'll let you know...
Thanks a lot! _________________ Alex |
|
|
|