Running a slow I2C bus on 20X2

matherp

Senior Member
I want to run my I2C bus at around 50khz to allow for the capacitance of the length of my cable run whilst limiting the pullup resistors to keep the bus current within spec (4ma).

Looking at the values of i2cfast_64 (0x27), i2cfast_32 (0x13), and i2cfast_16 (0x09) they make sense as the values to be loaded into the brg register of the i2c baud rate generator in the PIC18F14K22 chip.

However, i2cslow_64 (0xFF), i2cslow_32 (0xCF), and i2cslow_16 (0xA7) don't make sense as I think the actual brg values should be 0x9F, 0x4F, and 0x27 respectively. I assume there must be some coding in these values that the compiler is using?

Based on my understanding I can't get 50kHz at 64Meg as the brg register is only 8 bits. But at 32 meg the value should be 0x9F. Will this work as a literal in the hi2csetup command or am I missing something?

Thanks


Peter
 

hippy

Technical Support
Staff member
However, i2cslow_64 (0xFF), i2cslow_32 (0xCF), and i2cslow_16 (0xA7) don't make sense as I think the actual brg values should be 0x9F, 0x4F, and 0x27 respectively. I assume there must be some coding in these values that the compiler is using?
Your figures do match with the Microchip datasheet and we'll investigate that and correct the compiler constants as appropriate. I guess the slow values were calculated assuming a base speed of 4MHz rather than 8MHz.

Based on my understanding I can't get 50kHz at 64Meg as the brg register is only 8 bits. But at 32 meg the value should be 0x9F. Will this work as a literal in the hi2csetup command or am I missing something?
It looks like 0x9F will give 50kHz at 32MHz. It should be possible to simply drop that in where the i2cslow_32 constant would go. However ...

It seems like bit 7 of the constant is not being written. Which we will investigate, but you can use "PokeSfr 0xC8, 0x9F" after the "Hi2cSetup" or "I2cSlave" ...

#Picaxe 20X2
#Terminal 9600
Pause 2000

I2cSlave 0xA0, 0x55, I2CWORD
SerTxd( "I2cSlave with 0x55")
Gosub Report

I2cSlave 0xA0, 0xAA, I2CWORD
SerTxd( "I2cSlave with 0xAA")
Gosub Report

I2cSlave 0xA0, 0x9F, I2CWORD
SerTxd( "I2cSlave with 0x9F")
Gosub Report

PokeSfr 0xC8, 0x55
SerTxd( "Poke with 0x55")
Gosub Report

PokeSfr 0xC8, 0xAA
SerTxd( "Poke with 0xAA")
Gosub Report

PokeSfr 0xC8, 0x9F
SerTxd( "Poke with 0x9F")
Gosub Report

End

Report:
PeekSfr 0xC8, b0
b1 = b0 / 0x10 + "0"
If b1 > "9" Then : b1 = b1+7 : End If
b2 = b0 & 0x0F + "0"
If b2 > "9" Then : b2 = b2+7 : End If
SerTxd( " gives 0x", b1, b2, CR, LF )
Return

Reports ...

I2cSlave with 0x55 gives 0x55
I2cSlave with 0xAA gives 0x2A
I2cSlave with 0x9F gives 0x1F
Poke with 0x55 gives 0x55
Poke with 0xAA gives 0xAA
Poke with 0x9F gives 0x9F
 
Last edited:

Technical

Technical Support
Staff member
However, i2cslow_64 (0xFF), i2cslow_32 (0xCF), and i2cslow_16 (0xA7) don't make sense as I think the actual brg values should be 0x9F, 0x4F, and 0x27 respectively. I assume there must be some coding in these values that the compiler is using?
Peter
Actually these i2cslow numbers are correct, as bit7 in the BASIC command is used as the SSPSTAT.SMP slew control bit (see hi2csetup command in manual 2 - advanced details). That is why the numbers are 128 greater than you expected - as the slew control bit is enabled by bit 7.

The theroretical value for 64MHz is indeed $9F (159) , but the max value that is actually possible in that baud register is 127 (bit 7 is not used when reloading the baud rate generator). So you can only ever use assembler baud values of 3 to 127 (0-2 also don't work if you read the errata sheets for that PIC type!).

So at i2cslow_64 127 is used (as the nearest possible) + 128 = 255.
 
Last edited:

matherp

Senior Member
Sorry, should have picked up that bit 7 issue in the Picaxe manual. However, I'm still confused as to whether you are saying this is a compiler limitation or chip limitation. Page 151 of the chip datasheet indicates that all 8 bits are used in master mode and that the top bit is only not used in slave mode. I assume therefore that if I use pokesfr to write to sspadd as per hippy's response I can get 0x9F loaded and still have the sspstat bit correctly set?

Thanks

Peter
 

Technical

Technical Support
Staff member
Good point, all previous PICS have only used <6>-<0> bits, and the PICAXE firmware is setup to work like this.

However the Microchip datasheet for this 14K22 part contradicts itself many times

14.3.7.1 Clock Arbitration
...SCL pin is sampled high, the Baud Rate Generator is
reloaded with the contents of SSPADD<6:0> and

begins counting.


14.3.8 I
2C MASTER MODE START CONDITION TIMING
....the Baud Rate
Generator is reloaded with the contents of
SSPADD<6:0> and starts its count
...
register to be set. Following this, the Baud Rate Generator
is reloaded with the contents of SSPADD<7:0>

and resumes its count.


So the 14K22 datasheets says both in numerous places - even in the same sentence- so take your guess! Either it is
1) <6>-<0> like all previous PICs
2) <7>-<0> new setup for this PIC where bit 7 could be used

We'll ask Microchip!
 

Technical

Technical Support
Staff member
Microchip have confirmed this new generation part (20X2 part only, not any other part) now has an 8 bit register and that their datasheet is wrong in places.

The X2 firmware still only uses the older 7 bit system (3-127). But if you use a poke as suggested you could poke a full 8 bit number (3-255).
 
Top