• AVR Freaks

AnsweredHot!18F45K80 LUT help please

Author
Trevor Smith
Super Member
  • Total Posts : 218
  • Reward points : 0
  • Joined: 2013/07/22 11:42:07
  • Location: Peterborough UK
  • Status: offline
2020/09/25 07:52:10 (permalink)
0

18F45K80 LUT help please

Hi All,
I have a program running, including the code snippet shown below.
This uses a variable "SELECTOR" to choose various "ACTIONS" from an LUT.
The "ACTIONS" routines are all elsewhere in the program.
It appears even this code is struggling sometimes with page boundaries, sometimes performing the wrong actions.
This is strange, as I've used this approach before.
 
Any ideas guys ?
Thanks,
Trevor

;SELECTOR is a number generated by my program .... then CALL  READ_ACTIONS_TABLE
;
READ_ACTIONS_TABLE
      decf    SELECTOR,F                              ;sub -1
      decf    SELECTOR,F                              ;sub -1
      rlncf    SELECTOR,F                             ;SELECTOR x 2
;--------
      movlw   HIGH ACTIONS_TABLE            ;load PCLATH
      movff    WREG, PCLATH
      movff    SELECTOR, WREG ;LOAD PCL
      addlw    LOW ACTIONS_TABLE
      btfsc     STATUS,C
      incf       PCLATH,F
      movwf   PCL
;
;
ACTIONS_TABLE
      Bra   ACTION1                      ;ACTION1 routine performs various functions
      Bra   ACTION2
      Bra   ACTION3
      Bra   ACTION4
      Bra   ACTION5
      Bra   ACTION6
      Bra   ACTION7
      Bra   ACTION8
      Bra   ACTION9
      Bra   ACTION10
      Bra   ACTION11
      Bra   ACTION12
      Bra   ACTION13
      Bra   ACTION14
      Bra   ACTION15
      Bra   ACTION16

#1
1and0
Access is Denied
  • Total Posts : 11325
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 10:04:56 (permalink) ☄ Helpfulby Trevor Smith 2020/09/25 12:14:27
+2 (2)
Trevor Smith
This uses a variable "SELECTOR" to choose various "ACTIONS" from an LUT.
The "ACTIONS" routines are all elsewhere in the program.
It appears even this code is struggling sometimes with page boundaries, sometimes performing the wrong actions.
This is strange, as I've used this approach before.
 
Any ideas guys ?

The BRA instruction has limited range. PIC18 devices have better instructions for multiple-byte arithmetic. Why decrement SELECTOR twice? What is its range?
 
#2
Trevor Smith
Super Member
  • Total Posts : 218
  • Reward points : 0
  • Joined: 2013/07/22 11:42:07
  • Location: Peterborough UK
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 11:03:21 (permalink)
0
Hi 1and0,
1and0
Why decrement SELECTOR twice? What is its range?

Ooops, that's a typo when I pasted my code.  Only decremented once. 
"EDIT" SELECTOR= 0 to 16
1and0
The BRA instruction has limited range. PIC18 devices have better instructions for multiple-byte arithmetic.

Not sure which instructions ?
As you can see from the table, I need to choose an action based on the SELECTOR number.
ACTION1 is a little routine
ACTION2 is a different little routine
 
Trev
post edited by Trevor Smith - 2020/09/25 11:06:20
#3
1and0
Access is Denied
  • Total Posts : 11325
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 11:09:37 (permalink) ☼ Best Answerby Trevor Smith 2020/09/25 12:14:57
+2 (2)
So I guess your SELECTOR variable has a range of 1 to 16? Why not start at 0 and save yourself the DEC?
 
Forget those multiple-byte arithmetic instructions for now; they won't help here. ;)
 
Are you sure all those ACTIONx routines are within the range of a BRA instruction? Is the correct bank selected to access SELECTOR? Not an issue, but your uses of MOVFF in that snippet are not necessary and waste.
 
 
#4
1and0
Access is Denied
  • Total Posts : 11325
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 11:10:25 (permalink) ☄ Helpfulby Trevor Smith 2020/09/25 12:15:05
+1 (1)
Trevor Smith
Ooops, that's a typo when I pasted my code.  Only decremented once. 
"EDIT" SELECTOR= 0 to 16

Decrement 0 will result in 255. ;)
 
#5
Trevor Smith
Super Member
  • Total Posts : 218
  • Reward points : 0
  • Joined: 2013/07/22 11:42:07
  • Location: Peterborough UK
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 12:09:30 (permalink)
+1 (1)
Looks like you've done it again 1and0 !
 
The data sheet states the BRA has a range of -1024 – n – 1023.
Calculating the addresses from the disassembly listing, some of the ACTIONS routines were too far away from the BRA’s.
So, I’ve grouped all the ACTIONS routines together and put the BRA table with them.
The addresses are now all well within range and all works fine !
I live and learn.
 
1and0 Decrement 0 will result in 255. ;)

I’ve deleted the decrement and still all works fine.
I’ll investigate where this came from and what it’s doing.
 
Actually, the SELECTOR range is 1-16 for the table reads, as you correctly suspected.
It can go to zero, but that’s an alarm condition, which I’m trapping ok.
 
Thanks again,
Trev
#6
1and0
Access is Denied
  • Total Posts : 11325
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 12:32:43 (permalink)
+1 (1)
Trevor Smith
Actually, the SELECTOR range is 1-16 for the table reads, as you correctly suspected.
It can go to zero, but that’s an alarm condition, which I’m trapping ok.

This would be more efficient:
READ_ACTIONS_TABLE
        movlw   high ACTIONS_TABLE
        movwf   PCLATH
        rlncf   SELECTOR,w
        addlw   low ACTIONS_TABLE
        btfsc   STATUS,C
        incf    PCLATH
        movwf   PCL
        ; ...
        
ACTIONS_TABLE
        nop                 ; 0 -- do whatever best here
        bra     ACTION1
        ;...
        bra     ACTION16

 
#7
dan1138
Super Member
  • Total Posts : 3917
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 12:49:03 (permalink)
+1 (1)
Trevor Smith
Any ideas guys ?

This is how I would do it:
;
; File:     main.S
; Target:   PIC18F45K80
; Author:   dan1138
; Date:     2020-09-25
; Compiler: pic-as(v2.20)
; IDE:      MPLABX v5.40
;
; Description:
;
;   Example assembly language branch table
;
; Add this line in the project properties box, pic-as Global Options -> Additional options:
;   -Wl,-Wl,-presetVec=0h
;
    PROCESSOR   18F45K80
    PAGEWIDTH   132
    RADIX       dec

#include <xc.inc>

; PIC18F45K80 Configuration Bit Settings

 config RETEN = OFF      ; VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
 config INTOSCSEL = HIGH ; LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
 config SOSCSEL = HIGH   ; SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
 config XINST = OFF      ; Extended Instruction Set (Disabled)
 config FOSC = INTIO2    ; Oscillator (Internal RC oscillator)
 config PLLCFG = OFF     ; PLL x4 Enable bit (Disabled)
 config FCMEN = OFF      ; Fail-Safe Clock Monitor (Disabled)
 config IESO = OFF       ; Internal External Oscillator Switch Over Mode (Disabled)
 config PWRTEN = OFF     ; Power Up Timer (Disabled)
 config BOREN = OFF      ; Brown Out Detect (Disabled in hardware, SBOREN disabled)
 config BORV = 3         ; Brown-out Reset Voltage bits (1.8V)
 config BORPWR = ZPBORMV ; BORMV Power level (ZPBORMV instead of BORMV is selected)
 config WDTEN = OFF      ; Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
 config WDTPS = 1048576  ; Watchdog Postscaler (1:1048576)
 config CANMX = PORTB    ; ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
 config MSSPMSK = 1      ; MSSP address masking (7 Bit address masking mode)
 config MCLRE = ON       ; Master Clear Enable (MCLR Enabled, RE3 Disabled)
 config STVREN = ON      ; Stack Overflow Reset (Enabled)
 config BBSIZ = BB2K     ; Boot Block Size (2K word Boot Block size)
 config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF
 config CPB = OFF, CPD = OFF
 config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
 config WRTC = OFF, WRTB = OFF, WRTD = OFF
 config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
 config EBTRB = OFF      ; Table Read Protect Boot (Disabled)
;
; Power On Reset entry point
;
    PSECT   resetVec,class=CODE,reloc=2
    global  PORreset
PORreset:
    goto    main
;
; Action branch table
;
    PSECT   code
    global  ACTIONS_TABLE
ACTIONS_TABLE:
    goto    ACTION1
AT_SecondElement:
    goto    ACTION2
    goto    ACTION3
    goto    ACTION4
    goto    ACTION5
    goto    ACTION6
    goto    ACTION7
    goto    ACTION8
    goto    ACTION9
    goto    ACTION10
    goto    ACTION11
    goto    ACTION12
    goto    ACTION13
    goto    ACTION14
    goto    ACTION15
AT_LastdElement:
    goto    ACTION16
;
; Macros that describe the shape of the branch table
;
#define ActionTableElementCount ((AT_LastdElement-ACTIONS_TABLE)/(AT_SecondElement-ACTIONS_TABLE))
#define ActionTableElementSize (AT_SecondElement-ACTIONS_TABLE)
;
; Indirect branch to action
;
; Input: WREG = Action selector, range 0 to 255
;
    PSECT   code
    global  Select_Action
Select_Action:
    movwf   PRODL,c                 ; Save action seelctor.
    movlw   ActionTableElementCount+1
    cpfslt  PRODL,c                 ; Skip when action selector is withing the branch table.
    return
    movlw   ActionTableElementSize
    mulwf   PRODL,c                 ; Scale the selector by the action table element size to make the table offset.
    movlw   LOW(ACTIONS_TABLE)
    addwf   PRODL,F,c               ; Add offset to table start address (bits 7-0).
    movlw   HIGH(ACTIONS_TABLE)
    addwfc  PRODH,W,c               ; Add offset to table start address (bits 15-8).
    movwf   PCLATH,c
    clrf    PCLATU,c
    movlw   (ACTIONS_TABLE>>16)
    addwfc  PCLATU,F,c              ; Add offset to table start address (bits 23-16).
    movf    PRODL,W,c
    movwf   PCL,c                   ; Update the program counter to the branch table address.
;
;   Data used by main application
    PSECT   main_data,global,class=RAM,space=1,delta=1,noexec
;
    GLOBAL  Selector
Selector:   DS  1
;
; Application loop
;
    PSECT   code
    global  main
main:
    banksel Selector
    clrf    BANKMASK(Selector),b    ; Start with first asction.
AppLoop:
    movf    BANKMASK(Selector),W,b
    call    Select_Action           ; Invoke action.
    banksel Selector
    incf    BANKMASK(Selector),F,b  ; Select next action.
    movlw   ActionTableElementCount
    cpfsgt  BANKMASK(Selector),b    ; Skip if next action is not within the table.
    goto    AppLoop                 ; Loop for next action.
    goto    main                    ; Start all over.
;
; Actions call using table lookup
;
ACTION1:
    return
ACTION2:
    return
ACTION3:
    return
ACTION4:
    return
ACTION5:
    return
ACTION6:
    return
ACTION7:
    return
ACTION8:
    return
ACTION9:
    return
ACTION10:
    return
ACTION11:
    return
ACTION12:
    return
ACTION13:
    return
ACTION14:
    return
ACTION15:
    return
ACTION16:
    return

; Tell linker the address of the Power-On-Reset
    end     PORreset

 
post edited by dan1138 - 2020/09/25 16:18:44
#8
Trevor Smith
Super Member
  • Total Posts : 218
  • Reward points : 0
  • Joined: 2013/07/22 11:42:07
  • Location: Peterborough UK
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 14:49:33 (permalink)
0
Thanks for the help, brilliant as ever.
 
Thanks Dan,
Pretty advanced stuff there, a bit out of my league, but I'll try to decipher that and see what I can make of it.
Trev
#9
dan1138
Super Member
  • Total Posts : 3917
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: 18F45K80 LUT help please 2020/09/25 15:33:33 (permalink)
+2 (2)
Trevor Smith
Thanks for the help, brilliant as ever.
 
Thanks Dan,
Pretty advanced stuff there, a bit out of my league, but I'll try to decipher that and see what I can make of it.
Trev

Hey, you're writing assembly language now, so it's time to pee in the tall wheat with the big dogs. :)
#10
Jump to:
© 2020 APG vNext Commercial Version 4.5