Big LUT's

Page: 12 > Showing page 1 of 2
Author
Trevor Smith
Super Member
  • Total Posts : 194
  • Reward points : 0
  • Joined: 2013/07/22 11:42:07
  • Location: Peterborough UK
  • Status: offline
2015/06/19 05:13:56 (permalink)
0

Big LUT's

Hi All,
Recently had trouble with very large look up tables getting messed up, by crossing page boundaries.
With your usual generous help, this was all fixed by using the following ......
;READ_MOTOR_DEMAND ;Reads a table correctly, even with page overlap !
 movlw HIGH MOTOR_TABLE ;Move the High Byte of the first table location into W
 movwf PCLATH ;and then into PCLATH
 movlw MOTOR_TABLE + 1 ;Load W with the address of the first piece of data in Table2
 addwf MOTOR_DEMAND,W ;Calculate the offset address and
 btfsc STATUS,C ;see if it overflows
 incf PCLATH,F ;If so, increment PCLATH and
 call MOTOR_TABLE ;Jump to the data table

 
My question is,  if my code has small LUT's (as well as some big ones) can they cross page boundaries too ?
Thanks,
Trevor
#1

27 Replies Related Threads

    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Big LUT's 2015/06/19 07:01:31 (permalink)
    0
    No, if you can ensure they won't cross pages, you will save the PCLATH handling.
    Old snippets of code used to feature an assembly-time check to make sure it won't happen...

    GENOVA :D :D ! GODO
    #2
    1and0
    Access is Denied
    • Total Posts : 8337
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Big LUT's 2015/06/19 07:20:48 (permalink)
    0 (1)
    Trevor Smith
    My question is,  if my code has small LUT's (as well as some big ones) can they cross page boundaries too ?

    Yes, small LUTs can cross page boundary, but you can place them within a page too.  I typically located my LUTs at the top of the program memory.
    #3
    Trevor Smith
    Super Member
    • Total Posts : 194
    • Reward points : 0
    • Joined: 2013/07/22 11:42:07
    • Location: Peterborough UK
    • Status: offline
    Re: Big LUT's 2015/06/19 10:10:26 (permalink)
    0
    Thanks guys,
    DarioG
    No, if you can ensure they won't cross pages, you will save the PCLATH handling.
    Old snippets of code used to feature an assembly-time check to make sure it won't happen...

    Not really sure what you mean Dario
     
    1and0
    Yes, small LUTs can cross page boundary, but you can place them within a page too.  I typically located my LUTs at the top of the program memory.


    I place them all right at the top of the MPLAB IDE "program" right after the ORG statements. 
    Is that what you mean ? ........ or do you mean there's a way in the code of forcing them to certain addresses within pages ?



    #4
    1and0
    Access is Denied
    • Total Posts : 8337
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Big LUT's 2015/06/19 11:08:42 (permalink)
    +2 (2)
    First, I think "page" boundary is a bit confusing here; I would rather call it "paragraph" boundary.  In your other thread you used a PIC16F883, which has 4K words of program memory with address from 0x0000 to 0x0FFF.  Page 0 consists of address 0x0000 to 0x07FF and Page 1 consists of address 0x0800 to 0x0FFF.  Each page is consisted of eight "paragraphs" of 256 instruction words selected with PCLATH.  So, as long as all the entries of a LUT are located within the same PCLATH, then that LUT is not crossing any "paragraph" boundary.
     
    Let's say you have a LUT with 100 entries, I'd do this to locate it at the top of the program memory:
    ;
    ; Table entries
    ;
            org     0x1000-.100     ; located at top of program memory
    MyTable
            retlw   .0
            retlw   .1
            retlw   .2
            retlw   .3
            ; ...
            retlw   .99

    and this LUT is read with this:
    ;
    ; Input: WREG = 0 to 255 offset into table
    ;
    ReadMyTable
            movwf   PCLATH          ; setup high byte of table
            xorlw   high(MyTable)   ;   address without using
            xorwf   PCLATH          ;   a temporary register
            xorlw   high(MyTable)   ; recover table offset
            addlw   low (MyTable)   ; add to table base address
    ;       skpnc                   ; skip if does not cross bounary
    ;       incf    PCLATH          ; adjust high byte when it does
            movwf   PCL             ; lookup table entry

    Notice the two commented-out instructions are NOT needed when the table is located within a "paragraph" since there's no need to handle boundary crossing.  Uncommenting these two instructions and the table can then be located ANYWHERE in memory.
    post edited by 1and0 - 2015/06/19 12:26:52
    #5
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Big LUT's 2015/06/19 11:27:26 (permalink)
    0
    I meant something like this:

    GetPWMTable:                  ; entra Value, esce valore in W
         movlw  high PWMTable
        movwf  PCLATH
        rrf  Value,w
        andlw  31

            addlw  low PWMTable
            movwf  PCL
      if (high PWMTable != high PWMTable_end)
            MESSG    "Table crosses memory boundary"
      endif


     
    PWMTable:

      dt 0,1,2,3
      dt 4,5,6,7
      dt 8,9,10,11
      dt 12,13,14,15
      dt 16,18,20,22
      dt 30,32,34,36
      dt 38,42,46,50
      dt 54,58,60,63

    PWMTable_end:


    GENOVA :D :D ! GODO
    #6
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Big LUT's 2015/06/19 11:32:54 (permalink)
    0
    ..and thanks for the XORLW trick, 1and0 Smile after so many years, still improving this old code of mine!
     
    And, I can see, a ",F" is missing above
     
    post edited by DarioG - 2015/06/19 11:35:13

    GENOVA :D :D ! GODO
    #7
    1and0
    Access is Denied
    • Total Posts : 8337
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Big LUT's 2015/06/19 11:44:25 (permalink)
    0 (1)
    DarioG
    ..and thanks for the XORLW trick, 1and0  after so many years, still improving this old code of mine!
     And, I can see, a ",F" is missing above
     

    I don't like that ,F - stuffs.  mr green: mr green
    #8
    NorthGuy
    Super Member
    • Total Posts : 5016
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: Big LUT's 2015/06/19 14:07:18 (permalink)
    0 (1)
    It's much easier with enchanced (PIC16F1*) devices. If you align the table at the boundary of 256 bytes, then you can do:
     
    pagesel JumpTable
    callw

     
    #9
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Big LUT's 2015/06/19 14:49:34 (permalink)
    0
    I prefer using the FSRx method in that case, but indeed in some cases the Call can still be useful!

    GENOVA :D :D ! GODO
    #10
    SeanD
    Super Member
    • Total Posts : 475
    • Reward points : 0
    • Joined: 2009/10/23 07:48:32
    • Location: Dark Rural Northumberland
    • Status: offline
    Re: Big LUT's 2015/06/19 15:06:38 (permalink)
    +1 (1)
    1and0
    DarioG
    ..and thanks for the XORLW trick, 1and0  after so many years, still improving this old code of mine!
     And, I can see, a ",F" is missing above
     

    I don't like that ,F - stuffs.  mr green: mr green


    "tanquam ex ungue leonem" (we recognize the lion by his claw)
    #11
    ric
    Super Member
    • Total Posts : 22101
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Big LUT's 2015/06/19 16:04:27 (permalink)
    +2 (2)
    Much, much simpler on a 16F1xxx device.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #12
    1and0
    Access is Denied
    • Total Posts : 8337
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Big LUT's 2015/06/19 21:13:43 (permalink)
    +1 (1)
    SeanD
    "tanquam ex ungue leonem" (we recognize the lion by his claw)

    "gigantum humeris insidentes" (standing on the shoulders of giants)
     
    If I recall correctly I found that elegant XOR trick to update PCLATH without smashing the W register from dan1138.
     
    Agree that it's much simpler with enhanced midrange devices.
     
    #13
    SeanD
    Super Member
    • Total Posts : 475
    • Reward points : 0
    • Joined: 2009/10/23 07:48:32
    • Location: Dark Rural Northumberland
    • Status: offline
    Re: Big LUT's 2015/06/19 23:41:25 (permalink)
    +1 (1)
    NorthGuy
    I use on the 16f1x "brw" which will work irrespective of page/paragraph boundaries up to tables 256 in length, otherwise use indirect addressing with FSR0 or FSR1 with 0x8000 + address. The MSB is  set by the "high" operator if the table is in the same file as where the FSR registers are set, but if you are linking in a table from elsewhere it is not reliable.
    movlw low address
    movwf FSR0L
    movlw high address ; Will set the MSB if it is in the same file as LUT
    movwf FSR0H
    moviw

     
    1and0
    "gigantum humeris insidentes" (standing on the shoulders of giants)

    Impressed you got the reference!
    post edited by SeanD - 2015/06/19 23:51:04
    #14
    Trevor Smith
    Super Member
    • Total Posts : 194
    • Reward points : 0
    • Joined: 2013/07/22 11:42:07
    • Location: Peterborough UK
    • Status: offline
    Re: Big LUT's 2015/06/20 01:59:52 (permalink)
    0 (1)
    1and0
    First, I think "page" boundary is a bit confusing here; I would rather call it "paragraph" boundary.  In your other thread you used a PIC16F883, which has 4K words of program memory with address from 0x0000 to 0x0FFF.  Page 0 consists of address 0x0000 to 0x07FF and Page 1 consists of address 0x0800 to 0x0FFF.  Each page is consisted of eight "paragraphs" of 256 instruction words selected with PCLATH.  So, as long as all the entries of a LUT are located within the same PCLATH, then that LUT is not crossing any "paragraph" boundary.

    @ 1and0 .... Aha ! great explanation, thanks !
     
    1and0
    ReadMyTable
            movwf   PCLATH          ; setup high byte of table
            xorlw   high(MyTable)   ;   address without using
            xorwf   PCLATH          ;   a temporary register
            xorlw   high(MyTable)   ; recover table offset
            addlw   low (MyTable)   ; add to table base address
    ;       skpnc                   ; skip if does not cross bounary
    ;       incf    PCLATH          ; adjust high byte when it does
            movwf   PCL             ; lookup table entry

     
    Close to what I'd learned previously to work my huge tables. When I have trouble with smaller ones too, the above would be a wise precaution, thanks 1and0.

    Great suggestions guys, I'll try the ideas you've given me and get back to you.
    Thanks,
    Trev
    #15
    1and0
    Access is Denied
    • Total Posts : 8337
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Big LUT's 2015/06/21 15:18:52 (permalink)
    0 (1)
    SeanD
    I use on the 16f1x "brw" which will work irrespective of page/paragraph boundaries up to tables 256 in length, otherwise use indirect addressing with FSR0 or FSR1 with 0x8000 + address. The MSB is  set by the "high" operator if the table is in the same file as where the FSR registers are set, but if you are linking in a table from elsewhere it is not reliable.
    movlw low address
    movwf FSR0L
    movlw high address ; Will set the MSB if it is in the same file as LUT
    movwf FSR0H
    moviw


    Hmmm... not sure that's a bug or not, but a macro should take care of it:
    ;
    ; Load FSR with 16-bit Literal
    ;
    lfsr    macro   fsr,addr
        if  ((fsr) != FSR0) && ((fsr) != FSR1)
            error   Invalid FSR register
        endif
            movlw   low(addr)
            movwf   (fsr)+0
            movlw   high(addr)
            movwf   (fsr)+1
            endm
    ;
    ; Load FSR with Program Flash Memory Address
    ;
    lpfsr   macro   fsr,addr
            lfsr    fsr,(addr)+0x8000
            endm

    Usage:
     
            lpfsr   FSR0,address
    #16
    ric
    Super Member
    • Total Posts : 22101
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Big LUT's 2015/06/21 15:26:21 (permalink)
    0 (1)
    I haven't tried it recently, but the linker should be able to handle adding a constant to an external address.
    I don't see how wrapping it into a macro would make any difference.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #17
    1and0
    Access is Denied
    • Total Posts : 8337
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Big LUT's 2015/06/21 15:32:27 (permalink)
    0
    ric
    I haven't tried it recently, but the linker should be able to handle adding a constant to an external address.
    I don't see how wrapping it into a macro would make any difference.

    Yes, the linker should be able to, such as:

     
            movlw   low address
            movwf   FSR0L
            movlw   high (address + 0x8000)
            movwf   FSR0H
     

    but you don't have to worry about the offset when using the macro.  <edit> Besides, that macro works like PIC18's LFSR instruction </edit>
    post edited by 1and0 - 2015/06/21 15:35:27
    #18
    ric
    Super Member
    • Total Posts : 22101
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Big LUT's 2015/06/21 15:36:33 (permalink)
    +1 (1)
    The macro can't do any magic that your own code can't do too.
    If it's referring to an address in an external file, the addition has to be done by the linker.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #19
    1and0
    Access is Denied
    • Total Posts : 8337
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Big LUT's 2015/06/21 15:39:59 (permalink)
    0 (1)
    ric
    The macro can't do any magic that your own code can't do too.
    If it's referring to an address in an external file, the addition has to be done by the linker.

    Yes, just less typing and easier to read...at least to me. ;)
     
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2018 APG vNext Commercial Version 4.5