Strange problem - can't figure it out!
Hmm... seem to have a problem that I can't get to the bottom of... I am trying to make this as short as possible,
but it's a bit lengthy to explain (sorry):
I have been working on a prop-based unit that contains several i2c devices, one of which is a RTC. The code that
manages these devices runs in a separate cog, so to get the current time I use a caller function that operates, via
flags to avoid contention, as follows:
clkptr := dm.GetClock ' clkptr is pointer to byte array [noparse][[/noparse]0]=seconds, =minutes ...hour/wkday/date/month/year/(ms x 10)
Where dm is the device manager object. I have tested this object extensively and, as far as I am aware, it functions
100% reliably; certainly my testing has shown this to be the case.
Because I have the RTC I have implemented a timing schema that operates over a maximum period of one hour, or
3600000 milliseconds. In order to utilise the timer (and have multiple concurrent timers) I initially call a function
GetTimeStamp:
PRI GetTimeStamp | clkptr
' Calculates 60000 * minutes + 1000 * seconds + 10 * milliseconds
clkptr := dm.GetClock
return (byte[noparse][[/noparse]clkptr+1] * 60000) + (byte[noparse][[/noparse]clkptr] * 1000) + (byte[noparse][[/noparse]clkptr+7] * 10)
and to get the elapsed time I then use
PRI TimeDiff(startt) | now
now := GetTimeStamp
' Check rollover (going from mins=59 to mins=0)
if now < startt ' rolled over
return startt + (3600000 - startt) + now
else
return now - startt
So, using the timer is (or should be) as simple as
start := GetTimeStamp
..some time passes
elapsed := TimeDiff(start) ' Returns milliseconds
***********
THE PROBLEM:: If I use
***********
repeat while TimeDiff(start) < some_value
..some code
the code will sometimes exit early, that is, WELL before the time difference reaches the value of some_value.
WHEREAS..
start := GetTimeStamp
repeat while var_name < 3000 ' For example!
var_name := TimeDiff(start)
WORKS??....?! Why would using an additional variable here make such a difference? I'm a bit confused. I thought
maybe it was just a fluke, but I ran the above code for two separate one hour sessions today - both of which
crossed the zero boundary - and it didn't fail once. So I look to the collected wisdom of the sages on this forum!
-CF
but it's a bit lengthy to explain (sorry):
I have been working on a prop-based unit that contains several i2c devices, one of which is a RTC. The code that
manages these devices runs in a separate cog, so to get the current time I use a caller function that operates, via
flags to avoid contention, as follows:
clkptr := dm.GetClock ' clkptr is pointer to byte array [noparse][[/noparse]0]=seconds, =minutes ...hour/wkday/date/month/year/(ms x 10)
Where dm is the device manager object. I have tested this object extensively and, as far as I am aware, it functions
100% reliably; certainly my testing has shown this to be the case.
Because I have the RTC I have implemented a timing schema that operates over a maximum period of one hour, or
3600000 milliseconds. In order to utilise the timer (and have multiple concurrent timers) I initially call a function
GetTimeStamp:
PRI GetTimeStamp | clkptr
' Calculates 60000 * minutes + 1000 * seconds + 10 * milliseconds
clkptr := dm.GetClock
return (byte[noparse][[/noparse]clkptr+1] * 60000) + (byte[noparse][[/noparse]clkptr] * 1000) + (byte[noparse][[/noparse]clkptr+7] * 10)
and to get the elapsed time I then use
PRI TimeDiff(startt) | now
now := GetTimeStamp
' Check rollover (going from mins=59 to mins=0)
if now < startt ' rolled over
return startt + (3600000 - startt) + now
else
return now - startt
So, using the timer is (or should be) as simple as
start := GetTimeStamp
..some time passes
elapsed := TimeDiff(start) ' Returns milliseconds
***********
THE PROBLEM:: If I use
***********
repeat while TimeDiff(start) < some_value
..some code
the code will sometimes exit early, that is, WELL before the time difference reaches the value of some_value.
WHEREAS..
start := GetTimeStamp
repeat while var_name < 3000 ' For example!
var_name := TimeDiff(start)
WORKS??....?! Why would using an additional variable here make such a difference? I'm a bit confused. I thought
maybe it was just a fluke, but I ran the above code for two separate one hour sessions today - both of which
crossed the zero boundary - and it didn't fail once. So I look to the collected wisdom of the sages on this forum!
-CF
Comments
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
I don't know the reason from just reading your post.
As I don't have your hardware it's hard to test it.
How about debugging via a serial connection to your PC
and logging the received data to a file ?
Then you can look at the file and maybe you can detect some strange things and when they do happen
One Idea right out of the blue sky: Did you reserve enough stackspace in the cognew-commands ?
best regards
Stefan
I've spent more time on this 'simple' problem than I did on modifying Timothy's 8 bit driver for the oled-96 to 65K colours! So you can see how frustrating it's becoming
It should be:
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
I'm pretty sure the algorithm's OK". But now I think you could be right; I think I missed
a step somewhere.
It's late here so I'm going to have to pick this up in the am... I'll let you know if I sort this
out. Quite why it works using the variable, but otherwise not, isn't clear to me right now.
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
I implemented this change, however the result is still the same. I've come to the conclusion that it's something to do with reading the i2c bus; during the delay periods I am also reading the state of some input buttons connected to another device. Looks like the bus hasn't had time to settle down properly between successive reads, and when I read the clock again it returns something rather undefined. I'm really surprised at that, as the i2c code is all spin (uses Mike Green's Basic_I2C_Driver) and therefore should result in significant delays between reads... well, I could spend another several days tracking this down or implementing some kind of improved error checking, but I'm not going to, instead I'm planning a version of the same thing that uses the prop's internal timers which I'm sure will fix this.
In any case, there's nothing wrong with the prop or the spin compiler / interpreter (I'm hardly surprised at THAT conclusion!)
-CF