Thanks for the clarifications guys. I needed that.
@Jazzed, of course we had gone over this before but I had a serious senior moment. Maybe it will stick this time.
Harprit
Here is about the fastest frequency you can generate in PASM. The signal will be outputted on pin 24. We can increase the frequency slightly by removing the NOP but then the on-off signals will not be the same length. The NOP in the loop is needed to compensate for the extra time it takes the routine to jump back to OUT1
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
VAR
long freq_gen
PUB wavelength
cognew(@prog_gen, @freq_gen) 'start new cog
dat
org 0
prog_gen mov dira, set_dira
out1 mov outa, on
nop
mov outa, off
jmp #out1
set_dira long %00000001_00000000_0000000_00000000
on long %00000001_00000000_0000000_00000000
off long %00000000_00000000_0000000_00000000
Don't forget to use the special registers CTRA, FRQA, etc... to generate even higher frequencies.
Also VSCL, VCFG, & waitvid can be used for parallel/serial conversion.
Maybe it has do with that cnt can not be in the des field.
Though in wrlong the dest field is used as the "source", it still reads from the cnt's shadow register.
I think the assembler should give a waring anytime the special registers that should normaly not be in the dest field.
Register CNT is readonly (practically speaking except for the "shadow").
By having CNT be the destination "D" of "wrlong D, S" you are saying write to CNT.
While this is not a bug, it is very annoying. You'll see the same problem with "wrlong INA, PAR".
You can say "rdlong CNT, PAR" but that won't work either because CNT is readonly.
You can say "rdlong OUTA, PAR" however.
The only real hint about what is happening with this problem AFAIK comes from the Propeller Datasheet (v1.2) bottom of page 16 table Special Purpose Registers. Remember the Datasheet is a manual too
I takes some time to get used to "shadow", call it ghost or overlapping.
A special register like CNT, have kind of multiplexing gate depending if you have it in the Dest or Source field.
So you have a single memory address but it have two different values in it.
The dest field version (aka shadow) could be used as a free storage ram as it's not used anyway.
This will work:
mov cnt, cnt ' move the value of the running Counter to ram location of what cnt address represents.
wrlong cnt, par ' the snap shoot of cnt above is moved to the hub address.
In a PASM book for beginners I would leave all talk of "shadow registers" to some later advanced chapter. Unless you have to say "don't do that" and then reference the advanced chapter.
In a PASM book for beginners I would leave all talk of "shadow registers" to some later advanced chapter. Unless you have to say "don't do that" and then reference the advanced chapter.
Indeed. Can't fault anyone for stumbling over the need for an explanation though
Jazzed,
Indeed, and this is the brilliant concept of having a beginner in PASM writing a beginners book on PASM. All those "gotchas" that hang beginners up for hours and days can be pointed out along the way by the author who has recently been bitten by them. An expert old hand may well have forgotten such trip ups by the time he writes his book.
Jazzed,
Indeed, and this is the brilliant concept of having a beginner in PASM writing a beginners book on PASM. All those "gotchas" that hang beginners up for hours and days can be pointed out along the way by the author who has recently been bitten by them. An expert old hand may well have forgotten such trip ups by the time he writes his book.
It's only brilliant (in a non-sarcastic sense) if it is properly critiqued, vetted, and serves the community positively.
I won't repeat any of my other opinions in this area.
I marvel at the usage of "brilliant" by some posters though.
Some of the contexts are not even in urban dictionary.
I'm with you 100%. This is for beginners and though very valid points have been made by Steve and all, we need to keep it as simple and uncomplicated as I possibly can. After the beginners get their feet wet, they can discover all sorts of things. Maybe even read the manual and the data sheet! I myself have been through the data sheet a couple of times but would not say I have read it and it would be ridiculous to say that I understand it and even more so to say that I could get out of it what experienced programmers can. What you see in the forest is conditioned by what you have seen in other forests. I think jazzed has something like this to say at the end of every post.
Book progress: As for the book, I think I can get it done now. I have spent a few days beating my head against the wall but I have also figured out how to look at what I want without a debugger! Now on its pretty much just slugging through the mud for me. I can see the other side of the swamp now. I kinda understand how I will do the stuff in PASM now. Besides I am getting great help and encouragement.
Note to readers: I am kind of following the format of my SPIN book so when we get done we can actually compare the same or similar programs written in the two languages and see how much faster one is than the other etc etc.
Will publish it electronically on the web. Taking advise now. Expect availability by the end of the year. Maybe!
I'm on page 70 of about 250. It will go faster now.
Present estimate and wild guess.
Here is the code to add a delay between turning the signal on and turning it off. Thus changing the frequency.
You change the value of 'deltime' to change the frequency.
If 'deltime' is a voltage dependent, we have a voltage controlled oscillator.
If it is a programmed function it will respond to any function.
Next time we will add another cog to this program to read the frequency of this signal.
The console displays the count and the delay number. The number is an arbitrary selection of 10_000 at this time
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
var
long freq_gen
long countup
OBJ
fds : "FullDuplexSerial"
'+++++++++++++++++++++++++Cog 0+++++++++++++++++++++++++++++++++
PUB wavelengths
fds.start(31,30,0,115200) 'start console at 115200 for debug output
dira := %00000000_10000000_00000000_00000000
cognew(@prog_gen, @freq_gen) 'start new cog
waitcnt(clkfreq/4+cnt)
repeat 'loop
fds.tx($1) 'home to 0,0
fds.dec (countup) 'checks to see if cog is looping per Stephan
fds.tx($0d) 'new line
fds.dec(freq_gen) 'print value or PAR as decimal
fds.tx($0d) 'space
countup := countup + 1 'increment unused counter
waitcnt(clkfreq/60+cnt) 'flicker free wait
'++++++++++++++++++++++++++Cog 1++++++++++++++++++++++++++++++++
dat
org 0
prog_gen mov dira, set_dira 'to set directions
out1 or outa, mask 'turn on pin
call #clkdelay 'wait
andn outa, mask 'turn off pin
call #clkdelay 'wait
wrlong deltime, par 'delay time
jmp #out1
clkdelay mov time, deltime 'the delay subroutine, load deltime into time
take4 sub time, #1 wz 'sub 1 from time and set flag if 0
if_nz jmp #take4 'if flag not 0 go back to take4
clkdelay_ret ret 'return for delay subroutine
deltime long 10_000 'time of delay
set_dira long %00000000_10000000_00000000_00000000
mask long %00000000_10000000_00000000_00000000 'mask
time res 1
He was known in the department as Quiet John. Quiet John Bardeen, the inventor of the transistor taught at the Uni of Ill, the same university where I did my graduate work. One of his doctoral students, a friend of mine told me that Quiet John would explain the most mundane things to you in the detail you needed without hesitation or talking down to you at your request. But he would do it only once! You were expected to pay full attention and understand it in one round. He had no patience with not paying close attention. (His first doctoral student is the inventor of the LED.) His two Nobel prizes were for work in physics (transistor, superconductivity) . He did not have a degree in physics.
Extending the program gives us the following code.
The program adds a second PASM cog to read the wavelength being generated. You have to look at the INA register three times to get the wave length. It may be necessary to look at it four times. See question at end of listing.
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
var
long freq_gen, freq_red
long countup
OBJ
fds : "FullDuplexSerial"
'+++++++++++++++++++++++++Cog 0+++++++++++++++++++++++++++++++++
PUB wavelengths
fds.start(31,30,0,115200) 'start console at 115200 for debug output
dira := %00000000_10000000_00000001_00000000
cognew(@prog_gen, @freq_gen) 'start new cog
cognew(@prog_red, @freq_red) 'start new cog
waitcnt(clkfreq/4+cnt)
repeat 'loop
fds.tx($1) 'home to 0,0
fds.dec (countup)
fds.tx($0d) 'space
fds.dec(freq_gen) 'print value as decimal
fds.tx($0d) 'space
fds.dec(freq_red) 'print value as decimal
fds.tx(" ") 'new line
countup := countup + 1
waitcnt(clkfreq/60+cnt) 'flicker free wait
'++++++++++++++++++++++++++Cog 1++++++++++++++++++++++++++++++++
dat
org 0
prog_gen mov dira, set_dira 'to set directions
out1 or outa, on
call #clkdelay 'turn on pin
andn outa, off
call #clkdelay
wrlong deltime, par 'turn off pin
jmp #out1
clkdelay mov time, deltime 'the delay subroutine, load deltime into time
take4 sub time, #1 wz 'sub 1 from time and set flag if 0
if_nz jmp #take4 'if flag not 0 go back to take4
clkdelay_ret ret 'return for delay subroutine
deltime long 10_000 'time of delay (constant for now)
set_dira long %00000000_10000000_00000000_00000000
on long %00000000_10000000_00000000_00000000
off long %00000000_10000000_00000000_00000000
time res 1
'+++++++++++++++++++++++++++Cog 2++++++++++++++++++++++++++++++++
dat
org 0
prog_red mov dira, set_dira1 'to make sure pin 23 is an input
out2 mov temp, ina 'look at INA register
and temp, mask23 wz 'look at only pin 23
if_z jmp #out2 'stay here while it is low
mov mem, cnt 'just turned high so read timer
out3 mov temp, ina 'look at INA register
and temp, mask23 wz 'look at only pin 23
if_nz jmp #out3 'stay here while high
out4 mov temp, ina 'look at INA register
and temp, mask23 wz 'look at only pin 23
if_z jmp #out4 'stay here while low
mov mem1, cnt 'just turned high so read timer
sub mem1, mem 'figure time interval
wrlong mem1, par 'write it to PAR
jmp #out2 'do it again
set_dira1 long %00000000_10000000_00000001_00000000
mask23 long %00001111_11111111_11111111_11111111
temp res 1 'for looking at pin
mem res 1 'for first CNT reading
mem1 res 1 'for second CNT reading
I have a question on this program.
When you run it and look at the console you will see that the wave length varies between 160000 and 160024 cycles. Why is this not constant?
'+++++++++++++++++++++++++++Cog 2++++++++++++++++++++++++++++++++
dat
org 0
prog_red mov dira, set_dira1 '[COLOR="red"]to make sure pin 23 is an input[/COLOR]
out2 mov temp, ina 'look at INA register
and temp, mask23 wz '[COLOR="orange"]look at only pin 23[/COLOR]
if_z jmp #out2 'stay here while it is low
mov mem, cnt 'just turned high so read timer
out3 mov temp, ina 'look at INA register
and temp, mask23 wz '[COLOR="orange"]look at only pin 23[/COLOR]
if_nz jmp #out3 'stay here while high
out4 mov temp, ina 'look at INA register
and temp, mask23 wz '[COLOR="orange"]look at only pin 23[/COLOR]
if_z jmp #out4 'stay here while low
mov mem1, cnt 'just turned high so read timer
sub mem1, mem 'figure time interval
wrlong mem1, par 'write it to PAR
jmp #out2 'do it again
[COLOR="red"]set_dira1 long %00000000_10000000_00000001_00000000[/COLOR]
[COLOR="orange"]mask23 long %00001111_11111111_11111111_11111111 [/COLOR]
temp res 1 'for looking at pin
mem res 1 'for first CNT reading
mem1 res 1 'for second CNT reading
When you run it and look at the console you will see that the wave length varies between 160000 and 160024 cycles. Why is this not constant?
The way you sample the pin introduces a certain amount of overhead. Imagine the pin change just before it's sampled and just afterA and follow the code (delay). Anyway, for this type of task waitpxx is THE way to go.
So much for my faith in the repeatability of digital systems!
You got what you asked for. Note that [thread=126265]there are ways[/thread] to account for the loop overhead but what exactly is wrong with using waitpxx in this situation (which would give you a +/- 1 cycle accuracy)?
So is there an uncertainty on the wave generation side also?
For a given delay the waveform is certain/repeatable. That said, it won't necessarily be what you expect as you have a hubop in your loop i.e. there may not be a simple relationship between delay and frequency generated (I haven't checked the exact timing though).
waitpxx. I will add optimization techniques as I go along in the book but for now I want to keep it as BASIC like as I can for beginners.
Question. If I have a HUBOP in my code, why does that make things indeterminate. Why does the HUBOP not act the same way through each cycle. And, could a synchronizing technique be used to improve duplication. ie make it more exact
I'm not sure I agree with considering waitpxx an optimization technique.. to me it's more about the Right Way and the Wrong Way. A polling loop which checks for bits to change is almost always the Wrong Way, and I don't think it's a good direction in which to steer beginning programmers. Habits learned early have a tendency to stick..
I am going to re post the code for reading a potentiometer with the MCP 3208 chip. This time around, the code has been optimized and all unnecessary items and subroutines have been removed. This code is in intended to run in a separate cog and provide the resistance of the potentiometer to 12 bits in a global variable called POT_RES available to all users.
We need to be able to read a potentiometer, because essentially there are two kinds of variables. We have control of one kind, as represented by a potentiometer and we do not have direct control of the other kind as might be represented by a temperature or the level in a large tank or any number of other variables that change as time goes on, but we cannot vary them with the turn of a knob.
As we progress, my plan is to use the potentiometer reading directly as an input into the frequency generating program and see if we cannot write a program that will give us the frequency that we specify with the potentiometer. Essentially, it means that the two variables displayed on the console will be the same. Since the potentiometer reading can go from 0 to 4095 we will have to make allowances for that in our program.
You can start playing with this since, all the information that we need has already been posted and you may want to develop the skills to put it all together in a useful way without assistance. In the next few days I will work this out myself to and post my results. For now, let us say that our goal is to be able to generate a frequency from 1000 to 2000 cycles per second as the potentiometer varies from zero to 4095. That's the results we get if we read the potentiometer to 12 bits.
{{
Program to read a pot OPTIMIZED, installs in separate cog.
Resistance to 12 bits appears in POT_RES global variable
August 13 2011
Sandhu
}}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
VAR
long POT_RES
long stack1[25] 'space for oscope
long stack2[25] 'space for speaker
OBJ
fds : "FullDuplexSerial"
PUB null | P_VAL
fds.start(31,30,0,115200) 'start console at 115200 for debug output
cognew(@generate, @P_Val) 'new cog at "generate" and read variable into P_Val
repeat 'loop
POT_RES:=P_VAL 'endless loop to display data
fds.tx($1) 'home to 0,0
fds.bin(P_val,12) 'print value to the PST in binary to match LEDs
fds.tx($d) 'new line
fds.dec(P_val) 'print value as decimal
fds.tx(" ") 'space
waitcnt(clkfreq/60+cnt) 'flicker free wait
DAT org 0 'sets the starting point in Cog
generate mov dira, set_dira 'sets direction of the prop pins
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 Bi to make low
or outa , din_Bit 'Makes the Din high
call #Tog_clk 'clk hi-lo to read data
or outa , din_Bit 'Makes the Din high
call #Tog_Clk 'clock line hi then low to read in the data
andn outa , din_Bit 'makes Din low 000 for line 0
call #Tog_Clk 'clock line hi then low to read in the data
andn outa , din_Bit 'makes Din low 000 for line 0
call #Tog_Clk 'clock line hi then low to read in the data
andn outa , din_Bit 'makes Din low 000 for line 0
call #Tog_Clk 'clock line hi then low to read in the data
andn outa , din_Bit 'makes Din low
call #Tog_Clk 'clock line hi then low to read in the data
call #Tog_Clk 'clock line hi then low to read in the data
mov dat_red, #0 'Clear register we will read data into
mov count, #12 '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 all except Dout line. Set Z flag
shl Dat_red, #1 'shift register left 1 bit ready for next bit
if_nz add Dat_red, #1 'if value is still pos add 1 to data register
call #Tog_Clk 'toggle clock to get next bit ready in Dout
sub count, #1 wz 'decrement the "bits read" counter. Set Z flag
if_nz jmp #read_bit 'go up and do it again if counter not yet 0
mov mem, par 'get address of mem
wrlong dat_red, mem 'write it in PAR to share it as P.Val
or outa , chs_Bit 'Makes Chip select high
jmp #generate 'go back to do it all again
Tog_Clk or outa, clk_bit 'make clock bit high
andn outa, clk_bit 'make clock bit low
Tog_Clk_ret ret 'return from this subroutine
Set_dira long %00001011_00000000_00000000_00000000 'Set dira register
Chs_Bit long %00000001_00000000_00000000_00000000 'Chip select bit 24
Din_Bit long %00000010_00000000_00000000_00000000 'Data in bit 25
Dout_Bit long %00000100_00000000_00000000_00000000 'Data out bit 26
Clk_Bit long %00001000_00000000_00000000_00000000 'Clock bit 27
mask26 long %11111011_11111111_11111111_11111111 'Mask for reading the Dout bit only
temp res 1 'temporary storage variable, misc
count res 1 'temporary storage variable, read bit counter
Dat_Red res 1 'temporary storage variable, data being read
mem res 1 'memory
That is a really tough call. We need an acceptable book for beginners. ALL beginners think PASM is an impossible monster. It is NOT, even though I was very hesitant to learn even the basics, even though many encouraged me to follow the SPIN book up with a PASM book. Please keep in mind that this is not a textbook. It is and introduction for hobbyists. How the reader uses it not up to the writer.
As to bad habits. Yes of course, but I am not going to be able to fix bad habits. Those interested enough will develop, read more, become good at it or whatever. Even maybe write a much better book. My job is to get the started. To suggest to them that they can learn this language.
New problem?
I can read a value generated in a PASM cog and use in in SPIN. Done
I can't seem to find how to take a value in SPIN and put it into a PASM Cog variable.
You've got to pass the address of the variable to the COG.
Typically, this is done with par, and offsets to par.
Put the variable in a DAT section, pass that address to the PASM COG with @variable in the COGNEW.
In the PASM COG:
rdlong variable, PAR
Of course, you also need a defined place in the PASM COG to put it. There are various naming schemes for this. One really easy one is to define the address at the higher level as a label in the DAT section thus:
DAT
MyVar long 0
And in the PASM COG
_MyVar res 1
Or some similar thing.
Multiple values are best done with a loop, where they are fetched one by one, adding to par each time, and adding to the base address in the COG each time, variables kept in sequence. (*which I get caught not doing, unless I really need the code space)
cogs have their COG-RAM absolutely exclusivly. The only way I know (maybe kuroneko knows more ;-) ) is to read a HUB-RAM-long into COG-RAM using the PASM-command RDLONG.
This means the PASM-Cog has to poll for it using RDLONG. Automatic pushing does not work.
The only way of pushing I can think of is using IO-PINS to "push" a byte towards PASM-code.
The special purpose registers INB and OUTB could be used.
One thing that occurred to me was as I puzzled this was that I could write to a long in high memory in the hub and then read the same address in a PASM cog
Does that make sense? Can one do things like that?
Comments
@Jazzed, of course we had gone over this before but I had a serious senior moment. Maybe it will stick this time.
Harprit
Here is about the fastest frequency you can generate in PASM. The signal will be outputted on pin 24. We can increase the frequency slightly by removing the NOP but then the on-off signals will not be the same length. The NOP in the loop is needed to compensate for the extra time it takes the routine to jump back to OUT1
We can decrease the frequency be adding delays.
We will do that next time.
HSS
Also VSCL, VCFG, & waitvid can be used for parallel/serial conversion.
Why does work and does not.
I cannot find anything in the Prop manual that says that the counter cannot be written directly to PAR as a long.
Harprit
Though in wrlong the dest field is used as the "source", it still reads from the cnt's shadow register.
I think the assembler should give a waring anytime the special registers that should normaly not be in the dest field.
Register CNT is readonly (practically speaking except for the "shadow").
By having CNT be the destination "D" of "wrlong D, S" you are saying write to CNT.
While this is not a bug, it is very annoying. You'll see the same problem with "wrlong INA, PAR".
You can say "rdlong CNT, PAR" but that won't work either because CNT is readonly.
You can say "rdlong OUTA, PAR" however.
The only real hint about what is happening with this problem AFAIK comes from the Propeller Datasheet (v1.2) bottom of page 16 table Special Purpose Registers. Remember the Datasheet is a manual too
That took me a day.
H
A special register like CNT, have kind of multiplexing gate depending if you have it in the Dest or Source field.
So you have a single memory address but it have two different values in it.
The dest field version (aka shadow) could be used as a free storage ram as it's not used anyway.
This will work:
mov cnt, cnt ' move the value of the running Counter to ram location of what cnt address represents.
wrlong cnt, par ' the snap shoot of cnt above is moved to the hub address.
Indeed, and this is the brilliant concept of having a beginner in PASM writing a beginners book on PASM. All those "gotchas" that hang beginners up for hours and days can be pointed out along the way by the author who has recently been bitten by them. An expert old hand may well have forgotten such trip ups by the time he writes his book.
All the best with this project Harprit.
It's only brilliant (in a non-sarcastic sense) if it is properly critiqued, vetted, and serves the community positively.
I won't repeat any of my other opinions in this area.
I marvel at the usage of "brilliant" by some posters though.
Some of the contexts are not even in urban dictionary.
I'm with you 100%. This is for beginners and though very valid points have been made by Steve and all, we need to keep it as simple and uncomplicated as I possibly can. After the beginners get their feet wet, they can discover all sorts of things. Maybe even read the manual and the data sheet! I myself have been through the data sheet a couple of times but would not say I have read it and it would be ridiculous to say that I understand it and even more so to say that I could get out of it what experienced programmers can. What you see in the forest is conditioned by what you have seen in other forests. I think jazzed has something like this to say at the end of every post.
Book progress: As for the book, I think I can get it done now. I have spent a few days beating my head against the wall but I have also figured out how to look at what I want without a debugger! Now on its pretty much just slugging through the mud for me. I can see the other side of the swamp now. I kinda understand how I will do the stuff in PASM now. Besides I am getting great help and encouragement.
Note to readers: I am kind of following the format of my SPIN book so when we get done we can actually compare the same or similar programs written in the two languages and see how much faster one is than the other etc etc.
Will publish it electronically on the web. Taking advise now. Expect availability by the end of the year. Maybe!
I'm on page 70 of about 250. It will go faster now.
Present estimate and wild guess.
Harprit.
You change the value of 'deltime' to change the frequency.
If 'deltime' is a voltage dependent, we have a voltage controlled oscillator.
If it is a programmed function it will respond to any function.
Next time we will add another cog to this program to read the frequency of this signal.
The console displays the count and the delay number. The number is an arbitrary selection of 10_000 at this time
Harprit.
He was known in the department as Quiet John. Quiet John Bardeen, the inventor of the transistor taught at the Uni of Ill, the same university where I did my graduate work. One of his doctoral students, a friend of mine told me that Quiet John would explain the most mundane things to you in the detail you needed without hesitation or talking down to you at your request. But he would do it only once! You were expected to pay full attention and understand it in one round. He had no patience with not paying close attention. (His first doctoral student is the inventor of the LED.) His two Nobel prizes were for work in physics (transistor, superconductivity) . He did not have a degree in physics.
Harprit.
No, it does not. Its the idea, not the book.
H
The program adds a second PASM cog to read the wavelength being generated. You have to look at the INA register three times to get the wave length. It may be necessary to look at it four times. See question at end of listing.
I have a question on this program.
When you run it and look at the console you will see that the wave length varies between 160000 and 160024 cycles. Why is this not constant?
Harprit
A sampling only happens once every 12 cycles
That possibly accounts for 12 cycles
So is there an uncertainty on the wave generation side also?
Harprit.
For a given delay the waveform is certain/repeatable. That said, it won't necessarily be what you expect as you have a hubop in your loop i.e. there may not be a simple relationship between delay and frequency generated (I haven't checked the exact timing though).
waitpxx. I will add optimization techniques as I go along in the book but for now I want to keep it as BASIC like as I can for beginners.
Question. If I have a HUBOP in my code, why does that make things indeterminate. Why does the HUBOP not act the same way through each cycle. And, could a synchronizing technique be used to improve duplication. ie make it more exact
Harprit.
-Tor
We need to be able to read a potentiometer, because essentially there are two kinds of variables. We have control of one kind, as represented by a potentiometer and we do not have direct control of the other kind as might be represented by a temperature or the level in a large tank or any number of other variables that change as time goes on, but we cannot vary them with the turn of a knob.
As we progress, my plan is to use the potentiometer reading directly as an input into the frequency generating program and see if we cannot write a program that will give us the frequency that we specify with the potentiometer. Essentially, it means that the two variables displayed on the console will be the same. Since the potentiometer reading can go from 0 to 4095 we will have to make allowances for that in our program.
You can start playing with this since, all the information that we need has already been posted and you may want to develop the skills to put it all together in a useful way without assistance. In the next few days I will work this out myself to and post my results. For now, let us say that our goal is to be able to generate a frequency from 1000 to 2000 cycles per second as the potentiometer varies from zero to 4095. That's the results we get if we read the potentiometer to 12 bits.
Harprit
That is a really tough call. We need an acceptable book for beginners. ALL beginners think PASM is an impossible monster. It is NOT, even though I was very hesitant to learn even the basics, even though many encouraged me to follow the SPIN book up with a PASM book. Please keep in mind that this is not a textbook. It is and introduction for hobbyists. How the reader uses it not up to the writer.
As to bad habits. Yes of course, but I am not going to be able to fix bad habits. Those interested enough will develop, read more, become good at it or whatever. Even maybe write a much better book. My job is to get the started. To suggest to them that they can learn this language.
Thanks
HSS
I can read a value generated in a PASM cog and use in in SPIN. Done
I can't seem to find how to take a value in SPIN and put it into a PASM Cog variable.
HSS
Typically, this is done with par, and offsets to par.
Put the variable in a DAT section, pass that address to the PASM COG with @variable in the COGNEW.
In the PASM COG:
rdlong variable, PAR
Of course, you also need a defined place in the PASM COG to put it. There are various naming schemes for this. One really easy one is to define the address at the higher level as a label in the DAT section thus:
DAT
MyVar long 0
And in the PASM COG
_MyVar res 1
Or some similar thing.
Multiple values are best done with a loop, where they are fetched one by one, adding to par each time, and adding to the base address in the COG each time, variables kept in sequence. (*which I get caught not doing, unless I really need the code space)
This means the PASM-Cog has to poll for it using RDLONG. Automatic pushing does not work.
The only way of pushing I can think of is using IO-PINS to "push" a byte towards PASM-code.
The special purpose registers INB and OUTB could be used.
keep the questions coming
best regards
Stefan
Thanks guys
@Holly Minkowski. This book was requested by you among others. How come no comments so far?
HSS
One thing that occurred to me was as I puzzled this was that I could write to a long in high memory in the hub and then read the same address in a PASM cog
Does that make sense? Can one do things like that?
HSS