View Full Version : Cog registers?

01-11-2009, 03:37 AM
In the past, I've had trouble opening new cogs, due to missing the fact that each have their own registers. I have fixed the previous problems by declaring my registers in methods that have been launched into new cogs, but I don't see how that's exactly the problem. I imagine it's something similar, as the function I want to run in a new cog doesn't work correctly, but works when I run it in the same cog; but this puts me in an infinite loop.

Thanks in advance guys.


_xinfreq = 5_000_000
_clkmode = xtal1 + pll16x

SERVO_Pin_Right = 29
SERVO_Pin_Left = 26

PING_Pin = 28

LCD_Pin = 27 ' I/O Pin For LCD
LCD_Baud = 19_200 ' LCD Baud Rate
LCD_Lines = 4

'Compass Stuff
Enable = 0
Clock = 1
Data = 2

TotTime = 20000*80
'Control Coefficients

VAR byte i,j, stack1[100], stack2[100]
long HTa, range[10], rangeAve, HT, LT, Hold, theta, K, thetaGoal


LCD : "debug_lcd"
ping : "ping"
HM55B :"HM55B Compass Module Asm"

PUB main | CntNow

'FindAngle 'This will make it work, but I'm in an infinite Loop
cognew(FindAngle, @stack1) ' This opens a new cog, so I'm not stuck in a loop, but my text doesn't show up

PUB FindAngle

'The idea is to have a dedicated cog, just running this in an infinite loop, changing where the variable can be accessed by all

theta := HM55B.theta
LCD.gotoxy(14, 2) 'Copied print lines
LCD.decf(theta / 23, 3) '
waitcnt(clkfreq / 20 + cnt)

PUB Print_Angle 'This function also does not work at all, when called,

LCD.gotoxy(14, 2) 'I have to copy these two lines to the above method
LCD.decf(theta / 23, 3)

PUB InitializeLCD

LCD.init(LCD_Pin, LCD_Baud, LCD_Lines)
LCD.gotoxy(0, 0)
LCD.str(string("HighTime : "))
LCD.gotoxy(0, 1)
LCD.str(string("Range(in): "))
LCD.gotoxy(0, 2)
LCD.str(string("Angle(theta): "))

Phil Pilgrim (PhiPi)
01-11-2009, 03:59 AM
Initial impression here: You've defined your stacks as bytes instead of longs. 100 bytes is probably not only too short but misaligned as well. Try it with longs instead.


01-11-2009, 05:58 AM
Good thought Phil, but no dice. Changed stack1 to a long, and gave it 1000 instead of 100.

Paul Rowntree
01-11-2009, 06:24 AM
Can you narrow it down to a problem with the compass or the LCD by printing some looping values and comment out the compass code?

01-13-2009, 09:37 AM
I replaced the LCD printing line with one that just prints a variable that is declared in my CON block. It works fine so it isn't my LCD code, it's definitely the 'FindeAngle' function, which just calls the 'HM55B Compass Module' by Beau Schwabe. That program starts its own cog...but I don't see why that would be a problem, as I should have plenty left.

Here's all but the ASM code from the HM55B, which is called:

long cog,Enable,Clock,Data,HM55B_x,HM55B_y,HM55B_theta

PUB stop
'' Stop driver - frees a cog
if cog
cogstop(cog~ - 1)

PUB start(EnablePin,ClockPin,DataPin):okay
'' Start driver - starts a cog
'' returns false if no cog available
Enable := EnablePin
Clock := ClockPin
Data := DataPin
okay := cog := cognew(@HM55B, @Enable)

return HM55B_x

return HM55B_y

PUB theta
return HM55B_theta

Any help would be appreciated. I'm at a loss.

01-13-2009, 09:58 AM
It appears to me that you initialize the LCD in cog #0 but try to use from cog #1. The LCD initialization is likely setting at least one pin to as an output (changing the DIRA register) and this will not be transferred to another cog (each cog has its own DIRA register). You should execute the LCD initialization code in cog #1 if you want to use the LCD in cog #1.

01-13-2009, 10:13 AM
I think I'm with you, and I don't think it's the problem. Paul suggested that I narrow the problem down to see if the reason the value wasn't printing was because of the value, or bc of the printing aspect. I replaced the variable with a declared value from my CON block, and it printed fine, which shows that the LCD call is working, and that calling FindAngle in it's own cog is the problem. At least that is what makes the most sense to me right now; but you may be able to convince me otherwise.

Thanks, and keep 'em coming.

Beau Schwabe
01-13-2009, 10:37 AM

I don't think this would cause any problems, just the wrong or rather unexpected returned value... Remember that the angle returned in the theta value is in a 13-bit format which means that the returned value ranges from 0 to 8191 rather than the 0 to 359 that most people would expect.

0 Deg = 0
90 Deg = 2047
180 Deg = 4095
270 Deg = 6143

To convert the theta value to Deg, simply apply the formula...

Deg = theta * 45 / 1024

Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

Post Edited (Beau Schwabe (Parallax)) : 1/13/2009 3:52:54 AM GMT

01-13-2009, 10:44 AM
I do convert:

LCD.decf(theta / 23, 3)

Where 45 / 1024 ~ 22.7. So when I do get a number back, it's correct, I just don't get anything back when running it in it's own cog. The variable is defined in my VAR block, and so I'm fairly sure that each method and each cog sure have access to read from it. Is it possible that the new cog can't write to it for some reason? See what you think. I'll do some more work on it tomorrow afternoon. Thanks, again.

Beau Schwabe
01-13-2009, 10:51 AM

Also.... I am a little confused as to why you are using the HM55B.start every time that you call FindAngle. The HM55B.start should only be initialized once. Successive starts within FindAngle only starts up a new cog without closing the previous one. This could be your problem.

Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

01-13-2009, 11:19 AM
Wow...Somehow I missed that. There's a really good chance that's it. Thanks, I'll let you know.

01-13-2009, 11:27 AM
Wait...how? I call FindAngle one time, where it is launched in a new cog. This method calls start() once, and then runs a loop which is continuously updating theta...right? So start() is only called once. What am I missing?

Beau Schwabe
01-13-2009, 11:38 AM

Can you use the ... "File-->Archive-->Project" and attach that file to your post so that I can look at it tomorrow when I'm at my desk? I think I know what is going on but I need the entire program to confirm my thoughts.

Never mind.. I think I have enough of your code. I will look at it closer and let you know.

Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

Post Edited (Beau Schwabe (Parallax)) : 1/13/2009 4:45:41 AM GMT

01-13-2009, 11:53 AM
If you need the code, just let me know. And thanks, again.

Beau Schwabe
01-13-2009, 11:55 AM

Just for kicks, can you try this to see if anything prints to your LCD?

LCD.decf(4096 / 23, 3)

and then try....

LCD.decf(178, 3)

....and last but not least....

temp := 4096 / 23
LCD.decf(temp, 3)

... I have seen issues sometimes when you try to solve a formula inside of a CALL to another object. I just want to make sure that this is not happening here.

Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

01-13-2009, 12:32 PM
All of those gave me '178'

But they still yield nothing when I try to run it through a new cog.

Post Edited (heathclf) : 1/13/2009 5:37:35 AM GMT

01-14-2009, 12:30 AM
In your first listing, move the InitializeLCD call to the top of FindAngle and see if that helps.

01-14-2009, 02:51 AM

Um...yes. You're the man. Why did it? I'm confused. Will I have to run that script within each cog that I will want to write to the LCD?

Beau Schwabe
01-14-2009, 03:07 AM
heathclf (http://forums.parallax.com/member.php?u=53179),
"...Why did it?..." - for the same reason you have HM55B.start(Enable,Clock,Data) at the top of FindAngle... good job Pavel (http://forums.parallax.com/member.php?u=50185)
When you start a new cog with the line that reads cognew(FindAngle,·@stack1)· you are in a sense encapsulating everything within FindAngle to operate in it's own cog.· Since the LCD initialization portion was not included, you lost connectivity to the LCD that was defined previously defined·in the other cog.

Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

01-14-2009, 03:50 AM
The fix works for the reasons I described in my earlier post. In a nutshell, you need to configure the pin in the same cog that will be using it. If you set pin LCDPin as an output in cog #0, it's still remains an input pin in all other cogs (and you cannot transmit data to the LCD over a pin that is not an output pin). So cog #0 can use the LCD, other cogs cannot. By moving the display initialization to a call that is executed by cog #1 (the same cog that is actually using the LCD a bit later) the problem is fixed. This feature is described in the datasheet and the associated gotcha is mentioned in Tricks and Traps (but I've discovered it on my own (the hard way, of course)).

01-14-2009, 05:10 AM
Thanks, again Pavel.