Dat org 0
C_og1
loop1 mov mem, par
wrlong one, mem
jmp #loop1
C_og2
loop2 mov mem, par
add mem, #4
wrlong two, mem
jmp #loop2
one long 1
two long 2
mem res 1
What's the (cog) address of labels C_og1 and loop1?
What's the (cog) address of labels C_og2 and loop2?
What's are the (cog) addresses of labels one, two and mem?
(all in the context of the listed DAT block)
Once we established that I have some more questions.
By cog address do you mean which cog they are running in (or have been instructed to run in)?
Nope, I mean exactly what Eric so conveniently answered for you. If you have a loop in assembler the jump has to go somewhere. Normally we hide numeric values behind label names. Now, if we look at this one level down we get this picture:
DAT org 0 ' cog address
C_og1
loop1 mov 9, $1F0 ' $000
wrlong 7, 9 ' $001
jmp #0 ' $002
C_og2
loop2 mov 9, $1F0 ' $003
add 9, #4 ' $004
wrlong 8, 9 ' $005
jmp #3 ' $006
one long 1 ' $007
two long 2 ' $008
mem res 1 ' $009
DAT
This is what you'd actually see when you disassemble the binary file. After cognew(@C_og1, address) has finished the first 10 registers in the cog will look like this (location 9 will be more or less random depending on what your SPIN code looks like).
Is this OK so far? Can you see how the first loop works?
Sorry about the brevity to my response, but I tend to only answer the question.
I haven't read the whole thread, but I think I know where kuroneko is going with this.
DAT org 0 ' cog address
C_og1
loop1 mov 9, $1F0 ' $000 move the contents of register $1F0 (aka PAR, i.e. the second parameter in the SPIN cognew statement) to register 9
wrlong 7, 9 ' $001 write the contents of register 7 to the HUB address pointed to by the contents of register 9
jmp #0 ' $002 move the immediate value 0 to the program counter, execution continues with the instruction in register 0
C_og2
loop2 mov 9, $1F0 ' $003 move the contents of register $1F0 (aka PAR, i.e. the second parameter in the SPIN cognew statement) to register 9
add 9, #4 ' $004 add the immediate value 4 to the contents of register 9
wrlong 8, 9 ' $005 write the contents of register 8 to the HUB address pointed to by the contents of register 9
jmp #3 ' $006 move the immediate value 3 to the program counter, execution continues with the instruction in register 3
one long 1 ' $007 the contents of register 7 is the value 1
two long 2 ' $008 the contents of register 8 is the value 2
mem res 1 ' $009 the contents of register 9 is undefined as no data is stored in HUB RAM for this register
So if you did a cognew(@C_og1, @variable) the value of variable would be continuously overwritten with the value 1 after ~8K clock cycles. However, if you tried to cognew(@C_og2, @variable) the value of variable would be overwritten with an unknown value only once after ~8K clock cycles. This is because the C_og2 instruction would be loaded into register 0, not register 3 and would look like:
DAT org 0 ' cog address
C_og2
loop2 mov 9, $1F0 ' $000 move the contents of register $1F0 (aka PAR, i.e. the second parameter in the SPIN cognew statement) to register 9
add 9, #4 ' $001 add the immediate value 4 to the contents of register 9
wrlong 8, 9 ' $002 write the contents of register 8 to the HUB address pointed to by the contents of register 9
jmp #3 ' $003 move the immediate value 6 to the program counter, execution continues with the instruction in register 3
one long 1 ' $004 the contents of register 4 is the value 1
two long 2 ' $005 the contents of register 5 is the value 2
mem res 1 ' $006 the contents of register 6 is undefined as no data is stored in HUB RAM for this register
Very interesting indeed. The point of interest (getting it right) seems to have been made by "jazzed" by pointing out that we need another DAT statement to end what is contained in Cog1 before starting Cog2. That aside, I appreciate your taking the time to spell it all out for me so that I can hopefully pass the information on the beginners without messing it up.
An interesting aside to this is that I did not appreciate what kureneko was trying to get across to me and you saw it right away. I do not even understand the jargon at this time!! One more indication that beginners need to really start in the beginning and there seems to be no indicator, as far as I can see, as to where the beginning needs to be. Maybe I can help in that direction.
I am finding that a long declared as a PASM program constant at the bottom of the program can have its value changed by the program.
So it is not a constant forever the same as constants that are declared under CON.
Is this true and is it a proper use of a variable.
Or is just one way to declare a variable.
H
They are not constants but initialized variables. It it quite normal as you will see in many objects.
You can also change their values before launching the associated assembly cog if I remember rightly which can be useful and avoids having to send set-up parameters via par.
A long in DAT is not any kind of constant. It is initialized with what ever value you put in your code but can be changed by Spin or PASM after. But beware that long may be loaded into COG with your PASM in which case that same LONG you wrote has a dual existance, in the COG or COGs and the original place it occupied in HUB.
No you do not need to start a new DAT section to have more than one COGs PASM in an object.
Well I don't have the fat lady singing yet as regards the use of PAR.
I cannot figure out a simple rule that tells me when the variables being pointed to by PAR will be cleared or not.
What does one have to do or not do to preserve the variables across all cogs
And what does one have to do the clear them either on purpose or by mistake.
I can make it work but I am not sure I am doing it right. And things get messed up inadvertently.
i.e. I still don't have the confidence to tell beginners what to do or not do.
PAR is typically a pointer to a long in HUB RAM (which may be the first long in an array or list of longs). Note: due to how coginit (PASM) works, only bits 2-15 of PAR are valid; the other bits are zero; therefore PAR cannot point to a byte or word. It's also a read-only register.
Because HUB RAM is shared by all cogs, any cog can make updates. Changing the long pointed to by PAR is done via WRLOG register, PAR (where register contains the desired value).
I don't meant be flipant but I guess the simple as to when variables pointed to by PAR are cleared or not is:
If you clear them they are cleared. If you don't they are not.
I think you should answere kureneko's little quiz questions in pozt #542 before proceeding as we are suspecting a confusion over the use of DAT and/or ORG and/or RES here.
Well I don't have the fat lady singing yet as regards the use of PAR.
I cannot figure out a simple rule that tells me when the variables being pointed to by PAR will be cleared or not.
What does one have to do or not do to preserve the variables across all cogs
And what does one have to do the clear them either on purpose or by mistake.
I can make it work but I am not sure I am doing it right. And things get messed up inadvertently.
i.e. I still don't have the confidence to tell beginners what to do or not do.
Ericball answered the question in # 542. Iresponded by mading the corrections and posted to jazzed that everything wored fine for the simp[le programs that I was running. I dont think I am doing thingsany different now!!
======
Well I do think I am getting a handle on things so its not totally blind on my part.
Here is what I have going
Program 1
Reads a potentiometer stores it at Par pointer 1st position. Variable passed is @P_Val
Performs a division and stores the result in PAR pointer +16 the 5th long location
One routine displays the data, One stores it via PAR pointers.
Everything works fine I can read the data and it is what I want where I want it to be.
Running the program shows everything just right on the PST
No problems.
Program 2
Calls the all of the program in program 1 and everything is fine
Running the program shows everything just right on the PST
No problems.
Next I call just the part of the program that stored the variables in program 1
I get zeroes.
All routines that refer to the data use @V_Pal as the passed variable
Here are the listings you can comment routines out as you see fit.
{{
022 PASM Read4Pots.spin
Program to read 4 pots
Repeats the program GOOD 006 PASM ReadPot 4 times
Installs in separate cog.
Reads resistances to 12 bits appears in POT_RES global variable
15 Dec 2011
By Harprit Sandhu
}}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
bits=12
pots=8
VAR
long P_Val[7]
long pot_sub
long clear
OBJ
fds : "FullDuplexSerial"
PUB Main (address) 'P_VAL is a local variable here
fds.start(31,30,0,115200) 'start console at 115200 for debug output
read_Pots(@P_Val)
dira[0..2]~~
repeat 'endless loop
pot_sub:=0 'reset id of pot to be printed
fds.tx($1) 'home to 0,0
repeat pots 'loop to display data
fds.bin(P_val[pot_sub], bits) 'print to the PST in binary
repeat 2 'two spaces
fds.tx(" ") 'space to erase old data overflow
fds.dec(P_val[pot_sub]) 'print value as decimal value
repeat 2 'two spaces
fds.tx(" ") 'space to erase old data overflow
fds.dec(pot_sub*4) 'print value as decimal value
repeat 3 'three spaces
fds.tx(" ") 'space to erase old data overflow
fds.tx($d) 'new line
pot_sub:=(pot_sub)+1 'increment display counter
waitcnt(clkfreq/60+cnt) 'flicker free wait
clear:=clear+1 'increment counter. This routine clears up screen
if clear>10 'decision point by erasing extra lines of bot
fds.tx(16) 'clear screen of PST display every 10 loops
clear:=0 'reset counter
PUB Read_Pots(address)
cognew(@Read_P, address)
'----------------------------------end of first Cog------------------------------------------
DAT org 0 'sets the starting point in Cog
Read_P mov dira, set_dira 'sets direction of the prop pi
mov pots_read, #1 'number of pots to read [also change data]
mov bits_read, #12 'bit resolution of 3208 IC, can be less
mov mem, par 'get address of mem for PAR
mov mem1, mem
mov pot_id, #0 'first pot read is pot 0
Next_pot or outa , chs_Bit 'makes Chip select high
andn outa, chs_Bit 'makes chip select low
andn outa , clk_bit 'ANDN it with the Clock Bit to make low
or outa , din_Bit 'makes the Din high
call #Tog_clk 'toggle clock line hi-low to read data
or outa , din_Bit 'makes the Din high
call #Tog_Clk 'toggle clock line hi-low to read data
mov temp2, pot_id 'we will read three bits from this pot
call #get_third_bit 'get bit
if_nz jmp #its_one 'jump to set it as needed
jmp #its_zero 'jump to set it as needed
its_one call #Set_next_bit1 'setting bit subroutine call
jmp #continue1 'go to next bit
its_zero call #Set_next_bit0 'setting bit subroutine call
continue1 call #get_second_bit 'get bit
if_nz jmp #its_one1 'jump to set it as needed
jmp #its_zero1 'jump to set it as needed
its_one1 call #Set_next_bit1 'setting bit subroutine call
jmp #continue2 'go to next bit
its_zero1 call #Set_next_bit0 'setting bit subroutine call
continue2 call #get_first_bit 'get bit
if_nz jmp #its_one2 'jump to set it as needed
jmp #its_zero2 'jump to set it as needed
its_one2 call #Set_next_bit1 'setting bit subroutine call
jmp #continue3 'go to next bit
its_zero2 call #Set_next_bit0 'setting bit subroutine call
continue3 andn outa , din_Bit 'makes Din low
call #Tog_Clk 'toggle clock line hi-low to read data
call #Tog_Clk 'toggle clock line hi-low to read data
mov Data_read, #0 'clear register we will read data into
mov bit_count, bits_read 'counter for number of bits we will read
read_bit mov temp, ina 'read in what is in all the input lines
andn temp, mask26 wz 'mask off except Dout line. Set Z flag
shl Data_read, #1 'shift register left 1 bit for next bit
if_nz add Data_read, #1 'if value + add 1 to data register
call #Tog_Clk 'toggle clock get next bit ready in Dout
sub bit_count, #1 wz 'decr the "bits read" counter. Set Z flag
if_nz jmp #read_bit 'go up do it again if counter not yet 0
wrlong Data_read, mem wz 'write it in PAR to share it as P.Val
if_z jmp #next_pot
call #get_beat
skip add mem1,#16
wrlong data_read, mem1
add mem, #4 'add 4 to hub address for next long
mov mem1, mem
add pot_id, #1 'so we can look at next pot
mov temp2, pot_id 'recall what pot we are reading
sub temp2, pots_Read wz 'check if it is how many we want to read
if_nz jmp #Next_pot 'if it is not 0 go up and read next pot
jmp #Read_P 'go back beginning and do all pots again
'subroutines used
Set_next_bit0 andn outa , din_Bit 'makes Din low in 000 for line
call #Tog_Clk 'toggle clock line hi-low to read data
Set_next_bit0_ret ret 'return from this subroutine
Set_next_bit1 or outa , din_Bit 'makes Din high in 000 for line
call #Tog_Clk 'toggle clock line hi-low to read data
Set_next_bit1_ret ret 'return from this subroutine
Tog_Clk nop 'nop to settle signals
or outa, clk_bit 'make clock bit high
nop 'nop to settle signals
andn outa, clk_bit 'make clock bit low
nop 'nop to settle signals
Tog_Clk_ret ret 'return from this subroutine
Get_first_bit mov temp2, pot_id 'get current pot number
andn temp2, mask0 wz 'get last bit
Get_first_bit_ret ret 'return
Get_second_bit mov temp2, pot_id 'get current pot number
shr temp2, #1 'shift right 1 bit to get second bit
andn temp2, mask0 wz 'return
Get_second_bit_ret ret
Get_third_bit mov temp2, pot_id 'get current pot number
shr temp2, #2 'shift right 2 bits to get third bit
andn temp2, mask0 wz 'return
Get_third_bit_ret ret
Get_beat mov temp3, data_read
shl temp3, #3
mov total, clkf
mov beat, #0
do_again sub total, temp3 wc
add beat, #1
if_nc jmp #do_again
sub beat, #1
mov data_read, beat
Get_beat_ret ret
Set_dira long 001011_00000000_00000000_00000111 'Set dira register
Chs_Bit long 000001_00000000_00000000_00000000 'Chip select bit 24
Din_Bit long 000010_00000000_00000000_00000000 'Data in bit 25
Dout_Bit long 000100_00000000_00000000_00000000 'Data out bit 26
Clk_Bit long 001000_00000000_00000000_00000000 'Clock bit 27
mask26 long 111011_11111111_11111111_11111111 'Mask to read Dout bit
mask0 long 111111_11111111_11111111_11111110 'Mask to read 0 bit
clkf long 80_000_000
beat res 1
mem res 1 'Par location
mem1 res 1
temp res 1 'temporary storage variable, misc
temp2 res 1 'temporary storage variable, misc
temp3 res 1
bit_count res 1 'temporary storage variable, read bit counter
Data_Read res 1 'temporary storage variable, data being read
pot_id res 1 'current pot id number
pots_read res 1 'total number of pots to be read.
bits_Read res 1 'resolution of data read, 12 bits max
total res 1
{
OSC for metronome
Read pot and display on PST through 022 PASM Rea4PotsX
And sets up basic count oscillator
}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
'bits=32
VAR
long P_Val[7]
obj
RP : "ReadPots" 'reads pots
PUB Main
dira[0..2]~~
RP.main(@P_val)
'RP.read_Pots(@P_val)
Oscillate (@P_val)
PUB Oscillate (address)
cognew(@Oscil, address)
DAT org 0
Oscil mov dira, set_dira 'sets direction of the prop pins
loop mov mem, par 'get par address
add mem, #16
rdlong Pot, mem
mov delay, cnt 'read in CNT
add delay, 50 'add to skip over counter fill
andn outa, bit_1 'bits low
waitcnt delay, pot 'pause
mov delay, cnt 'read in CNT
add delay, 50 'add to skip over counter fill
or outa, bit_1 'bits high
waitcnt delay, pot 'pause
jmp #loop 'loop back
Set_dira long 001011_00000000_00000000_00000111 'Set dira register
bit_1 long 000000_00000000_00000000_00000001 'output bit
pot res 1
mem res 1 'memory location for PAR variable
delay res 1 'delay constant for CNT
Next I call just the part of the program that stored the variables in program 1 I get zeroes.
By that I assume you mean program 2 does this? If not please elaborate.
PUB Main
dira[0..2]~~
RP.read_Pots(@P_val)
Oscillate (@P_val)
What does get zeroes actually mean (you don't have PST output in this case AFAICS)? It would also help if you used a technique (to attach code) which doesn't destroy binary constants.
What goes on here?
That code in post #557 does not even compile.
There are binary constants with out %
There are two _clkmode and _xinfreq which at least BST does not like.
No they don't. It would make it easier (and faster) for us to help you if you'd actually answer questions posed to you. Otherwise people will stop responding.
My sincerest apologies. I try to answer all questions unless someone else does or they other wise get discussed.
Or if I think they are tangential to a beginner's interests at this time.
I copied the programs from code that I was running so they should have compiled.
The % indicators were stripped by the discussion software.
I was unaware that it does that.
No one has ever mentioned it before to my knowledge.
As regards #558 I am not getting any output on the PST but if I put in 0s for the variables, I get the same output on the O'scope as if I had read 0s
@Jazzed
I will call Tech support on Monday and report the results
@Heater
I store the variables, I never clear them and then later I cannot read them. Something is happening that is causing them to be cleared and I cannot
figure out what it is. Till I know I cannot proceed with the book because this affects everything about my understanding of what is going on and how I explain it.
I've been at it for two weeks!!
@All
Lets try again with less code in the examples. I stripped almost everything that I could think of as unnecessary.
My code had the % binary designators in it but they were stripped by the discussion forum.
I do not know the reason.
I have eliminated them and shortened the code many times over to show just the essence of the problem I am having
The following code in the first program has two routines in it.
This program should be saved as "ReadPots2" when you save it. It will be called in a later program.
The first routine lets you look at the 12 LS bits on 8 registers, as longs, pointed to by PAR on the Parallax Serial Terminal
{{
Name this program"ReadPots2"
}}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
bits=12
pots=8
VAR
long P_Val[7]
long pot_sub
long clear
OBJ
fds : "FullDuplexSerial"
PUB Main 'P_VAL is a local variable here
fds.start(31,30,0,115200) 'start console at 115200 for debug output
read_Pots(@P_Val)
show
PUB Show
dira[0..2]~~
repeat 'endless loop
pot_sub:=0 'reset id of pot to be printed
fds.tx($1) 'home to 0,0
repeat pots 'loop to display data
fds.bin(P_val[pot_sub], bits) 'print to the PST in binary
repeat 2 'two spaces
fds.tx(" ") 'space to erase old data overflow
fds.dec(P_val[pot_sub]) 'print value as decimal value
repeat 2 'two spaces
fds.tx(" ") 'space to erase old data overflow
fds.dec(pot_sub*4) 'print value as decimal value
repeat 3 'three spaces
fds.tx(" ") 'space to erase old data overflow
fds.tx($d) 'new line
pot_sub:=(pot_sub)+1 'increment display counter
waitcnt(clkfreq/60+cnt) 'flicker free wait
clear:=clear+1 'increment counter. This routine clears up screen
if clear>10 'decision point by erasing extra lines of bot
fds.tx(16) 'clear screen of PST display every 10 loops
clear:=0 'reset counter
PUB Read_Pots(address)
cognew(@Read_P, address)
DAT org 0 'sets the starting point in Cog
Read_P mov dira, set_dira 'sets direction of the prop pi
mov mem, par 'get address of mem for PAR
wrlong data1, mem
mov mem1, mem
add mem1, #16
wrlong data2, mem1
jmp #Read_P
Set_dira long 7 'Set dira register
data1 long 2000
data2 long 500
mem res 1 'Par location
mem1 res 1
The second routine in the first program stores 2000 at the first PAR location and 500 at the fifth PAR location as longs
The second program reads the fifth PAR locations and uses it as a delay to turn bit 1 on the propeller on and off so I can look at it with a scope.
It does not
It should also allow you to look at the 8 PAR longs but it does not. The PST remains blank
I am at a complete loss as to why this is happening. And I know its something stupid on my part.
{
Name this [U]program[/U] "Oscillator" it calls "ReadPots2" as a OBJ
}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
bits=12
pots=8
VAR
long P_Val[7]
obj
RP : "ReadPots2" 'reads pots
fds : "FullDuplexSerial"
PUB Main
dira[0..2]~~
fds.start(31,30,0,115200) 'start console at 115200 for debug output
RP.read_Pots(@P_val)
RP.show
Oscillate (@P_val)
PUB Oscillate (address)
cognew(@Oscil, address)
DAT org 0
Oscil mov dira, set_dira 'sets direction of the prop pins
loop mov mem, par 'get par address
add mem, #16
rdlong Pot, mem
mov delay, cnt 'read in CNT
add delay, #50 'add to skip over counter fill
andn outa, bit_1 'bits low
waitcnt delay, pot 'pause
mov delay, cnt 'read in CNT
add delay, #50 'add to skip over counter fill
or outa, bit_1 'bits high
waitcnt delay, pot 'pause
jmp #loop 'loop back
Set_dira long 7 'Set dira register
bit_1 long 1 'output bit
pot res 1 'read variable
mem res 1 'memory location for PAR variable
delay res 1 'delay variable usage
The way I understand things, this should all work but it does not.
I am at a loss to understand why.
Your Show "pot_sub" variable increments forever, which means your output will probably be bogus after a few loops.
You add the contents of register 50 to your delay in DAT Oscil. What is in 50? Did you mean to use the value #50?
Of course Oscillate is never called since Show repeats forever.
I believe Kuroneko is asking you questions to inspire you to solve your own problems.
New knowledge can be cemented by thinking about such questions and answers.
Seems like he's trying to teach you how to fish.
A conference call may allow you to quickly resolve some software barriers in maybe a few minutes -vs- a few days.
The repeat that Pot_sub is is in, repeats pot times, so it get reset after reaching 7. It starts at 0.
The 50 is indeed mistake. Its should be #50. But I fixed that and it still does not work.
MAIN call three public methods each of which loops on its own. If Oscillate did not execute, nor would show
But show does execute because you can see the display of the PST which is called in show
Then I made the oscillator software a part of the ReadPots program. At the tail end.
Now the display show garbage numbers for the first and 5th longs in PAR but the
oscillation starts to work but it is insensitive to data changes in the 5th variable.
Very strange. I am as confused as I have ever been.
This is really driving me up the wall.
I'm going to re write the whole metronome object as one PASM routine with PASM subroutines to see what happens.
So I can examine variable my way.
Re #568 it means that you can write to PAR only with the last Cog you open. EVER. You cannot open a cog after the writes.
But...You read from other cogs in loops so that you re read the data after it was written later in the game.
Since this is not the case with my code, I need to recode
Re #568 it means that you can write to PAR only with the last Cog you open. EVER. You cannot open a cog after the writes.
But...You read from other cogs in loops so that you re read the data after it was written later in the game.
Since this is not the case with my code, I need to recode
Am I right?
H
There is a PAR register for every COG, so there is no interdependence between opening COG1 and COG2 (unless the value PAR passed for both cognew is the same).
I mean only that when you use cognew(@somecode, @somelong) the value of PAR is set to the address of somelong. Alternatively, cognew(@somecode, someaddr) will set PAR to the value of someaddr with the 2 lower bits cleared. That is the only way to set the value of PAR for a COG. If you write to PAR from inside the COG code, it is not changing PAR. Once PAR is set using cognew, it will not change.
You can change the data of the variable passed to PAR with no problem and read the data in the COG with rdlong, etc.... You just can't change PAR.
Comments
- What's the (cog) address of labels C_og1 and loop1?
- What's the (cog) address of labels C_og2 and loop2?
- What's are the (cog) addresses of labels one, two and mem?
(all in the context of the listed DAT block)Once we established that I have some more questions.
By cog address do you mean which cog they are running in (or have been instructed to run in)?.
@Ericball
I did not understand your post completely.
Please expand.
It is important for me to understand this thread in detail.
@jazzed
I made the changes you suggested and it does indeed work now. Thanks
Now to understand exactly what is going on! And why.
H
Is this OK so far? Can you see how the first loop works?
I haven't read the whole thread, but I think I know where kuroneko is going with this.
So if you did a cognew(@C_og1, @variable) the value of variable would be continuously overwritten with the value 1 after ~8K clock cycles. However, if you tried to cognew(@C_og2, @variable) the value of variable would be overwritten with an unknown value only once after ~8K clock cycles. This is because the C_og2 instruction would be loaded into register 0, not register 3 and would look like:
Very interesting indeed. The point of interest (getting it right) seems to have been made by "jazzed" by pointing out that we need another DAT statement to end what is contained in Cog1 before starting Cog2. That aside, I appreciate your taking the time to spell it all out for me so that I can hopefully pass the information on the beginners without messing it up.
An interesting aside to this is that I did not appreciate what kureneko was trying to get across to me and you saw it right away. I do not even understand the jargon at this time!! One more indication that beginners need to really start in the beginning and there seems to be no indicator, as far as I can see, as to where the beginning needs to be. Maybe I can help in that direction.
Thanks again I appreciated it.
H
So it is not a constant forever the same as constants that are declared under CON.
Is this true and is it a proper use of a variable.
Or is just one way to declare a variable.
H
You can also change their values before launching the associated assembly cog if I remember rightly which can be useful and avoids having to send set-up parameters via par.
Graham
No you do not need to start a new DAT section to have more than one COGs PASM in an object.
Well I don't have the fat lady singing yet as regards the use of PAR.
I cannot figure out a simple rule that tells me when the variables being pointed to by PAR will be cleared or not.
What does one have to do or not do to preserve the variables across all cogs
And what does one have to do the clear them either on purpose or by mistake.
I can make it work but I am not sure I am doing it right. And things get messed up inadvertently.
i.e. I still don't have the confidence to tell beginners what to do or not do.
H
Because HUB RAM is shared by all cogs, any cog can make updates. Changing the long pointed to by PAR is done via WRLOG register, PAR (where register contains the desired value).
If you clear them they are cleared. If you don't they are not.
I think you should answere kureneko's little quiz questions in pozt #542 before proceeding as we are suspecting a confusion over the use of DAT and/or ORG and/or RES here.
Ericball answered the question in # 542. Iresponded by mading the corrections and posted to jazzed that everything wored fine for the simp[le programs that I was running. I dont think I am doing thingsany different now!!
======
Well I do think I am getting a handle on things so its not totally blind on my part.
Here is what I have going
Program 1
Reads a potentiometer stores it at Par pointer 1st position. Variable passed is @P_Val
Performs a division and stores the result in PAR pointer +16 the 5th long location
One routine displays the data, One stores it via PAR pointers.
Everything works fine I can read the data and it is what I want where I want it to be.
Running the program shows everything just right on the PST
No problems.
Program 2
Calls the all of the program in program 1 and everything is fine
Running the program shows everything just right on the PST
No problems.
Next I call just the part of the program that stored the variables in program 1
I get zeroes.
All routines that refer to the data use @V_Pal as the passed variable
Here are the listings you can comment routines out as you see fit.
Harprit.
That code in post #557 does not even compile.
There are binary constants with out %
There are two _clkmode and _xinfreq which at least BST does not like.
Each will compile
H
My sincerest apologies. I try to answer all questions unless someone else does or they other wise get discussed.
Or if I think they are tangential to a beginner's interests at this time.
I copied the programs from code that I was running so they should have compiled.
The % indicators were stripped by the discussion software.
I was unaware that it does that.
No one has ever mentioned it before to my knowledge.
As regards #558 I am not getting any output on the PST but if I put in 0s for the variables, I get the same output on the O'scope as if I had read 0s
@Jazzed
I will call Tech support on Monday and report the results
@Heater
I store the variables, I never clear them and then later I cannot read them. Something is happening that is causing them to be cleared and I cannot
figure out what it is. Till I know I cannot proceed with the book because this affects everything about my understanding of what is going on and how I explain it.
I've been at it for two weeks!!
@All
Lets try again with less code in the examples. I stripped almost everything that I could think of as unnecessary.
My code had the % binary designators in it but they were stripped by the discussion forum.
I do not know the reason.
I have eliminated them and shortened the code many times over to show just the essence of the problem I am having
The following code in the first program has two routines in it.
This program should be saved as "ReadPots2" when you save it. It will be called in a later program.
The first routine lets you look at the 12 LS bits on 8 registers, as longs, pointed to by PAR on the Parallax Serial Terminal
The second routine in the first program stores 2000 at the first PAR location and 500 at the fifth PAR location as longs
===================================================================
The second program reads the fifth PAR locations and uses it as a delay to turn bit 1 on the propeller on and off so I can look at it with a scope.
It does not
It should also allow you to look at the 8 PAR longs but it does not. The PST remains blank
I am at a complete loss as to why this is happening. And I know its something stupid on my part.
The way I understand things, this should all work but it does not.
I am at a loss to understand why.
H
- Your Show "pot_sub" variable increments forever, which means your output will probably be bogus after a few loops.
- You add the contents of register 50 to your delay in DAT Oscil. What is in 50? Did you mean to use the value #50?
- Of course Oscillate is never called since Show repeats forever.
I believe Kuroneko is asking you questions to inspire you to solve your own problems.New knowledge can be cemented by thinking about such questions and answers.
Seems like he's trying to teach you how to fish.
A conference call may allow you to quickly resolve some software barriers in maybe a few minutes -vs- a few days.
The repeat that Pot_sub is is in, repeats pot times, so it get reset after reaching 7. It starts at 0.
The 50 is indeed mistake. Its should be #50. But I fixed that and it still does not work.
MAIN call three public methods each of which loops on its own. If Oscillate did not execute, nor would show
But show does execute because you can see the display of the PST which is called in show
Then I made the oscillator software a part of the ReadPots program. At the tail end.
Now the display show garbage numbers for the first and 5th longs in PAR but the
oscillation starts to work but it is insensitive to data changes in the 5th variable.
Very strange. I am as confused as I have ever been.
H
You are right about the loop in show.
It has to be called after the other methods start.
H
OK.
Is it possible the encountering a DAT resets everything in the world of PAR
H
The contents of the long variable pointed to by PAR can change of course, but not by the DAT statement.
I'm going to re write the whole metronome object as one PASM routine with PASM subroutines to see what happens.
So I can examine variable my way.
H
Re #568 it means that you can write to PAR only with the last Cog you open. EVER. You cannot open a cog after the writes.
But...You read from other cogs in loops so that you re read the data after it was written later in the game.
Since this is not the case with my code, I need to recode
Am I right?
H
There is a PAR register for every COG, so there is no interdependence between opening COG1 and COG2 (unless the value PAR passed for both cognew is the same).
I mean only that when you use cognew(@somecode, @somelong) the value of PAR is set to the address of somelong. Alternatively, cognew(@somecode, someaddr) will set PAR to the value of someaddr with the 2 lower bits cleared. That is the only way to set the value of PAR for a COG. If you write to PAR from inside the COG code, it is not changing PAR. Once PAR is set using cognew, it will not change.
You can change the data of the variable passed to PAR with no problem and read the data in the COG with rdlong, etc.... You just can't change PAR.