Shop OBEX P1 Docs P2 Docs Learn Events
W = w*2 ? — Parallax Forums

W = w*2 ?

NetHogNetHog Posts: 104
edited 2007-11-27 04:34 in General Discussion
Ok, in my code, I was hoping for a 1 byte instruction that would be equivalent to W = W*2
Thoughts that came to mind are "RL W" and "ADD W,W", however both of these are not possible unless W is mapped to fr=1.

I can work around this of course by using another temporary memory location, however I feel like I'm missing something?

BTW, interestingly, "RL W" gets encoded as "RL IND" (0x360 or %001101100000)·so I didn't catch this until tracing through the simulator.
·

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-11-25 02:28
    If you don't need direct access to the contents of RTCC, you can reassign its address mapping to the W register. This is done by clearing bit 7 of the OPTION register. In this case, W can also be referred to by its register name, WREG, and statements like RL WREG are possible.

    -Phil
  • NetHogNetHog Posts: 104
    edited 2007-11-25 04:20
    Hence my comment "unless W is mapped to fr=1" [noparse];)[/noparse] In my project, I'm using RTCC register, and I lose as much switching back and forth for this register than I would gain, so this isn't an available optimization.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-11-25 05:03
    Ah so; 'missed that detail. Absent he WREG option, any optimization will depend on the context. As a trivial example, if W had just been loaded from another register and you wanted to rotate it, you could have done MOV W,<<REG (which doesn't alter REG) instead. But since there's no way, using one instruction, to double a number already in W, a more comprehensive answer will depend on seeing the actual code you're working with.

    -Phil
  • NetHogNetHog Posts: 104
    edited 2007-11-25 07:15
    Simply put, the question is on how to take the lower 2 bits of FOO, and converting that to drive one of RA3..RA0 low. I.e. to drive a cathode of a group of 4 seven-seg displays. I've solved this another way, so the question at this point is purely academic.
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2007-11-25 09:44
    Please note: When W is mapped into fr=1, this does not mean that you can't use the RTCC for controlling interrupts any more. RTCC roll-overs still work fine, and the RTCC is incremented on every clock cycle with OPTION.6 and OPTION.5 cleared. RETIW also updates the RTCC as it should. You simply can't directly read or write to the RTCC which is not necessary anyway when used for interrupts.

    When using any rotate instruction, like rl wreg, or mov wreg, <<reg, keep in mind that this only works correctly when the carry flag is clear, so for security reasons you should execute a clc instruction before which requires another clock cycle. So add w, wreg will be faster.

    The fact that SASM generates "RL IND" for "RL W" is a bug in my opinion because this is not the expected result. It should generate a warning or error in this case.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • NetHogNetHog Posts: 104
    edited 2007-11-25 16:41
    Hi Guenther, I love the material you've produced related to the SX chip.

    There's a couple of caveat's on this project which has me reading RTCC...
    In the general design, I have a "start" interrupt occuring (RB.6) and a "stop" interrupt occuring (RB.7). Between these two events I want an accurate time that must have high precision and resolution.

    Ok, what does this mean? I have interrupts coming in from RTCC, RB.6 and RB.7.
    With the "RTCC interrupt", I need to increment on roll-over RTCC_1, and when that roll's over, RTCC_2. If RTCC was the only interrupt, this is very trivial to do.
    Also using the time-base interrupt, I refresh 4 7-seg displays based on DISP_0 .. DISP_3 (and every second, alternate with a second set of display registers DISP_4 .. DISP_7).

    Now, when you introduce RB.6 and RB.7 to the mix, things get more interesting on the SX28 because it has no indicator that the interrupt is time based vs RB.x (the two co-incide, and obviously you can't asusme RB.x means it wasn't time-based).

    I solve this with a little trick. When RTCC is < 128, I assume that the clock rolled over, and use RETIW to add 128 to RTCC. This means I get the interrupt twice as fast of course, but means I can accurately determine RTCC has rolled over even with other interrupts coming in. I have RTCC scaled enough so that the max interrupt time is < RTCC interrupt period. I happen to also use RTCC_1 and RTCC_2 in the ISR to feed my display refresh clocks.

    When I need to snapshot my time, I use RTCC (7 bits) combined with RTCC_1 and RTCC_2 to give myself a 23-bit time-base.

    Now one option in the code is to avoid ever using WREG, another option I'm entertaining is to modify OPTION.7 whenever I need to use RTCC register, and modify it back when I don't.
  • BeanBean Posts: 8,129
    edited 2007-11-26 12:18
    NetHog said...

    Now, when you introduce RB.6 and RB.7 to the mix, things get more interesting on the SX28 because it has no indicator that the interrupt is time based vs RB.x (the two co-incide, and obviously you can't asusme RB.x means it wasn't time-based).

    NetHog,
    · This has turned into an interesting thread. Cool.

    · The WKPND_B register indicates if the interrupt was caused by a Port B wake-up.

    · In SX/B use:

    INTERRUPT 
      temp = 0       ' To clear all pending port-b interrupts 
      WKPND_B = temp ' This actually swaps WKPND_B and temp 
      IF temp.6 = 1 THEN 
        ' Interrupt on RB.6 code 
      ENDIF 
      IF temp.7 = 1 THEN 
        ' Interrupt on RB.7 code 
      ENDIF 
    RETURNINT
    

    Bean


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.iElectronicDesigns.com

    ·
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-11-26 17:48
    NetHog,

    I like your technique for dealing with the SX's lack of an interrupt pending bit for the timer rollover. That annoying little quirk in the SX's architecture has bedeviled me in the past; and, although I've come up with a solution, yours is more elegant. In essence, you've created a timer interrupt pending flag (inverted) in RTCC.7. You do have to be careful with your timing, though, to make sure RTCC is either over 128 or significantly less than 128 when you check it. If it's 127, say, it'll be over 128 by the time you get to the RETIW 128, which will cause a rollover. Although the docs do not make it clear whether or not an artficial rollover, such as this, will cause an interrupt, I suspect that it will not.

    -Phil
  • BeanBean Posts: 8,129
    edited 2007-11-26 18:11
    Phil,
    · Just for the record, the SX48 does have an RTCC rollover bit. It is "RTCCOV" bit 7 of T1CNTB register.
    · It is only available on the SX48 though.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.iElectronicDesigns.com

    ·
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-11-26 19:12
    Bean,

    Yup, something for which we can all be thankful! smile.gif

    BTW, here's my ISR code for mixed interrupts on the SX28 family chips. As I said, it's less elegant than NetHog's solution, but it works:

    ISR     MOV     W,#2            ;If RTCC low enough, then must be timer interrupt...
            MOV     W,RTCC-W
            BANK    sysREGS
            JNC     RTCISR          ;Yup, must be timer interrupt.
            MOV     RTCCQ,W         ;Nope, save current value minus 2 for later check.
    ;
            MODE    M_WKPND         ;Access port B pending registers... (M IS NOT RESTORED!!!)
            MOV     !RB,#%00000000
    
            ...
    
    :CKRTC  MOV     W,#3            ;Will a timer rollover occur before the RETI?
            ADD     W,RTCC
            JC      :CKRTC          ;  Yes. Wait for it. (No carry when RTCC hits zero.)
            MOV     W,#2            ;Look at ISR entry value of RTCC.
            ADD     W,RTCCQ
            MOV     W,RTCC-W        ;Is the current value lower?
            JNC     RTCISR          ;  Yes: A rollover has occured.
            RETI                    ;  No: No rollover. Just get out.
    
    
    RTCISR
    
            ...
    
    :RTCEND MOV     W,#RTCON        ;Add constant to RTCC on way out for proper rate...
            RETIW
    
    
    


    This code, incidentally, used an RTCC prescalar rate of 1:4. Other prescale rates will entail different constants for detecting or anticipating an RTCC interrupt.

    -Phil
  • James NewtonJames Newton Posts: 329
    edited 2007-11-26 23:53
    NetHog said...
    Simply put, the question is on how to take the lower 2 bits of FOO, and converting that to drive one of RA3..RA0 low. I.e. to drive a cathode of a group of 4 seven-seg displays. I've solved this another way, so the question at this point is purely academic.
    http://www.sxlist.com/techref/ubicom/lib/math/bit/setbit_sx.htm
    may be of help.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • James NewtonJames Newton Posts: 329
    edited 2007-11-27 00:08
    Although it probably doesn't apply to the OP's design, there are some interesting issues with multiple interrupt sources on the SX chips.

    Check out:
    http://www.sxlist.com/techref/ubicom/sxints.htm
    and especially the comments of Alexey Vladimirov near the bottom of the page:
    Alexey Vladimirov said...

    Each SX instruction in turbo mode executed in a 4-stage pipeline, consisting of the following steps: fetch instruction, decode opcode, execute opcode, write result.

    In the example mov !rb, w instruction at the second step simultaneously with instruction decode also read WKPND_B register and at the fourth step clear WKPND_B register.

    If another external interrupt on different portB pin occurs exactly at this time (at the 2,3,4 steps of the mov !rb, w execution), SX will loose this interrupt (as the WKPND_B register cleared and, therefore, pending bit for this interrupt also cleared without interrupt processing).

    It mean, that it is not possible to use 2 or more asynchronous external interrupts on the SX without loosing some interrupts.

    This problem related to all current (as of Jan 2001) SX revisions.

    [noparse][[/noparse]To work around this, check the pins by reading the actual port value after the first interrupt.] If you will use polling instead of interrupts - all will works OK. You can also use one external interrupt and poll other pins. However, if you have two asynchronous signals and you need interrupt on both (bridge application, for example), the only possible workaround we found - add some external glue logic (triggers for each interrupt with separate reset from SX port, as in any typical interrupt controller, like 8259) or change from interrupts to polling.

    The page at:
    http://www.sxlist.com/techref/ubicom/rtcc.htm ·also points out some little known information, although it only applies to the use of RTCC with an external clock signal.
    anon said...
    The SX literature says that the dual stage synchronizer is _always_ activated on RTCC. If that is so, then the RTCC may actually be counting two LESS pulses than have actually been presented on the input pin.
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • NetHogNetHog Posts: 104
    edited 2007-11-27 01:31
    James: Thanks, I will modify my logic per this data.

    Phil: you are correct about using RTCC.7 as a pseudo interrupt pending flag, and that you have to be very careful with how long you spend in the interrupt routine due to these concerns. Things should be more than fine if the max ISR timing is less than 64 RTCC increments (enough time for ISR to run to completion twice). With some forethought in the logic, capturing RTCC at the start and end of the ISR, you can push max ISR time to be closer to 128 RTCC increments.



    Bean: Yup, about the SX48, sadly I have SX28's in my bucket [noparse]:)[/noparse] BTW, feel free to change the topic title to reflect the prominant subject matter of the thread since we've veered off from the original subject.
  • NetHogNetHog Posts: 104
    edited 2007-11-27 04:34
    Phil, nice catch on the "rolled over or may roll over before next ISR". Obviously this method needs the prescale rate to be small enough, which is why I went the direction I went. Pro's and Con's with both approaches.
    Phil Pilgrim (PhiPi) said...
    Bean,

    Yup, something for which we can all be thankful! smile.gif

    BTW, here's my ISR code for mixed interrupts on the SX28 family chips. As I said, it's less elegant than NetHog's solution, but it works:

    ISR     MOV     W,#2            ;If RTCC low enough, then must be timer interrupt...
            MOV     W,RTCC-W
            BANK    sysREGS
            JNC     RTCISR          ;Yup, must be timer interrupt.
            MOV     RTCCQ,W         ;Nope, save current value minus 2 for later check.
    ;
            MODE    M_WKPND         ;Access port B pending registers... (M IS NOT RESTORED!!!)
            MOV     !RB,#%00000000
    
            ...
    
    :CKRTC  MOV     W,#3            ;Will a timer rollover occur before the RETI?
            ADD     W,RTCC
            JC      :CKRTC          ;  Yes. Wait for it. (No carry when RTCC hits zero.)
            MOV     W,#2            ;Look at ISR entry value of RTCC.
            ADD     W,RTCCQ
            MOV     W,RTCC-W        ;Is the current value lower?
            JNC     RTCISR          ;  Yes: A rollover has occured.
            RETI                    ;  No: No rollover. Just get out.
    
    
    RTCISR
    
            ...
    
    :RTCEND MOV     W,#RTCON        ;Add constant to RTCC on way out for proper rate...
            RETIW
    
    
    


    This code, incidentally, used an RTCC prescalar rate of 1:4. Other prescale rates will entail different constants for detecting or anticipating an RTCC interrupt.

    -Phil
Sign In or Register to comment.