Understanding the use of DAT data as a variable
Erlend
Posts: 612
Quite some time ago I thought I had grasped how a data element declared in DAT could be used as a variable across many instances of an Object. I am not so sure anymore.
In the I2C driver object I have
and that allows for only the first parent caller to need to call Init, all the others can simply call the particular bus routines, being safe that this Object still remembers which two pins to use. Correct?
So, what if an other parent caller comes around and wants to initiate a different I2C bus, on an other pair of pins? The way I understand it, if this new caller calls Init with some new set of pin numbers, this will hit back on the original one, and redefine those pin numbers in the same go. Correct?
If so, do I need two different I2C drivers, one like the above, which assumes everyone want to go on the same physical bus, and an other version where the VAR is used instead of DAT?
Or is there some even more devious DAT technique where a set of pins could be defined for an object such as this??
The question is not related to I2C as such, but more in general about how this kind of 'varable sharing' can be done.
My trick for understanding this is to think of DAT as part of the code, not the variables. Code is loaded only once, variables are constructed each time an object is called (instantiated), modifying DAT is like modifying the code, and it therefore affects all the object instances. Is this far off?
Erlend
In the I2C driver object I have
DAT PINscl LONG -1 PINsda LONG -1 PUB Init(_PINscl, _PINsda) LONG[@PINscl]:= _PINscl LONG[@PINsda]:= _PINsda DIRA[PINscl] := 0 OUTA[PINscl] := 0 DIRA[PINsda] := 0 Reset
and that allows for only the first parent caller to need to call Init, all the others can simply call the particular bus routines, being safe that this Object still remembers which two pins to use. Correct?
So, what if an other parent caller comes around and wants to initiate a different I2C bus, on an other pair of pins? The way I understand it, if this new caller calls Init with some new set of pin numbers, this will hit back on the original one, and redefine those pin numbers in the same go. Correct?
If so, do I need two different I2C drivers, one like the above, which assumes everyone want to go on the same physical bus, and an other version where the VAR is used instead of DAT?
Or is there some even more devious DAT technique where a set of pins could be defined for an object such as this??
The question is not related to I2C as such, but more in general about how this kind of 'varable sharing' can be done.
My trick for understanding this is to think of DAT as part of the code, not the variables. Code is loaded only once, variables are constructed each time an object is called (instantiated), modifying DAT is like modifying the code, and it therefore affects all the object instances. Is this far off?
Erlend
Comments
A standard object like BASIC_I2C names the pin(s) to use with each and every method call, i2c.xxx(sda,...) so one i2c object can be easily used with different i2c busses.
I like to define the pins as VAR, and then call i2c.init(sda,scl,...). Include the init with the same pins in each object that uses that bus. Each one uses a couple more bytes in VAR, but so what? Then, calls to that bus don't need to include the pin numbers. Each separate i2c bus defined needs to have its own OBJ instance and each one needs to be init'd it throughout the project.
An i2c bus is a system resource. If it can be accessed from different cogs, one has to be sure that calls to it don't clobber one another. If that is a possibility, the parent object needs either to coordinate tightly or to check out a lock and pass it along along with the pin numbers.
Erlend
A multiport i2c object written in PASM could (like the 4-port serial object) use a port/bus number to refer to each bus, and the pins associated with each bus would be stored in the PASM cog. If those were to be more or less fixed pins, they could be preset in the DAT section to be loaded into the cog.
Again, thanks.
Erlend
The suggestion of having multiple "ports" like Tracy's 4 port serial driver, is probably your best option with Spin. Still slower than the original, but less wasteful than having two full versions of the code just to change the pins.
This is probably my biggest complaint with Spin - Not being able to pass objects around in the code imposes some significant limits, but it's not the kind of thing you'd normally run into until your projects get big, and it's a big part of why I went with C/C++ for the flight controller code.
Thanks a bunch for all the good brain feed, right now I am implementing this scheme for the SPI bus, intended to run a number of powerStep01 chips.
Erlend
In more complex projects, I like to keep a core i2c bus that contains the eeprom and the RTC and RTC scratch ram and maybe other chips that are isolated from the outside world. Peripherals are relegated to a second bus, particularly if it goes off the board or is in any way susceptible to mess ups. Much easier to recover and continue and troubleshoot that way.