Shop OBEX P1 Docs P2 Docs Learn Events
PC+W error — Parallax Forums

PC+W error

BebopALotBebopALot Posts: 79
edited 2006-03-04 23:54 in General Discussion
Hi folks, I have been learning a lot of assembly lately and trying to write some programs a little differently. Lately I have been playing around with state machines. Can some one please help me with my error?

Everything goes well until I have this command,

mov w, stateselect
JMP PC+W
JMP Routine1
JMP Routine2

I get bad call error or something like that. Stateselect is always either binary 1 (0000_0001) or 2 (0000_0010).
What am I doing wrong?

Comments

  • pjvpjv Posts: 1,903
    edited 2006-03-03 16:41
    Hi Bebop;

    Not sure about the error message, but Stateselect should be 0 to offset to the line after the JMP PC+W, or 1 to offset two lines farther.

    Often there is even an easier way to do the state jumps with the intermediary table, and that is to use the address of the routine itself. Some restrictions, such as you must remain on the same page.

    
    
     
     
    Init   <code>
           <code>
           mov StateAddr,#Addr1             ;at some point the first stae needs to be initialized
           <code>
     
     
    Main   <code>        <code>
           mov PC,StateAddr                 ;state jumper; load the PC with the (lower byte) address of the chosen routine
     
    Addr1  <code>
           <code>
           <state determination code>       ;criteria to select the next state..Addr2
           mov StateAddr, #Addr2            ;next time the state jumper is encountered jump to Addr2
           jmp Mainline
     Addr2  <code>
           <code>
           <state determination code>       ;criteria to select the next state..Addr1
           mov StateAddr, #Addr1            ;next time the state jumper is encountered jump to Addr1
           jmp Mainline
     
    More   <code>
           <code>
     
    
    
    
    
    



    Cheers,

    Peter





    Post Edited (pjv) : 3/3/2006 4:57:43 PM GMT
  • BebopALotBebopALot Posts: 79
    edited 2006-03-03 20:14
    That's an excellent way to do it. I integrated it and it makes sense to me.

    Unfortunately, when SXSim tries to

    mov PC, Stateselect

    its giving me a "bad jump or return address"

    I'll investigate further.
  • BebopALotBebopALot Posts: 79
    edited 2006-03-04 02:35
    Can't seem to shake the error. Could it be trying to cross another page?
  • pjvpjv Posts: 1,903
    edited 2006-03-04 02:47
    Can't tell if you don't post your complete code.

    Cheers,

    Peter (pjv)
  • BebopALotBebopALot Posts: 79
    edited 2006-03-04 15:38
    Sorry bout that PJV. Below is the code. Now what I did was remove "$100" from my Main address and it started working fine and stopped getting the "bad jump or return address error".

    I am doing something a little different here than last time. First I am bursting two pins simulataneously for 75us at 40Khz while keeping a 40KHz carrier wave active through the burst and then silent periods. Using your tips for a State Machine, this was easy and reliable in its design. The tricky part was that every 12.5 us all pins are OFF regardless of which state (burst or wait) so I NOT a register every 12.5us to toggle between those two states and use an OldState variable to prevent state loss. Looks like it works fine. I have several loop variables set to 1 just because in the future I may use them to increase the interupt count.


    Thanks for helping me learn Peter,

    BBAL

    ;5.120 MHz version

    Device SX28L, Turbo, Stackx, OSCHS3
    IRC_CAL IRC_SLOW
    FREQ 5_120_000


    RESET ResetEntry

    ORG $000

    Interrupt ; Interrupt Routine - always starts at 0
    Mov w, State
    Mov Ra, w
    Setb Flag.0
    Mov w, #-64
    Retiw


    Org $08

    State DS 1
    Flag DS 1
    Loop1 DS 1
    Loop2 DS 1
    Loop3 DS 1
    StateSelect DS 1
    OnOffSelect DS 1
    OldState DS 1

    ResetEntry

    ; de-glitch initial state

    Mov w, #%0000
    Mov Ra, w ; set register A output to digital LOW
    Mov w, #%0000_0000
    Mov Rb, w ; set register B output to digital LOW
    Mov w, #%0000_0000
    Mov Rc, w ; set register C output to digital LOW

    ; configure ports

    Mov M, #$0f ; access TRIS mode
    Mov W, #%0000 ; bits 0-3 are outputs
    Mov !Ra, W ; make Ra0-Ra3 outputs
    Mov W, #%0000_0000 ; all bits output
    Mov !Rb, W ; set Port B pins to output
    Mov W, #%0000_0000 ; all bits output
    Mov !Rc, w ; set Port C pins to output

    ; configure interrupt

    Mov w, #%1011_1111
    Mov RTCC, w ; set RTCC to 191
    Mov w, #%1001_1111
    Mov !option, w ; set RTCC without prescaler

    ; Initialize
    Mov w, #%0000_0000
    Mov State, w ; set State pins to 0's
    Mov w, #Burst ; set stateselect to burst
    Mov StateSelect, w
    Mov w, #%0000_0000 ; set initially to off - but first output will flip and write
    Mov OnOffSelect, w
    Mov w, #%0000_0001 ; set to trigger state change
    Mov Loop1, w
    Mov w, #%0000_0001
    Mov Loop2, w
    Mov w, #%0000_0001
    Mov Loop3, w
    Clrb Flag.0
    ; **************************** HERE I REMOVED THE $100 which stopped the error
    Main
    Sb Flag.0 ; test for interupt occured
    JMP Main
    ; come here every 12.5us
    Clrb Flag.0 ; clear interupt flag
    NOT OnOffSelect ; toggle "odd even"
    Sb OnOffSelect.0 ; every other 12.5us all pins = 0
    JMP LoState ;

    Mov w, Oldstate ; go here if odd
    Mov State, w
    decsz Loop1 ; countdown
    JMP Main
    decsz Loop2
    JMP Main
    decsz Loop3
    JMP Main

    Mov PC, StateSelect ; load the state number

    Burst
    Mov w, #%1011 ; State 1 ON config (Tx2.N/A.CW.TX1) - come here every 25 us
    Mov State, w
    ; load State 1 Loop Values
    Mov w, #%0000_0100 ; 1 more than needed for dec command to time correctly
    Mov Loop1, w ; inner loop value
    Mov w, #%0000_0001 ; 1 (0 really)
    Mov Loop2, w ; middle loop value
    Mov w, #%0000_0001 ; 1 (0 really)
    Mov Loop3, w ; outer loop value
    3 interupts, done
    Mov StateSelect, #Wait ; pre-load next state
    JMP Exit

    Wait Mov w, #%0010 ; State 2 ON config (Tx2.N/A.CW.TX1)
    Mov State, w
    ; load State 2 Loop Values
    Mov w, #%1010_0001 ; 161
    Mov Loop1, w ; inner loop value
    Mov w, #%0000_0001
    Mov Loop2, w ; middle loop value
    Mov w, #%0000_0001
    Mov Loop3, w ; outer loop value
    Mov StateSelect, #Burst ; pre-load next state
    JMP Exit

    LoState Mov w, State ; save old state value to reload on even toggle
    Mov OldState, w
    Mov w, #%0000 ; all off
    Mov State, w


    Exit
    JMP Main
  • pjvpjv Posts: 1,903
    edited 2006-03-04 17:04
    Hi Bebop;

    So I guess all is working.

    A couple of point of advice/suggestions.

    1. I just learned this, and wish to pass it on; when you want to post a reply which has code in it, then use the full reply button at the end of the thread labeled "Post Reply" rather than the "Quick Reply" The reason is that the full featured method has the ability through the selection button labeled "#" to post your code with preserving its format, and that's a big help. It makes it so much more readable. Until someone had pointed this out to me I would just use the "Quick Reply" method, post my code which would then have its formatting (mostly tabs) stripped out, and I would post-edit it with spaces to make it look more reasonable. That was a real pain. Now I can post code pretty much the way I originally formatted it.

    2. In your program when you invoke the state jumper, you need to be sure your jumps are always to the page that your jumper is located in. If jou need to go to a different page, then you need to use an intermediate jump, one to the current page which then executes another jump to another page, but of course not before you have performed an appropriate "page" instruction. The assembler's @ operator before the address name is great for this.

    3. The state jumper uses·the 8 bit variable "StateAddr", so that can only address the lower 256 bytes of·the current·page. So, if you need to jump to the high 256 bytes of·the current·page, you are forced to use the intermediate jump method.

    4. Do be sure, that after your state-jump to another page, that when you wish to return to the Mainline, you don't forget to set the page of the Mainline using the Page instruction or, better yet, the @ operator in front of the mainline address as per my example.


     
     
    Page0  org  $000                        ;this is page 0
    ISR    <ISR code>                       ;
           mov w,#IntValue                  ;
           retiw                            ;exit ISR 
     
    Init   <code>
           <code>
           mov StateAddr,#Addr1             ;at some point the first stae needs to be initialized
           <code>
     
     
    Main   <code>        <code>
           mov PC,StateAddr                 ;state jumper; load the PC with the (lower byte) address of the chosen routine
     
    Addr1  [url=mailto:jmp@Addr3]jmp@Addr3[/url]                        ;intermediate jump for Addr3 which is on another page
      Addr2  [url=mailto:jmp@Addr4]jmp@Addr4[/url]                        ;intermediate jump for Addr4 which is on another page
     
    
    
     
    Page1  org $200                         ;this is located on page 1
    Addr3  <code>
           <code>
           <state determination code>       ;criteria to select the next state..Addr2
           mov StateAddr, #Addr2            ;next time the state jumper is encountered jump to Addr2
           jmp @Mainline                    ;set page, then jump back to mainline
      Page2  org $400                         ;this is located on page 2
    Addr4  <code>
           <code>
           <state determination code>       ;criteria to select the next state..Addr1
           mov StateAddr, #Addr1            ;next time the state jumper is encountered jump to Addr1
           jmp @Mainline                    ;set page, then jump back to mainline
     
    More   <code>
           <code>
     
    
    
    
    
    



    There are yet other, more involved tricks, but we'll just leave this for now.... hope this helps some more.

    Cheers,

    Peter (pjv)
  • BebopALotBebopALot Posts: 79
    edited 2006-03-04 23:14
    Thanks Peter, I see that I was probably that the error I was getting was referring to this.

    What does "Mainline" refer to ? The beginning of the main progam labeled Main?
  • pjvpjv Posts: 1,903
    edited 2006-03-04 23:54
    Hi Bebop;

    Yes, sorry if I was not clear. It is all that other code, whatever it might be, that you need to run as well as the state code.

    Cheers,

    Peter (pjv)
Sign In or Register to comment.