Stupidest things ever (or am I stupid?)
OK...I've been banging my head against the wall ...trying to figure this one out:
Program 1:
Program 2:
Should be the same program right? In both test88 is ignored.
On my test board here...program 1 sets pin 13 high...and nothing on pin 24
Program 2 does exactly what is should do...turn pin 24 high and low...nothing anywhere else...
WTF!!!! I've tried this on two different boards, same results.
If you change one thing...like add a waitcnt(clkfreq + cnt) before the cognew is called...then it works fine again.
There's no way it could be the µController...right? What am I doing wrong...or am I just missing the simplest mistake ever!? Or is it something with my hardware...but look at the program...there should be zero difference, right!?
...I'm frustrated to say the least...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
Program 1:
CON
OBJ
VAR
PUB Main
cognew(@test1, 0)
DAT
ORG 0
test88
MOV DIRA, Pin
XOR OUTA, Pin
test1
MOV DIRA, Pin
:loop XOR OUTA, Pin
JMP #:loop
Pin LONG |< 24
FIT 496
Program 2:
CON
OBJ
VAR
PUB Main
cognew(@test1, 0)
DAT
ORG 0
test88
'MOV DIRA, Pin
'XOR OUTA, Pin
test1
MOV DIRA, Pin
:loop XOR OUTA, Pin
JMP #:loop
Pin LONG |< 24
FIT 496
Should be the same program right? In both test88 is ignored.
On my test board here...program 1 sets pin 13 high...and nothing on pin 24
Program 2 does exactly what is should do...turn pin 24 high and low...nothing anywhere else...
WTF!!!! I've tried this on two different boards, same results.
If you change one thing...like add a waitcnt(clkfreq + cnt) before the cognew is called...then it works fine again.
There's no way it could be the µController...right? What am I doing wrong...or am I just missing the simplest mistake ever!? Or is it something with my hardware...but look at the program...there should be zero difference, right!?
...I'm frustrated to say the least...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!

Comments
I guess we're both stupid!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm
Post Edited (Rayman) : 6/17/2009 1:04:37 AM GMT
Does that make sense?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
Thank you for killing my headache!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
...yeah, my first object with multiple entries into the PASM code....usually I just have one..and the PASM figures it out..but I guess I got a little too fancy for my level of PASM expertise....you live you learn...then you realize just how little you actually know.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm
Won't work. They are not relative in the sense you think they are. It's the '$' operator and it means the current compiler cog address.
In the context of the program above it'd still be wrong.
This will give you an infinite loop, but the actual code compiled is hardcoded to those locations, so to load it elsewhere in a cog will cause mayhem.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Missed it by ->" "<- that much!
I think there's a way to do it by changing the DAT code before launching the code... Just calculate the #longs between your desired start point and the actual ORG 0 and then subtract that difference from all the JMP lines in your DAT section...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm
Yep, that'd do it but you also need to shuffle _all_ your source and dest addresses. Basically look at the instruction and if it does not have the 'i' bit set you need to re-calculate the source and destination addresses, otherwise you only need to recalculate the dest address.
Is it really worth that much trouble?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Missed it by ->" "<- that much!
Long answer - the COG will load the 496 longs starting from the address provided in COGINIT/COGNEW and start executing the first instruction. The PropTool (or equivalent) has to change all labels to absolute register numbers (i.e. JMP #:loop becomes JMP #1). The ORG 0 tells the PropTool to restart the register numbering at 0. So in Program 1 it gets to JMP #:loop and changes it to JMP #3, while for Program 2 it gets changed to JMP #1. However, in both cases :loop XOR OUTA, Pin gets loaded into register 1 by COGNEW( @test1, 0 ). Result - Program 1 effectively does a JMP #Pin and goes off to never-never-land.
Now, there's no reason you can't have multiple PASM programs in a single DAT section, just precede each by ORG 0. However, trying to have overlapping code (i.e. COG 1 contains code A + code B, and COG 2 contains code B + code C with the DAT being code A code B code C) just seems like a lot of effort and complexity to save a minor amount of HUB RAM. Much easier to duplicate the overlapping code in the DAT section, or create the code so both COGs get loaded with all the routines and then JMP to the starting address. For example:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Composite NTSC sprite driver: http://forums.parallax.com/showthread.php?p=800114
NTSC color bars (template): http://forums.parallax.com/showthread.php?p=803904
I think I will go with the PASM-controlled routing, like you suggested.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
This is a custom driver I wrote for a MCP3008. It just gets the voltage of each channel and feeds it back to the volts long(s).
It seems to work on only channel 0.
The headache is I am getting the whole pin 13 is going high and low randomly depending on how I add or remove code.
I'm still in the pangs of learning PASM, so please any criticism would be nice on how to make the code better.
CON _CLKMODE = XTAL1' + PLL4X _XINFREQ = 8_000_000 ' 8MHz Crystal Vclk_p = 24 Vn_p = 25 Vo_p = 26 Vcs_p = 27 OBJ DEBUG : "FullDuplexSerial" VAR LONG volts[noparse][[/noparse]8] PUB Main DEBUG.start(31, 30, 0, 57600) waitcnt(clkfreq + cnt) DEBUG.tx($0D) GET(Vo_p, Vn_p, Vclk_p, Vcs_p, 10, 5, %11000) repeat PUB GET (DTPin, INPin, ClkPin, RSPin, delay_us, bitcount, value) | ret_value, done, i DPin := |< DTPin CPin := |< ClkPin CSPin := |< RSPin NPin := |< INPin pinmask := DPin | CPin | CSPin delay := ((clkfreq / 1_000_000) * delay_us) #> 9 Bits := bitcount val := value val_addr := @volts REPEAT i FROM 0 TO 7 volts[noparse][[/noparse] i ]~ done~ cognew(@entry, @done) REPEAT UNTIL (done) REPEAT i FROM 0 TO 7 DEBUG.bin(volts[noparse][[/noparse] i ], 10) DEBUG.tx($0D) DAT ORG 0 entry MOV OUTA, #0 ' set all low MOV OUTA, CSPin ' set CS pin high (inactive) MOV DIRA, pinmask ' set pins we use to output MOV Bits3, Bits ' backup MOV val2, val ' backup MOV idx, #7 ' set index to 7 (to cycle through voltages) bigloop MOV val, val2 ' get backup ADD val, idx ' add index to current value MOV Bits, Bits3 ' get backup SUB Bits2, Bits ' determine number of shifts (difference of output bits and a long) SHL val, Bits2 ' shift value so first bit to output is at bit 31 ANDN OUTA, CSPin ' set CS pin low (active) shift_out SHL val, #1 WC ' shift output value and place bit 31 in C MUXC OUTA, Dpin ' set data pin to what value bit 31 was OR OUTA, CPin ' start clock cycle MOV wait, cnt ADD wait, delay WAITCNT wait, delay ' delay clock cycle (before low) ANDN OUTA, CPin ' end clock cycle MOV wait, cnt ADD wait, delay WAITCNT wait, delay ' delay clock cycle (before next bit) DJNZ Bits, #shift_out ' cycle through the rest of the value MOV val_out, #0 ' set to reset value (0) shift_in MOV Bit, INA ' get INA mask TEST Bit, NPin WZ ' if data input pin is high SHL val_out, #1 IF_NZ ADD val_out, #1 ' add input pin value to output OR OUTA, CPin ' start clock cycle MOV wait, cnt ADD wait, delay WAITCNT wait, delay ' delay clock cycle (before low) ANDN OUTA, CPin ' end clock cycle MOV wait, cnt ADD wait, delay WAITCNT wait, delay ' delay clock cycle (before next bit) DJNZ bits_in, #shift_in ' continue to end of input value OR OUTA, CSPin ' set CS pin high (inactive) WRLONG val_out, val_addr ' write value to value address MOV bits_in, #13 ' set to reset value (13) MOV Bits2, #32 ' set to reset value (32) ADD val_addr, #1 ' move address one long for next cylce DJNZ idx, #bigloop ' do it again! WRLONG Bits2, PAR ' write a non-zero value to done value pinmask LONG 0 Dpin LONG 0 CPin LONG 0 CSPin LONG 0 NPin LONG 0 idx LONG 0 delay LONG 0 wait LONG 0 Bit LONG 0 Bits LONG 0 Bits3 LONG 0 Bits2 LONG 32 bits_in LONG 13 val LONG 0 val2 LONG 0 val_out LONG 0 val_addr LONG 0 FIT 496▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
Post Edited (Bobb Fwed) : 6/17/2009 10:51:29 PM GMT
Shouldn't your variables use RESs instead of LONGs? Like this example line
val RES 1
At least that's what I understand.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Long allows you to let SPIN set DAT values, its very handy.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
You better do something after that line, e.g. fetch the next command, wait forever or terminate the cog. But what you don't want is execute data [noparse]:)[/noparse] I cannot guarantee that this is the source of your problem but it certainly contributes.