Shop OBEX P1 Docs P2 Docs Learn Events
Help please required in reducing the byte count in ASM ISR code snippit — Parallax Forums

Help please required in reducing the byte count in ASM ISR code snippit

Tony LeylandTony Leyland Posts: 71
edited 2006-05-19 11:38 in General Discussion
Hi,

Can anyone please help in reducing the byte count in this code snippit. It is from a 2 channel UART VP
(this is not true simultaneous 2 channels, but more switching between the 2 channels).

If it helps, the W reg can be used. The numbers in brackets are the bytes used for each instruction.

It strikes me after breaking down the compound instruction 'movb' into it's basic instructions, that there are
a lot of SKIP type instructions and that is where some space could be saved.

I'm looking to make it a bit more elegant and reduce the time spent in the ISR.

Thanks a lot
Tony



    sb     UART_tx_ch1_enable              ; (1,2)  Is channel 1 enabled ?
    jmp    UART_tx_ch1_skip                ; (3)    No

    movb   UART_tx_ch1, /UART_tx_low.6     ; (4)    Output next bit to ch1.

UART_tx_1_skip:

    sb     UART_tx_ch2_enable              ; (1,2)  Is channel 2 enabled ?
    jmp    UART_tx_ch2_skip                ; (3)    No

    movb   UART_tx_ch2, /UART_tx_low.6     ; (4)    Output next bit to ch2.

UART_tx_2_skip:


Comments

  • BeanBean Posts: 8,129
    edited 2006-05-17 17:04
    Tony, without knowing the bit positions of the other variables, this is the best "I" could do...
    ; Takes 8 cycles if UART_tx_low.6 is high (no matter if either or both channels are enabled)
    ; Takes 9 cycles if UART_tx_low.6 is low (no matter if either or both channels are enabled)
        jb UART_tx_low.6, one ;(2/4)
        sb UART_tx_ch1_enable ; (1/2)
        SETB UART_tx_ch1 ; (1)
        sb UART_tx_ch2_enable ; (1/2)
        SETB UART_tx_ch2 ; (1)
        JMP Done ; (3)
    one:
        sb UART_tx_ch1_enable ; (1/2)
        CLRB UART_tx_ch1 ; (1)
        sb UART_tx_ch2_enable ; (1/2)
        CLRB UART_tx_ch2 ; (1)
    done:
        
    ; Takes 8 cycles if neither channel is enabled
    ; Takes 10 cycles if either channel is enabled
    ; Takes 12 cycles if both channels are enabled
        sb     UART_tx_ch1_enable              ; (1,2)  Is channel 1 enabled ?
        jmp    UART_tx_ch1_skip                ; (3)    No
        movb   UART_tx_ch1, /UART_tx_low.6     ; (4)    Output next bit to ch1.
    UART_tx_1_skip:
        sb     UART_tx_ch2_enable              ; (1,2)  Is channel 2 enabled ?
        jmp    UART_tx_ch2_skip                ; (3)    No
        movb   UART_tx_ch2, /UART_tx_low.6     ; (4)    Output next bit to ch2.
    UART_tx_2_skip:
    
    

    Bean.



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap 4-digit LED display with driver IC·www.hc4led.com


    COMING SOON "SD DATA LOGGER" www.sddatalogger.com

    "I reject your reality, and substitute my own." Mythbusters
    ·
  • pjvpjv Posts: 1,903
    edited 2006-05-17 21:57
    Hi Tony;

    By the nature of your question, I am assuming that the VP UART routines themselves are not residing in the ISR. For if they were, it is much more likely that significant code/cycles reduction could be had in that section of code, rather than the port bit-banging part.

    Assuming that my assumption is correct, then this could be accomplished by just setting some flags in the ISR that will be read and used by the mainline UART routines.

    This could be accomplished as simply as:

    DataAvailFlag      equ     Flags.0            ;advises mainline UART routines data is available if they are looking for some
    UART1Data          equ     Flags.1            ;state of UART1 received bit UART2Data          equ     Flags.2            ;state of UART2 received bit
    
    
     
    ISR           ....                            ;other ISR stuff
                  ....                            ;other ISR stuff
                  mov  w,#%0000_0111              ;prep to set three flags
                  or   Flags,w                    ;set them
                  sb   UART1PortBit               ;test level of UART1
                  clrb UART1Data                  ;data level was low               sb   UART2PortBit               ;test level of UART2
                  clrb UART2Data                  ;data level was low
                  ....                            ;               ....                            ;other ISR stuff
                  mov  w,InterruptConstant        ;reload interrupt time
                  retiw                           exit
     
    
    
    
    
     
    ;This approach yields a constant 6 byte/cycle result, regardless of data or which UART(s) are active
    ;In the MainLine, clear the DataAvailFlag
    

    If, on the other hand my assumption is incorrect, and the UARTs are located in the ISR, then a simple state machine will be your simplest and best approach.

    I could help you with that if you posted the UART routines and a little more of what you're trying to accomplish.

    Cheers,

    Peter (pjv)
  • Tony LeylandTony Leyland Posts: 71
    edited 2006-05-18 16:07
    Thanks Bean, that looks like it should do the trick.


    Hi Peter,

    The ISR does in fact hold all the code for the UART, thanks for your advice and offer of additional help. If I need to optimise the code
    further I'll post the code (it does also have 3 general purpose 16 bit timers in the ISR !)

    Cheers
    Tony
  • pjvpjv Posts: 1,903
    edited 2006-05-18 18:19
    Hi Tony;

    I don't know what your goals are of course, but my approach would be to place the minimum amount of code in the ISR. Generally it is "better" to do only the real-time critical portion of a routine in the ISR, and then flag the mailine outside or, better yet, have state jumpers that complete the activity outside of the ISR.

    That said, if you have lots of cycles available in the ISR, then why not do it there. I gathered from your original post that you needed to "tighten it up", and that probably implies a different approach from what you have.

    Let me know if I may clarify this more for you.

    Cheers,

    Peter (pjv)
  • PJMontyPJMonty Posts: 983
    edited 2006-05-19 04:17
    Tony,

    I'm a bit confused. The code you showed was nice, clean, simple, easy to read code. It also used a trivial amount of cycles. Any other solution is likely funkier, trickier, and harder to read. If the code works, and fits within the amont of time it needs to take, why change it? This seems like uneccessary code optimization bordering on code obfuscation. I would leave it and walk away, knowing that it works today and will be understandable six months from now.
      Thanks, PeterM
  • Tony LeylandTony Leyland Posts: 71
    edited 2006-05-19 11:02
    Hi PeterM,

    I know what you mean, it does sound like I'm being a bit too 'picky' with my coding and trying to save unnecessary bytes.

    The program that I have developed runs on an SX48 as the SX/B code is too large for the smaller devices. I'm now faced with
    the problem of running out of program space on the SX48 (not enough debug space of approx 136 bytes at the end of ROM).

    I've been going through the whole program (both my SX/B and my ASM code) to reduce byte count. There is hardly any data
    stored in the ROM, it is all much needed code routines. I've already shaved over 300 bytes from my current optimisation procedures and
    so I'm looking deeper in to my ASM code to futher reduce the byte count.

    The project that I'm working on for my company involves the following:-

    1) A very accurate GPS unit is connected to my SX board using Bluetooth.
    2) The GPS time/speed string that arrives via BlueTooth is sent via a serial connection to a video overlay device that puts a display
    on live video, which is then recorded on a small Hardisk PVR device.
    3) I use a blue Matrix Orbital 20x4 LCD to display menu screens, where the operator chooses various options using 4 keys and displays current operation status.
    4) External I2C 256 byte EEPROM for storing user settings (like MAC address of detected BlueTooth GPS device).

    As you can see, I'm pushing it somewhat in cramming all of that in a single SX device. The SX/B source is over 30 pages long and the ASM files over 20 pages long.

    I will probably need to split it up into modules based around 2 or more SX devices.

    Hope that explains a few things !

    Cheers
    Tony
  • PJMontyPJMonty Posts: 983
    edited 2006-05-19 11:28
    Tony,

    Yeah, that makes a lot more sense. There are really only two times you want to worry about optimizing code to the smallest it can be:

    1 - When the exisiting code is too slow

    2 - When you're out of space and need more stuff to fit.

    You're clearly in the latter camp, and for good reason. I was just concerned that you were falling into the trap of trying to write the coolest or fastest code when you didn't need to, but's it's obvious now you were already on top of it.

    Sounds like a pretty bada$$ project.
      Thanks, PeterM
  • Tony LeylandTony Leyland Posts: 71
    edited 2006-05-19 11:38
    Thanks Peter, yes it is a bit of a monster project but the source is split into seperate files that have the routines and is well documented. It's taken me
    over a year now to learn about the SX at about an hour or so a day during my lunch break !

    I'm just at the stage where I'm about to produce a working prototype on a PCB (having a crash course in Eagle PCB !) for 'in-the-field' trials.

    Cheers
    Tony
Sign In or Register to comment.