Weird values
John Abshier
Posts: 1,116
CON 'CMPSO3Demo
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
SCL = 0 'Define Constants
SDA = 1
VAR
OBJ
C : "CMPS03"
Tv : "Tv_Text"
PUB Main | version, bBearing, wBearing
Init
Tv.str(string("Bus check "))
Tv.dec(C.BusCheck)
Tv.out(13)
Tv.str(string("Device Present "))
Tv.dec(C.Present)
Tv.out(13)
if C.Present
Tv.str(string("Present"))
Tv.out(13)
version := C.GetVersion
Tv.str(string("Version "))
Tv.hex(version,8)
Tv.out(13)
bBearing := C.GetBBearing
Tv.str(string("Byte Bearing "))
Tv.hex(bBearing,8)
Tv.out(13)
wBearing := C.GetWBearing
Tv.str(string("Word Bearing "))
Tv.hex(WBearing,8)
PUB Init
Tv.start(12) ' should check fail
Tv.out($00) ' clear
Tv.out($01) ' home
C.Init(SDA, SCL)
CON 'CMPS03 object
CMP_ADDRESS = $C0
OBJ
I2C : "I2C LowLevel"
PUB Init(SDA, SCL)
repeat 9
I2C.i2cStop
I2C.Initialize(SDA, SCL) ' Initialize i2c MASTER in present COG
PUB GetVersion
result := ReadReg($00)
return
PUB GetBBearing
result := ReadReg($1)
return
PUB GetWBearing : wBearing
wBearing := ReadReg($2)
wBearing <<= 8
wBearing |= REadReg($3)
return
PRI ReadReg(reg)
I2C.i2cStart
I2C.i2cWrite(CMP_ADDRESS | 0, 8)
I2C.i2cWrite(reg, 8)
I2C.i2cStart
I2C.i2cWrite(CMP_ADDRESS | 1, 8)
result := I2C.i2cRead(0, 8)
return
PUB BusCheck
result := I2C.testBus
return
PUB Present
result := I2C.devicePresent(CMP_ADDRESS)
return
The output of the program that reads a CMPS03 compass is
Version 9· This is the correct value.
bBearing $9E8· This should be a byte. E8 would be reasonable.
wBearing $9E80CD6 This should be a word. $0CD6 is a consistent result with $E8 for bBearing
I don't understand what is going on.· I thought that the result local variable was set to 0 on a call.


Comments
This is simple to fix... if you are expecting a BYTE, then just AND the result with $FF... expecting a WORD, then AND the result with $FFFF... for a LONG, just leave it alone.
I'll make note of this when I release this object in the future.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Who says you have to have knowledge to use it?
I've killed a fly with my bare mind.
CJ, I tried stuffing the result into the proper sized variable, but Spin only allows long local variables.
John, as you pointed out in a PM...
"The problem is that i2cData is global to the object. Making it local to Pub i2cRead solves the problem."
The reason I made i2cData global was so that I could use the incoming data as a FIFO (First-In-First-Out).
This kind of circumstance has been handy for some applications I have come across so I implemented the variable
this way.· That said, it is difficult to design a one size fits all.· The whole idea anyway is that the propeller
objects can be modified by the user to fit a specific application.· In some cases, the way I did it can reduce
the amount of code space required, when in a pinch can make a real impact.· For example:
a section of your code that reads....
PUB GetWBearing : wBearing wBearing := ReadReg($2) wBearing <<= 8 wBearing |= REadReg($3) return...could be re-written as...
PUB GetWBearing : wBearing ReadReg($2) wBearing := REadReg($3) & $FFFF return...it only saves a 'long' but if this can be applied several times, it could make a difference.
And yes, documentation is the answer, however the Lowlevel I2C routines John uses here have not officially been released
to the object exchange, instead they were used in an object (DS1307) which has been released.
As far as the ack bit ... this depends on the i2c device itself.· On some devices they don't care, on others they either
look for a "1" or a "0".· From the documentation, it looks like the CMPS03 wants to see a "0".
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.