Shop OBEX P1 Docs P2 Docs Learn Events
Stupidest things ever (or am I stupid?) — Parallax Forums

Stupidest things ever (or am I stupid?)

Bobb FwedBobb Fwed Posts: 1,119
edited 2009-06-18 00:07 in Propeller 1
OK...I've been banging my head against the wall ...trying to figure this one out:
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

  • RaymanRayman Posts: 14,838
    edited 2009-06-16 23:21
    I don't see the problem... Maybe a compiler bug?

    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
  • lonesocklonesock Posts: 917
    edited 2009-06-16 23:22
    Bobb Fwed said...
    ...
      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
    

    Note that in program 1 you are loading a cog starting at test1, which is great, except that your ORG 0 line is before 2 other commands, so the compiler is basically thinking that test1 will be at cog address 2 instead of 0. Likewise Pin is thought to be at address 6 instead of 4.

    Does that make sense?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • kuronekokuroneko Posts: 3,623
    edited 2009-06-16 23:25
    What makes you think it's the same? The first program is ORG'ed for 0 but you use it 2 longs off. Which means Pin resolves to some more or less random value and the JMP goes off into nowhere (assembled for 3, but the way you use it it jumps to Pin).
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-06-16 23:25
    ah...I told you it would be simple...and I'd look like a fool :-P

    Thank you for killing my headache!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    April, 2008: when I discovered the answers to all my micro-computational-botherations!
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-06-16 23:30
    So the correct answer would be "yes you are stupid".

    ...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!
  • RaymanRayman Posts: 14,838
    edited 2009-06-17 12:28
    I think there may be a way to do what you want using relative jumps... I vaguely recall someone talking Chip into adding a way have the assembler calculate relative jumps. I think it was with some symbol like "&" or something... You'd probably have to search the forum to find it...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm
  • BradCBradC Posts: 2,601
    edited 2009-06-17 12:32
    Rayman said...
    I think there may be a way to do what you want using relative jumps... I vaguely recall someone talking Chip into adding a way have the assembler calculate relative jumps. I think it was with some symbol like "&" or something... You'd probably have to search the forum to find it...

    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.

    
      xor  outa,#1
      jmp #$-1
    
    
    



    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!
  • RaymanRayman Posts: 14,838
    edited 2009-06-17 12:44
    Ok, I think I see it. But, I'm not giving up!

    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
  • BradCBradC Posts: 2,601
    edited 2009-06-17 12:49
    Rayman said...
    Ok, I think I see it. But, I'm not giving up!

    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...

    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!
  • ericballericball Posts: 774
    edited 2009-06-17 13:57
    Short answer - ORG 0 should always precede the label you use in COGINIT/COGNEW.

    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:

    DAT
      ORG 0
    start_  JMP #start_A
    start_A
    <code A>
    start_B
    <code B>
    <code C>
    _startA JMP #start_A
    _startB JMP #start_B
    PUB
      start_ := _startA
      COGINIT( start_, 0 )
      start_ := _startB
      COGINIT( start_, 0 )
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Composite NTSC sprite driver: http://forums.parallax.com/showthread.php?p=800114
    NTSC color bars (template): http://forums.parallax.com/showthread.php?p=803904
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-06-17 15:30
    ericball said...
    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.
    But that is a bit of a pain to duplicate it, since you can't use the same symbols or labels.
    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!
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-06-17 22:36
    OK...so now I am getting the same problem with this code. What I am doing wrong with it?
    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
  • HarleyHarley Posts: 997
    edited 2009-06-17 22:46
    Bobb Fwed,

    Shouldn't your variables use RESs instead of LONGs? Like this example line

    val RES 1

    At least that's what I understand. yeah.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Harley Shanko
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-06-17 22:53
    they can go either way..it seems more experienced people use res...but I use long.
    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!
  • kuronekokuroneko Posts: 3,623
    edited 2009-06-18 00:07
    WRLONG  Bits2, PAR              ' write a non-zero value to done value
    


    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.
Sign In or Register to comment.