Speed optimization (framebuffer scrolling)


Closed Thread
Results 1 to 17 of 17

Hybrid View

  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,531

    Default Speed optimization (framebuffer scrolling)

    I'm working on my MAX7219 display code and I'm in optimization mode. Have managed to get from 22ms to 6.5ms for redrawing a screen of 81 matrices (at 2MHz SPI clock) and I don't think I can squeeze more performance out of that particular section of the code at this moment. Next in line is the scrolling of the framebuffer, here's the code for it:
    Code:
    NumberOfDisplays  CON 36
    FrameBufferSize   CON NumberOfDisplays * 10 + 20 
    
    FrameBuffer       VAR BYTE[FrameBufferSize]
    Row               VAR BYTE
    Col               VAR WORD
    Offset            VAR WORD
    FrameBufferByte   VAR BYTE
    MAX7219_Value     VAR BYTE
    
    
    ScrollLeft:
        ' Shifts content of the screenbuffer one column to the left. It does not redraw the display.
        ' Input: None
        ' Output: None    
        ' This version: 3.5ms for 36 displays @64MHz
    
        FOR Col = 0 to NumberOfDisplays + 1                        ' 8 columns on left and right side, outside of display area
            For Row = 0 to 9                                                   ' One invisible row top and bottom of display area to facilitate vertical scrolling
                Offset = Row * (NumberOfDisplays + 2) + Col 
                MAX7219_Value = FrameBuffer[Offset] >> 1
    
                ' As long as the next byte is NOT the last byte in the row:
                IF Col < (NumberOfDisplays + 1) THEN
                  FrameBufferByte = FrameBuffer[Offset + 1]
                  MAX7219_Value.7 = FrameBufferByte.0
                ENDIF
    
                FrameBuffer[Offset] = MAX7219_Value
            NEXT
        NEXT
    RETURN
    Any ideas on how to make this run faster?

  2. #2
    Join Date
    Aug 2011
    Posts
    419


    Did you find this post helpful? Yes | No

    Default Re: Speed optimization (framebuffer scrolling)

    Without getting into asm or anything, how about this (untested):
    Code:
    OFFSET_INCR CON NumberOfDisplays + 2
    ScrollLeft:
        ' Shifts content of the screenbuffer one column to the left. It does not redraw the display.
        ' Input: None
        ' Output: None    
        ' This version: 1.30ms for 36 displays @64MHz
    
        ' do for Col < NumberOfDisplays+1
        FOR Col = 0 to NumberOfDisplays                        ' 8 columns on left and right side, outside of display area
            Offset = Col
            For Row = 0 to 9                                                   ' One invisible row top and bottom of display area to facilitate vertical scrolling
                'Offset = Row * (NumberOfDisplays + 2) + Col 
                MAX7219_Value = FrameBuffer[Offset] >> 1
    
                FrameBufferByte = FrameBuffer[Offset + 1]
                MAX7219_Value.7 = FrameBufferByte.0
    
                FrameBuffer[Offset] = MAX7219_Value
                Offset = Offset + OFFSET_INCR           ' basically Row * (NumberOfDisplays + 2)
            NEXT
        NEXT
    
        Col = NumberOfDisplays + 1                        ' 8 columns on left and right side, outside of display area
        Offset = Col
        For Row = 0 to 9                                                   ' One invisible row top and bottom of display area to facilitate vertical scrolling
            'Offset = Row * (NumberOfDisplays + 2) + Col 
            MAX7219_Value = FrameBuffer[Offset] >> 1
            FrameBuffer[Offset] = MAX7219_Value
            Offset = Offset + OFFSET_INCR           ' basically Row * (NumberOfDisplays + 2)
        NEXT
    RETURN
    That cuts it down to 1.3ms

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    2,397


    Did you find this post helpful? Yes | No

    Default Re: Speed optimization (framebuffer scrolling)

    try some asm

    untested but should be close
    bcnt var byte bank 1
    dcnt var byte bank 1
    dspbuff var byte[380] ;36 displays + 2 outside of display * 10

    Code:
    rotate_r:  ' pic18
    asm
        banksel _bcnt    ;ROW
        movlw   10       ;10 rows  
        movwf   _bcnt
        clrf    FSR0H
        movlw   low  (_dspbuff)
        movwf   FSR0L
        movlw   111        ;BUFFER SIZE low byte  (380-1) 36 displays + 2 outside of display * 10-1
        ADDWF   FSR0L,F
        movlw   high (_dspbuff)
        ADDWFC   FSR0H
        movlw   1        ;BUFFER SIZE high byte  (380)
        ADDWF   FSR0H
        banksel _bcnt     ;note place bcnt and dcnt in same bank
        MOVLW 38     ;36 displays + 2 outside of display  
    NROW       
        movwf   _dcnt
        bcf    STATUS, C
    Ncol
        rrcf   POSTDEC0 ,f     ;PER COLUMN
        DECFSZ  _dcnt ,F
        BRA    Ncol
        BNC    NBNC
        bsf    PLUSW0,7     ;max displays would be 127 to use plusw
    NBNC 
        DECFSZ  _bcnt ,F
        BRA    NROW
        banksel 0
    endasm










    this is my 4 panel code for reference


    Code:
    rotate: ;pic18
    asm
        banksel _bcnt    ;ROW
        movlw   8
        movwf   _bcnt
        clrf    FSR0H
        movlw   low  (_dspbuff)
        movwf   FSR0L
        movlw   31        ;BUFFER SIZE
        ADDWF   FSR0L,F
        movlw   high (_dspbuff)
        ADDWFC   FSR0H
        banksel _bcnt
        MOVLW 4
    NROW     
        bcf    STATUS, C
        rrcf   POSTDEC0 ,f     ;PER COLUMN
        rrcf   POSTDEC0 ,f     ;PER COLUMN
        rrcf   POSTDEC0 ,f     ;PER COLUMN
        rrcf   POSTDEC0 ,f     ;PER COLUMN
        BNC    NBNC
        bsf    PLUSW0,7
    NBNC 
        DECFSZ  _bcnt ,F
        BRA    NROW
    endasm
    Last edited by richard; - 10th October 2022 at 00:46.
    Warning I'm not a teacher

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,531


    Did you find this post helpful? Yes | No

    Default Re: Speed optimization (framebuffer scrolling)

    Richard, thank you. My problem is I suck as ASM and I don't understand half of what's going on there. It might very well work, in which case I'd be lucky but if it doesn't or I need to modify it I basically have no idea what I'm doing. I should use it as a learning exercise though as I do feel the need to better understand ASM.

    tumblweed, wow, that was an easy yet effective modification (and it works perfectly fine) - just what I was hoping for.
    Went down from 7.6ms to just above 3ms for a 81 matrix wide display. More than double the speed, cool!

    One thing threw me off on a tangent for a while...
    Code:
    OFFSET_INCR CON NumberOfDisplays + 2
    Since NumberOfDisplays is already a CONstant (with the value 81 in this particular case) I replaced
    Code:
    Offset = Offset + OFFSET_INCR
    with
    Code:
    Offset = Offset + NumberOfDisplays + 2
    expecting the compiler to replace both versions to
    Code:
    Offset = Offset + 83
    It did not...your version with, the constant defined executes at 3.03ms, the other one in 3.45ms

    I took 15 minutes for the penny to drop and now I need to go thru my code and see where else I've made that silly mistake.

    Thanks again, both of you guys!

    /Henrik.

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,397


    Did you find this post helpful? Yes | No

    Default Re: Speed optimization (framebuffer scrolling)

    I should use it as a learning exercise though as I do feel the need to better understand ASM.
    its worth the effort

    this just under 100uS for a iteration



    Code:
    '****************************************************************
    '*  Name    : UNTITLED.BAS                                      *
    '*  Author  : richard                                           *
    '*  Notice  : Copyright (c) 2022 caveat emptor                  *
    '*          : All Rights Reserved                               *
    '*  Date    : 11/10/2022                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    #CONFIG
      CONFIG  FOSC = INTIO67
      CONFIG  PLLCFG = ON
      CONFIG  PRICLKEN = ON
      CONFIG  FCMEN = OFF
      CONFIG  IESO = OFF
      CONFIG  PWRTEN = ON
      CONFIG  BOREN = SBORDIS
      CONFIG  BORV = 190
      CONFIG  WDTEN = OFF
      CONFIG  WDTPS = 32768
      CONFIG  CCP2MX = PORTC1
      CONFIG  PBADEN = OFF
      CONFIG  CCP3MX = PORTB5
      CONFIG  T3CMX = PORTC0
      CONFIG  HFOFST = ON
      CONFIG  P2BMX = PORTB5
      CONFIG  MCLRE = EXTMCLR
      CONFIG  STVREN = ON
      CONFIG  LVP = OFF
      CONFIG  XINST = OFF
      CONFIG  DEBUG = OFF
      CONFIG  CP0 = OFF
      CONFIG  CP1 = OFF
      CONFIG  CP2 = OFF
      CONFIG  CP3 = OFF
      CONFIG  CPB = OFF
      CONFIG  CPD = OFF
      CONFIG  WRT0 = OFF
      CONFIG  WRT1 = OFF
      CONFIG  WRT2 = OFF
      CONFIG  WRT3 = OFF
      CONFIG  WRTC = OFF
      CONFIG  WRTB = OFF
      CONFIG  WRTD = OFF
      CONFIG  EBTR0 = OFF
      CONFIG  EBTR1 = OFF
      CONFIG  EBTR2 = OFF
      CONFIG  EBTR3 = OFF
      CONFIG  EBTRB = OFF
    #ENDCONFIG
        
    
    
    
    
        DEFINE OSC 64
        DEFINE DEBUG_REG PORTB
        DEFINE DEBUG_BIT 7
        DEFINE DEBUG_BAUD 9600
        DEFINE DEBUG_MODE 0
        LATB.7=1
        bcnt       VAR BYTE   bank0
        dcnt       VAR BYTE   bank0
        BUFF       VAR BYTE[32]
        iteration  VAR word 
        OSCCON=$70
        OSCTUNE.6=1
        while ! osccon2.7 :WEND    ;wait for pll
        ANSELB=0
        ANSELC=0
        ANSELA=0 
        dspbuff var byte[380]
        clear
        trisc = %01111111 
        TRISB = %01111111
        TRISA = %11111111
        pause 1000
        debug 13,10,"ready",13,10
         LATc.7=0
         ;38x8 bits wide 10 bits high
         dspbuff[379]=$c0
         dspbuff[37]=$c0
    main:
    LATc.7=1; trigger oscilloscope
    gosub rotate_r    
    LATc.7=0
    debug 13,10,dec iteration
    debug 13,10,bin8 dspbuff[379]," " ,bin8 dspbuff[378]," " ,bin8 dspbuff[343] ," ",bin8 dspbuff[342] 
    debug 13,10,bin8 dspbuff[37] ," " ,bin8 dspbuff[36] ," " ,bin8 dspbuff[1]   ," ",bin8 dspbuff[0] 
    pause 200
    iteration=iteration+1    
    goto main    
        
        
        
        
    rotate_r:  ' pic18    100uS
    asm
        banksel _bcnt    ;ROW
        movlw   10       ;10 rows  
        movwf   _bcnt
        movlw   high (_dspbuff)
        movwf   FSR0H    
        movlw   low  (_dspbuff)
        movwf   FSR0L
        movlw   123        ;BUFFER SIZE low byte  (380-1) 36 displays + 2 outside of display * 10-1
        ADDWF   FSR0L 
        movlw   1        ;BUFFER SIZE high byte  (380)
        ADDWFC   FSR0H
        MOVLW 38     ;36 displays + 2 outside of display 
    NROW  
        movwf   _dcnt
        bcf    STATUS, C
    Ncol
        rrcf   POSTDEC0 ,f     ;PER COLUMN
        DECFSZ  _dcnt ,F
        BRA    Ncol
        BNC    NBNC
        bsf    PLUSW0,7     ;max displays would be 127 to use plusw
    NBNC 
        DECFSZ  _bcnt ,F
        BRA    NROW
        banksel 0
        return
    endasm
    Warning I'm not a teacher

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,531


    Did you find this post helpful? Yes | No

    Default Re: Speed optimization (framebuffer scrolling)

    Thanks Richard,
    What device did you run this on?
    After being unseccessfull in integrating your version into my code I tried to get your code (I removed some oscillator specific stuff to match my device) to compile for the 57Q43 but it won't.
    It can't fit bcnt/dcnt into bank 0 so I tried various banks. Bank 5 works but I still get [ASM WARNING: ASM-SCROLL.ASM (411) : Invalid RAM location specified]

    Line 411 in the .asm listing is banksel 0 in the NBNC routine.

    I know it says warning and not error but the description sounds bad enough :-)

    See, this is what I mean....

    For reference, here's what I'm trying to compile for the 57Q43:
    Code:
    DEFINE OSC 64
    DEFINE DEBUG_REG PORTB
    DEFINE DEBUG_BIT 7
    DEFINE DEBUG_BAUD 9600
    DEFINE DEBUG_MODE 0
    
    LATB.7=1
    
    bcnt       VAR BYTE   bank0
    dcnt       VAR BYTE   bank0
    iteration  VAR word 
    
    ANSELB=0
    ANSELC=0
    ANSELA=0 
    dspbuff var byte[380]
    clear
    trisc = %01111111 
    TRISB = %01111111
    TRISA = %11111111
    pause 1000
    debug 13,10,"ready",13,10
     LATc.7=0
     ;38x8 bits wide 10 bits high
     dspbuff[379]=$c0
     dspbuff[37]=$c0
    
    
    main:
    LATc.7=1; trigger oscilloscope
    gosub rotate_r    
    LATc.7=0
    debug 13,10,dec iteration
    debug 13,10,bin8 dspbuff[379]," " ,bin8 dspbuff[378]," " ,bin8 dspbuff[343] ," ",bin8 dspbuff[342] 
    debug 13,10,bin8 dspbuff[37] ," " ,bin8 dspbuff[36] ," " ,bin8 dspbuff[1]   ," ",bin8 dspbuff[0] 
    pause 200
    iteration=iteration+1    
    goto main    
        
        
    rotate_r:  ' pic18    100uS
    asm
        banksel _bcnt    ;ROW
        movlw   10       ;10 rows  
        movwf   _bcnt
        movlw   high (_dspbuff)
        movwf   FSR0H    
        movlw   low  (_dspbuff)
        movwf   FSR0L
        movlw   123        ;BUFFER SIZE low byte  (380-1) 36 displays + 2 outside of display * 10-1
        ADDWF   FSR0L 
        movlw   1        ;BUFFER SIZE high byte  (380)
        ADDWFC   FSR0H
        MOVLW 38     ;36 displays + 2 outside of display 
    NROW  
        movwf   _dcnt
        bcf    STATUS, C
    Ncol
        rrcf   POSTDEC0 ,f     ;PER COLUMN
        DECFSZ  _dcnt ,F
        BRA    Ncol
        BNC    NBNC
        bsf    PLUSW0,7     ;max displays would be 127 to use plusw
    NBNC 
        DECFSZ  _bcnt ,F
        BRA    NROW
        banksel 0
        return
    endasm

  7. #7
    Join Date
    May 2013
    Location
    australia
    Posts
    2,397


    Did you find this post helpful? Yes | No

    Default Re: Speed optimization (framebuffer scrolling)

    18f26k22

    i have not tried much with Q43 yet , but
    they have no ram below bank 5.
    i dont know what bank pbp defaults to for them bank0 makes no sense at all , before them pbp kinda assumes bank0 before and after calls.
    the instruction set is slightly different. movfffl or whatever
    there may be other weird shit with indirect addressing

    i have some q43's i just lack the enthusiasm to learn about them when the tried and trusty k22 serves my needs
    Warning I'm not a teacher

Similar Threads

  1. Re:Scrolling speed control problem in moving message display
    By machobob in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 19th June 2010, 12:08
  2. Replies: 0
    Last Post: - 7th August 2008, 09:02
  3. code size VS speed optimization setting?
    By Kamikaze47 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 28th April 2008, 14:38
  4. While we're on the subject of optimization...
    By skimask in forum mel PIC BASIC Pro
    Replies: 31
    Last Post: - 11th March 2008, 12:51
  5. Multiple if then optimization
    By Mugelpower in forum mel PIC BASIC Pro
    Replies: 35
    Last Post: - 5th March 2008, 12:15

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts