![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
teekaytk
Joined: 14 Jan 2005 Posts: 28
|
dual i2c on 8722 |
Posted: Wed Feb 21, 2007 5:23 am |
|
|
Hi,
there was some mention on this forum of the second I2C on pic18f8722 not being complied rightly (some asm lisiting suggested that the registeds being used were not of SSP2 but of SSP1). Is there a way of knowing if this has been solved now. I am using 4.025
Thanks
TK |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 21, 2007 5:09 pm |
|
|
I installed PCH vs. 4.025 and compiled the test program shown below
so I could look at the code in the .LST file. First I compiled it for pins
C4 and C3. Then I compiled it for pins D5 and D6. Then I printed and
compared the .LST files.
I think there is a bug in the i2c_write() code for the i2c channel
on pins D5 and D6 (the 2nd SSP module).
Notice in the listing below that it clears bit 3 in register 0xF9E.
This is the SSP1IF bit in the PIR1 register. But that's wrong.
For the 2nd SSP, it should be clearing the SSP2IF bit in the PIR3
register. But that's bit 7 of register 0xFA4.
They're clearing the SSPIF bit for first SSP module, instead of for
the 2nd SSP module. That's a bug. A little bit farther down,
there's a place where they're testing it. Again, they're testing
the SSPIF bit in the first SSP module, and that's a bug.
Code: |
... #use i2c(master, sda=PIN_D5, SCL=PIN_D6, FORCE_HW)
00004: BCF F63.7
00006: BCF F9E.3 // Clear PIR1.SSP1IF -- Bug
00008: MOVFF 07,F66
0000C: MOVLW 02
0000E: BTFSC F63.7
00010: BRA 001C
00012: BTFSS F9E.3 // Bug
00014: BRA 0012
00016: MOVLW 00
00018: BTFSC F62.6
0001A: MOVLW 01
0001C: MOVWF 01 |
Code: |
#include <18F8722.h>
#fuses XT, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=4000000)
#use i2c(master, sda=PIN_C4, SCL=PIN_C3, FORCE_HW)
// #use i2c(master, sda=PIN_D5, SCL=PIN_D6, FORCE_HW)
//========================
void main()
{
char c;
i2c_start();
i2c_write(0x55);
c = i2c_read(0);
i2c_stop();
while(1);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
teekaytk
Joined: 14 Jan 2005 Posts: 28
|
|
Posted: Wed Feb 21, 2007 11:59 pm |
|
|
thanks, that confirms why its kind of not working for me here. it seems like a small fix, but has been in the compiler for years now i think. i need to get a product out to a client by early april (no too far :( ). the first ssp is being used to write to a flash card. the pcb has been made and cant be changed at this stage. has someone made correct i2c drivers for ssp2 that i can use instead?
regards
TK |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 22, 2007 2:09 am |
|
|
You could write a substitute routine for the bad library code. Only the
i2c_write() function has a problem and only in the 2nd SSP module.
One easy way to do this is to look at the ASM code in the .LST file
and write C code that does the same thing. I've done this below.
Here's the corrected ASM code for the i2c_write() function for the 2nd
i2c port on the 18F8722. I've fixed the register address and bit position
for the SSP2IF bit, and I've added comments:
Code: | /
/*
... #use i2c(master, sda=PIN_D5, SCL=PIN_D6, FORCE_HW)
00004: BCF F63.7 // Set WCOL2 = 0
00006: BCF FA4.7 // Set SSP2IF = 0
00008: MOVFF 07,F66 // Put byte into SSP2BUF
0000C: MOVLW 02
0000E: BTFSC F63.7 // Test WCOL2
00010: BRA 001C // Return 2 if WCOL2 = 1.
00012: BTFSS FA4.7 // Test SSP2IF
00014: BRA 0012 // Wait in loop if SSP2IF = 0
00016: MOVLW 00
00018: BTFSC F62.6 // Test ACKSTAT
0001A: MOVLW 01 // Return state of ACKSTAT
0001C: MOVWF 01
*/
|
Here's a functional translation of the above ASM code to C. It doesn't
compile to exactly the same ASM code, but it performs the same functions.
Code: |
// Define registers and bits used by the routine.
#byte SSP2CON1 = 0xF63
#bit WCOL2 = SSP2CON1.7
#byte PIR3 = 0xFA4
#bit SSP2IF = PIR3.7
#byte SSP2CON2 = 0xF62
#bit ACKSTAT2 = SSP2CON2.6
#byte SSP2BUF = 0xF66
// Here is the new routine. Call it instead of i2c_write()
// in the CCS library code for the 2nd SSP module.
int8 i2c_write_ssp2(int8 value)
{
int8 retval;
WCOL2 = 0;
SSP2IF = 0;
SSP2BUF = value;
if(WCOL2)
{
retval = 2;
}
else
{
while(!SSP2IF);
retval = ACKSTAT2;
}
return(retval);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|