Question on accessing an object across cogs
dharwood
Posts: 12
I have a DS1302 that has a value (word) stored in the first two bytes of RAM.
If I run the following code as a method on the primary cog, I can retrieve and display it fine.
If instead I launch the method on its own cog, it doesn't work.
Being new to Spin and Propeller, I sure I am making a basic blunder but I can't see it. Anyone want to clue me in to what I am doing wrong in the second example?
Thanks!
If I run the following code as a method on the primary cog, I can retrieve and display it fine.
CON _clkmode = xtal1 + pll16x ' Feedback and PLL multiplier _xinfreq = 5_000_000 ' External oscillator = 5 MHz VAR word SwitchCount ' Counter to hold total number of switch closures byte cmd OBJ pst : "Parallax Serial Terminal" ' Serial Terminal object - requires 1 cog rtc : "DS1302_full" PUB Start ' Main method pst.Start(115_200) pst.Str(string("Starting up...")) rtc.init( 22, 21, 20 ) 'ports Clock, io, chip enable rtc.config 'Set configuration register SwitchWatch(@SwitchCount) waitcnt(clkfreq * 2 + cnt) ' Wait 1 second -> .5 Hz pst.Str(string(pst#NL, "RAM value...")) pst.Dec(SwitchCount) PRI SwitchWatch(CounterAddr) cmd:=rtc.command(rtc#ram,rtc#burst,rtc#r) rtc.readN(cmd, CounterAddr, 1)
If instead I launch the method on its own cog, it doesn't work.
CON _clkmode = xtal1 + pll16x ' Feedback and PLL multiplier _xinfreq = 5_000_000 ' External oscillator = 5 MHz VAR word SwitchCount ' Counter to hold total number of switch closures long Stack[20] ' Sets up a stack space byte SwitchCogID ' Cog ID of the SwitchWatch Cog byte cmd OBJ pst : "Parallax Serial Terminal" ' Serial Terminal object - requires 1 cog rtc : "DS1302_full" PUB Start ' Main method pst.Start(115_200) pst.Str(string("Starting up...")) rtc.init( 22, 21, 20 ) 'ports Clock, io, chip enable rtc.config 'Set configuration register SwitchCogID := cognew(SwitchWatch(@SwitchCount), @Stack) 'Starts a Cog, calls SwitchWatch, the Cog uses @stack waitcnt(clkfreq * 2 + cnt) ' Wait 1 second -> .5 Hz pst.Str(string(pst#NL, "RAM value...")) pst.Dec(SwitchCount) PRI SwitchWatch(CounterAddr) cmd:=rtc.command(rtc#ram, rtc#burst, rtc#r) rtc.readN(cmd, CounterAddr, 1)
Being new to Spin and Propeller, I sure I am making a basic blunder but I can't see it. Anyone want to clue me in to what I am doing wrong in the second example?
Thanks!
Comments
Thanks! I have moved the rtc.init and rtc.config calls into the SwitchWatch method, and as you suggest, it does work.
Unfortunately, I was hoping to use this object on both cogs. I want to use the clock functions on the main cog and the ram functions on the seperate cog.
My thinking was that SwitchWatch would run in its own cog and count switch closures via a shared VAR, that also gets persisted to the DS1302 RAM. This way, everytime it restarts, it can pick up where it left off.
Meanwhile the main cog could be logging the "current" count at set time intervals, and reset it to zero once it is captured.
Am I barking up the wrong tree here? Is this not going to work using two seperate cogs to access this chip?
Thanks
Say more about how often and how quickly you have to access the DS1302. You will need to be become familiar with the LOCKxxx statements. Have a look at the Propeller Manual starting at page 120.
Update: Wouldn't you know it, they are already queueing
Question...did I understand you correctly, are you saying I should NOT use the RTC object and do it myself with locking? Or should I still use the RTC object, but use locking?
Thanks for the help!
Everything else should work the same as it does with the OBEX RTC except that the other methods can be called from multiple cogs. I strongly suggest you look at the modified code. It does two things differently:
1) Any operation that accesses the DS1302 uses a "lock" first to prevent any other cogs from accessing the DS1302, then releases the lock before returning from RTC.
2) The I/O pins (OUTA and DIRA for all cogs) are always left in either input mode or output low. If you look at how the various cogs' I/O registers are wired (in the diagram on the Propeller Downloads webpage), this allows multiple cogs to control the I/O pins, changing the pins to either output low or high (from input mode) or to output high (from output low).
NOTE: I haven't tested this yet, but it should work
Update: Corrected RTC.config
Update: Now object can be declared in multiple objects
Thank you for modifying the DS1302_Full object to work with multiple cogs!
I tested it and it works, except for one thing....
I had to comment out the: repeat while lockset(locknum) and lockclr(locknum) lines within the RTC.Config method. While I don't pretend to know why this caused it to freeze, I didn't think they were needed, since the RTC.Config should only be called once from the main cog, therefore shouldn't require locking.
With that change, I was able to have one instance of the RTC obj defined and access it's methods from both cogs.
Can't thank you enough!
Dan
There is one cog who is accessing the hardware. This cog does it all the time updating some variables in a DAT-section
every other cog can access the variables in the DAT-ection thrugh the HUB-RAM-adresses. So other cogs only read the
information from the variables.
If any cog wants to change the RTC-registers this would be done over DAT-variables too.
keep the questions coming
best regards
Stefan
I've updated the archive on message #7
Tried your modified version and naturally, it works like a charm.
Thanks again!