• AVR Freaks

Hot!Need help with branch table

Page: 12 > Showing page 1 of 2
Author
davea
Senior Member
  • Total Posts : 153
  • Reward points : 0
  • Joined: 2016/01/28 13:12:13
  • Location: 0
  • Status: offline
2019/09/10 15:14:05 (permalink)
0

Need help with branch table

trying to create a simple branch table
this is what I have so far
and it needs work
 
void TESTS(void) {
   uint8_t state;
   state = NEW_state;
   state++; // add 1 for offset ????????

   asm("MOVF __state, 1"); // ERROR HERE !!!!!!
   asm("BRW");

static void (TAB_base) (void) = {state0 - TAB_base, state1 - TAB_base, state2 - TAB_base};
                           // ^^^^^ ERROR HERE !!!!!!
state0:
   NOP();
   NEW_state++;
   goto end_state;
state1:
   NOP();
   NOP();
   NEW_state++;
   goto end_state;
state2:
   NOP();
   NOP();
   NOP();
   NEW_state = 0;
end_state:
}

post edited by davea - 2019/09/10 15:17:17
#1

31 Replies Related Threads

    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Need help with branch table 2019/09/10 15:21:31 (permalink)
    +2 (2)

       asm("MOVF __state, 1"); // ERROR HERE !!!!!!

    Why two underscores? C only adds one.
     
    Why use inline ASM at all?
    A switch() construct, using sequential case values will generate almost exactly the same code.
    You seem to be trying to do the compiler's job for it.
     

    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!
    #2
    davea
    Senior Member
    • Total Posts : 153
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/10 15:28:54 (permalink)
    0
    I do use the switch () statement
    but every time it generates 11 instructions (XC-8 PRO - setting 3)
    just trying to speed it up for a ISR
    #3
    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Need help with branch table 2019/09/10 15:33:46 (permalink)
    +1 (1)
    Please show the C code you tried.
     

    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!
    #4
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11347
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: Need help with branch table 2019/09/10 15:57:46 (permalink)
    +1 (1)
    Have you looked at the various switch optimizations the compiler supports?
    #5
    dan1138
    Super Member
    • Total Posts : 3232
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/10 17:00:40 (permalink)
    +2 (2)
    davea
    I do use the switch () statement
    but every time it generates 11 instructions (XC-8 PRO - setting 3)
    just trying to speed it up for a ISR



    I think what you are trying to do is terrible in C but this syntax does work:
    /*
     * File:   main.c
     * Target: PIC16F1574
     * Author: dab1138
     *
     * Created on September 10, 2019, 4:06 PM
     */

    // CONFIG1
    #pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator; I/O function on CLKIN pin)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
    #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

    // CONFIG2
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    #pragma config PPS1WAY = OFF    // PPSLOCK bit One-Way Set Enable bit (PPSLOCKED Bit Can Be Cleared & Set Repeatedly)
    #pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
    #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
    #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config LPBOREN = OFF    // Low Power Brown-out Reset enable bit (LPBOR is disabled)
    #pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

    #include <xc.h>
    #include <stdint.h>

    void main(void)
    {
        INTCON = 0;
        OPTION_REGbits.TMR0CS = 0;
        OPTION_REGbits.PSA = 1;
        TMR0 = 0;
        INTCONbits.TMR0IF = 0;
        INTCONbits.TMR0IE = 1;
        INTCONbits.GIE = 1;
        for(;;)
        {
        }
    }

    void __interrupt() ISR_handler( void)
    {
       static uint8_t state = 0;

       if (!INTCONbits.TMR0IE) goto end_state;
       if (!INTCONbits.TMR0IF) goto end_state;
       INTCONbits.TMR0IF = 0;
       if(state > 2) goto err_state;
       
       __asm("MOVF ISR_handler@state,W");
       __asm("BRW");
       __asm("BRA ISR_handler_state0");
       __asm("BRA ISR_handler_state1");
       __asm("BRA ISR_handler_state2");
       /*
        * This code is redundant but required
        * to prevent XC8 from removing code.
        */
       switch (state)
       {
           case  0: goto state0;
           case  1: goto state1;
           case  2: goto state2;
           default: state = 0;
       }

    state0:
    __asm("ISR_handler_state0:");
       NOP();
       state = 1;
       goto end_state;
    state1:
    __asm("ISR_handler_state1");
       NOP();
       NOP();
       state = 2;
       goto end_state;
    state2:
    __asm("ISR_handler_state2:");
       NOP();
       NOP();
       NOP();
    err_state:
       state = 0;
    end_state:
       NOP();
    }

    This is an awful thing I've done. :)
    post edited by dan1138 - 2019/09/10 17:06:39
    #6
    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Need help with branch table 2019/09/10 17:16:56 (permalink)
    +1 (1)
    dan1138
    ...
    This is an awful thing I've done. :)

    I can't argue with you there! ;)

    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!
    #7
    pcbbc
    Super Member
    • Total Posts : 1332
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/10 18:10:29 (permalink)
    +2 (2)
    A switch statement will use a jump table, but there’s a threshold for the number of sequential case values before it decides to use one.
    I seem to remember last time I tested this that it is around 4 or 5.
    #8
    davea
    Senior Member
    • Total Posts : 153
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/10 19:18:48 (permalink)
    0
    jtemples
    Have you looked at the various switch optimizations the compiler supports?


    No but I will
    I just needed something simple and fast, only need 5 states
     
    tried this in code from original post 
          asm("MOVF _state, W"); // undefined symbol "_state"
          asm("BRW");
          asm("goto _state0"); // undefined symbol "_state0"
          asm("goto _state1"); // undefined symbol "_state1"
          asm("goto _state2"); // undefined symbol "_state2"
     
    thank for all responses
    #9
    davea
    Senior Member
    • Total Posts : 153
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/10 19:43:21 (permalink)
    0
    you can see why for just 4 case's
     
    1128: switch(NEW_state){
    062B 082C MOVF NEW_state, W
    062C 0084 MOVWF FSR0
    062D 3004 MOVLW 0x4
    062E 0204 SUBWF FSR0, W
    062F 1803 BTFSC STATUS, 0x0
    0630 0008 RETURN
    0631 30A4 MOVLW 0xA4
    0632 3187 MOVLP 0x7
    0633 0704 ADDWF FSR0, W
    0634 0082 MOVWF PCL
    07A4 2E18 GOTO 0x618
    1129: case 0:
    1130: NOP();
    0618 0000 NOP
    1131: NEW_state = 1;
    0619 0140 MOVLB 0x0
    061A 01AC CLRF NEW_state
    061B 0AAC INCF NEW_state, F
    1132: break;
    061C 0008 RETURN
    1133: case 1:
    1134: NOP();
    061D 0000 NOP
    1135: NEW_state = 2;
    061E 3002 MOVLW 0x2
    061F 0140 MOVLB 0x0
    0620 00AC MOVWF NEW_state
    1136: break;
    0621 0008 RETURN
    1137: case 2:
    1138: NOP();
    0622 0000 NOP
    1139: NEW_state = 3;
    0623 3003 MOVLW 0x3
    0624 0140 MOVLB 0x0
    0625 00AC MOVWF NEW_state
    1140: break;
    0626 0008 RETURN
    1141: case 3:
    1142: NOP();
    0627 0000 NOP
    1143: NEW_state = 0;
    0628 0140 MOVLB 0x0
    0629 01AC CLRF NEW_state
    1144: }
    062A 0008 RETURN

    #10
    davea
    Senior Member
    • Total Posts : 153
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/11 12:02:58 (permalink)
    0
    //****************************************
    void TESTS(void) {
       asm("MOVF _state, W"); // NO offset needed !!!!!
       asm("BRW");
       asm("goto _state0");
       asm("goto _state1");
       asm("goto _state2");
    state0:
       asm("_state0");
       state = 1;
       goto end_state;
    state1:
       asm("_state1");
       state = 2;
       goto end_state;
    state2:
       asm("_state2");
       state = 0;
    end_state:
       asm("RETURN"); // EXIT <<<<<<<<<

       //---------- NEEDED for compiler to label state's ------
       if ((state & 1) == 0) {// 8 instructions (wasted space in ROM)
          goto state0;
       }
       if ((state & 2) == 0) {
          goto state1;
       }
       if ((state & 4) == 0) {
          goto state2;
       }
    }

    This is what I ended up with and it does WORK
    3 instruction jump table :)
    if anyone knows how to reduce the wasted space in ROM
    please let me know..
    thanks to ALL posters, without you I would NEVER have done it....
    #11
    dan1138
    Super Member
    • Total Posts : 3232
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/11 14:11:07 (permalink)
    +1 (1)
    davea
    if anyone knows how to reduce the wasted space in ROM please let me know..

    This is the best I can do with this bad idea:
    /*
     * File:   main.c
     * Target: PIC16F1574
     * Author: dan1138
     *
     * Created on September 11, 2019, 2:02 PM
     */

    // CONFIG1
    #pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator; I/O function on CLKIN pin)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
    #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

    // CONFIG2
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    #pragma config PPS1WAY = OFF    // PPSLOCK bit One-Way Set Enable bit (PPSLOCKED Bit Can Be Cleared & Set Repeatedly)
    #pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
    #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
    #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config LPBOREN = OFF    // Low Power Brown-out Reset enable bit (LPBOR is disabled)
    #pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

    #include <xc.h>
    #include <stdint.h>

    void main(void)
    {
        INTCON = 0;
        OPTION_REGbits.TMR0CS = 0;
        OPTION_REGbits.PSA = 1;
        TMR0 = 0;
        INTCONbits.TMR0IF = 0;
        INTCONbits.TMR0IE = 1;
        INTCONbits.GIE = 1;
        for(;;)
        {
        }
    }

    void __interrupt() ISR_handler( void)
    {
       static uint8_t state = 0;

       if (INTCONbits.TMR0IE && INTCONbits.TMR0IF)
       {
            INTCONbits.TMR0IF = 0;
            if(state > 2) state = 0;
            
            __asm("MOVF ISR_handler@state,W");
            __asm("BRW");
            __asm("BRA ISR_handler_state0");
            __asm("BRA ISR_handler_state1");
            __asm("BRA ISR_handler_state2");

            __asm("ISR_handler_state0:");
            NOP();
            state = 1;
            __asm(" goto ISR_handler_end_state\nISR_handler_state1:");
            NOP();
            NOP();
            state = 2;
            __asm(" goto ISR_handler_end_state\nISR_handler_state2:");
            NOP();
            NOP();
            NOP();
            state = 0;
            __asm("ISR_handler_end_state:");
        }
    }

    #12
    1and0
    Access is Denied
    • Total Posts : 9771
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Need help with branch table 2019/09/11 15:24:42 (permalink)
    +1 (1)
    davea
    if anyone knows how to reduce the wasted space in ROM
    please let me know..

    Just comment off the unused labels and remove the redundant code.
     
    Why not code the entire function in assembly?
     
    #13
    1and0
    Access is Denied
    • Total Posts : 9771
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Need help with branch table 2019/09/11 15:42:30 (permalink)
    +1 (1)
    But if you insist ...
    void TESTS(void) {
        static uint8_t state = 0;
       
        asm("movf TESTS@state,w");
        asm("brw");
        asm("bra _state0");
        asm("bra _state1");
        asm("bra _state2");
       
    //state0:
        asm("_state0");
        state = 1;
        do { return; } while(0);
    //state1:
        asm("_state1");
        state = 2;
        do { return; } while(0);
    //state2:
        asm("_state2");
        state = 0;
    }

    #14
    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Need help with branch table 2019/09/11 15:53:42 (permalink)
    +1 (1)
    In my tests, the static auto variable was usually NOT in bank 0.
    You're going to need a BANKSEL at the start of that code.
     

    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!
    #15
    1and0
    Access is Denied
    • Total Posts : 9771
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Need help with branch table 2019/09/11 16:10:55 (permalink)
    +1 (1)
    ... or make it a global variable located in the shared memory.
     
    Edit: By the way, which PIC device is OP using?
     
    post edited by 1and0 - 2019/09/11 16:12:09
    #16
    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Need help with branch table 2019/09/11 17:03:59 (permalink)
    +1 (1)
    1and0
    ... or make it a global variable located in the shared memory.

    Exactly what I did, by:
    • moving the declaration out of the function (so it's global)
    • adding a "near" qualifier (you can't do this to a static auto variable)
    • editing the project properties to tell XC8 to obey the near qualifier (qualifier setting is "require")
     

    Edit: By the way, which PIC device is OP using?

    I saw reference to a PIC16F1574 in Dan's post, and assumed he got it from one of the OP's other topics.
    It's nicer when you don't have to guess...
    post edited by ric - 2019/09/11 18:03:39

    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
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3292
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/11 17:09:30 (permalink)
    0
    11 instructions (XC-8 PRO - setting 3)
    My logic would be to get a faster chip.
     
    asm volatile ("nop");
    To tell the compiler not to insert any code in-between.
    I don't like inline asm, ends up like this:

           asm volatile("mov #%0,w0\nrcall _i2c_write"::"i"(I2C_DS1307_RTC):"w0");
        asm volatile("clr w0\nrcall _i2c_write":::"w0");
        asm volatile("rcall _i2c_restart");
        asm volatile("mov #%0,w0\nrcall _i2c_write"::"i"(I2C_DS1307_RTC|1):"w0");


    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #18
    dan1138
    Super Member
    • Total Posts : 3232
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Need help with branch table 2019/09/11 21:32:02 (permalink)
    +2 (2)
    1and0
    By the way, which PIC device is OP using?



    I do not know what the OP is using.
     
    I selected the PIC16F1574 because it's the dumbest choice I could make for an 8-bit enhanced mid-range PICs with the "BRW" opcode.
     
    Unlike the OP I posted a complete, builds-without-errors-or-warnings using the Free mode of XC8 example program.
     
    In post #12 I show how I removed all of the redundant code that kept XC8 form breaking things.
     
    This is still awful code. I should be ashamed. :)
    post edited by dan1138 - 2019/09/12 12:43:25
    #19
    1and0
    Access is Denied
    • Total Posts : 9771
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Need help with branch table 2019/09/12 07:02:45 (permalink)
    +1 (1)
    dan1138
    I selected the PIC16F1574 because it's the dumbest choice I could make for an 8-bit enhanced mid-range PICs with the "BRW" opcode.

    grin: grin
     

    Unlike the OP I posted a complete, builds-without-errors-or-warnings using the Free mode of XC8 example program.
     
    In post #12 I show how I removed all of the redundant code that kept XC8 for breaking things.

    Yeah, the do-while(0) seems to get XC8 to behave and not generate "unreachable code" warnings.
     

    This is still awful code. I should be ashamed. :)

    LoL: LoL   I'd go all assembly for this ISR since OP worries about 11 instruction cycles on this switch() thingy. I am sure the other parts of this ISR probably wastes more than that many cycles.
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5