• AVR Freaks

Toggle a LED

Page: 12 > Showing page 1 of 2
Author
uzslm
Super Member
  • Total Posts : 407
  • Reward points : 0
  • Joined: 2016/06/28 18:46:27
  • Location: 0
  • Status: offline
2016/08/23 06:30:45 (permalink)
0

Toggle a LED

 
XC8,PIC16F1459,Consider below lines:
#define LAT_LED1          LATAbits.LATA5
#define LED1_STATUS    PORTAbits.RA5
#define PIN_OUTPUT_DELAY_US  2
void Toggle_Led()
{//i've set LED1 pin as output
if(LED1_STATUS)
LAT_LED1 = __OFF;//#define  __OFF  0
else
LAT_LED1 = __ON;//#define   __ON    1

__delay_us(PIN_OUTPUT_DELAY_US); 
}
if i used LAT_LED1 ^=1,seems that XC8 give a warning(advisory: (1395) notable code sequence candidate suitable for compiler validation suite detected (315) );in fact,this was used to toggle LED in some MLA's demo,but XC8 show no warning,i don't know why.
 i could also change to:LAT_LED1 = !LED1_STATUS,to toggle my LED,but i don't know whether it is safe for read-modify-write operation;although i add additional delay 2 us for output setup.
 
#1

25 Replies Related Threads

    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Toggle a LED 2016/08/23 07:13:03 (permalink)
    0
    I definitely advice that
    LAT_LED1 ^=1
     
    That warning looks like an internal message to the XC developers...

    GENOVA :D :D ! GODO
    #2
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/08/23 07:49:07 (permalink)
    0
    uzslm
     
    i could also change to:LAT_LED1 = !LED1_STATUS,to toggle my LED,but i don't know whether it is safe for read-modify-write operation;although i add additional delay 2 us for output setup.

    Use LATx to avoid RMW.
    LAT_LED1 ^= 1;

    or
    LAT_LED1 = !LAT_LED1;

     
     
    #3
    NKurzman
    A Guy on the Net
    • Total Posts : 19144
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Toggle a LED 2016/08/23 08:19:10 (permalink)
    0
    give a warning(advisory: (1395) notable code sequence candidate suitable for compiler validation suite detected (315) );
     
    This is Not an indication that there is a problem with the code.
    It is a statement the The Optimizer has no rule to optimize it, but it thinks it should.
    You can use the code as is.
     
    IF you are using the Latest version of the compiler.  Zip up a copy of the project and included it with a support ticket.
    At some point it will be reviewed by a team of highly skilled programs.  Then they will optimize it to the fewest op-codes possible.
    #4
    vloki
    Jo, alla!
    • Total Posts : 6815
    • Reward points : 0
    • Joined: 2007/10/15 00:51:49
    • Location: Germany
    • Status: offline
    Re: Toggle a LED 2016/08/24 00:40:57 (permalink)
    0
    1and0
    Use LATx to avoid RMW.
    LAT_LED1 ^= 1;
    or
    LAT_LED1 = !LAT_LED1;
      
    Try both and view the disassembly ;-)
    Not Sure about actual xc Version because I use the latest with plib (3.34).
    With c18 the Resultat was exactly the Same but with xc8 = ! :-(
    post edited by vloki - 2016/08/24 00:43:24

    Uffbasse !
    #5
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/08/24 07:03:57 (permalink)
    0
    vloki
    Try both and view the disassembly ;-)Not Sure about actual xc Version because I use the latest with plib (3.34).
    With c18 the Resultat was exactly the Same but with xc8 = ! :-(

    With OP's PIC device being a PIC16 without a BTG instruction, I would think (and have seen) the former statement generates shifts and xor instructions, while the latter statement generates bit tests and bcf/bsf instructions. That said, I believe this:
    #define LED1 5
    LATA ^= (1 << LED1);

    should generate more efficient code and it can be wrapped with a bitflip() macro:
    #define bitflip(var, bitno) ((var) ^= 1UL << (bitno))

    #6
    cobusve
    Super Member
    • Total Posts : 495
    • Reward points : 0
    • Joined: 2012/04/02 16:15:40
    • Location: Chandler
    • Status: offline
    Re: Toggle a LED 2016/09/02 16:58:01 (permalink)
    0
    Advisory: (1395)  is not an error and does not mean there is anything wrong with your code. This simply means that you have managed to make the compiler do something which none of our internal tests make it do.

    This is used to measure code coverage (which means whenever you do not get this message everything the compiler did was covered by some test).
     
    The compiler team appreciates being sent the project which reproduces these and they will add it to the test suite to help us improve the quality of the compiler.



    #7
    cobusve
    Super Member
    • Total Posts : 495
    • Reward points : 0
    • Joined: 2012/04/02 16:15:40
    • Location: Chandler
    • Status: offline
    Re: Toggle a LED 2016/09/02 17:00:39 (permalink)
    0
    To add, this is in the Compiler User's guide on this Advisory:


    (1395) notable code sequence candidate suitable for compiler validation suite detected (*)
    (Code Generator)
    The compiler has in-built checks that can determine if combinations of internal code
    templates have been encountered. Where unique combinations are uncovered when
    compiling code, this message is issued. This message is not an error or warning, and
    its presence does not indicate possible code failure, but if you are willing to participate,
    the code you are compiling can be sent to Support to assist with the compiler testing
    process.
    #8
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Toggle a LED 2016/09/03 01:15:00 (permalink)
    0
    cobusve
    To add, this is in the Compiler User's guide on this Advisory:


    (1395) notable code sequence candidate suitable for compiler validation suite detected (*)(Code Generator)The compiler has in-built checks that can determine if combinations of internal codetemplates have been encountered. Where unique combinations are uncovered whencompiling code, this message is issued. This message is not an error or warning, andits presence does not indicate possible code failure, but if you are willing to participate,the code you are compiling can be sent to Support to assist with the compiler testingprocess.



    Perfect Smile

    GENOVA :D :D ! GODO
    #9
    Ian.M
    Super Member
    • Total Posts : 13273
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re: Toggle a LED 2016/09/03 18:53:21 (permalink)
    0
    As PIC10/12/16 don't have a BTG instruction, its also worth trying
    LAT_LED1=LAT_LED1?0:1;

    as there are native BTFSS/BTFSC, BCF and BSF instructions.
     
    Under older XC8 compiler versions, the ternary operator tended to generate really crappy code in FREE mode due to the lack of jump to jump optimisations, but that's been fixed in recent versions.

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #10
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/09/03 21:39:05 (permalink)
    0
    Ian.M
    As PIC10/12/16 don't have a BTG instruction, its also worth trying
    LAT_LED1=LAT_LED1?0:1;

    as there are native BTFSS/BTFSC, BCF and BSF instructions.

    That should generate the same code as:
    LAT_LED1 = !LAT_LED1;

     
    Still think this
    #define LED1 5
    LATA ^= (1 << LED1);

    generate more efficient code MOVLW/XORWF, as it does not need the tests and jumps.
    #11
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/09/03 22:06:46 (permalink)
    0
    Here's the disassembly, the first three are crappy when using FREE mode:
     
    32: LAT_LED1 ^= 1;
    07C7 0E0C SWAPF PORTA, W
    07C8 00F7 MOVWF 0x77
    07C9 0C77 RRF 0x77, W
    07CA 3901 ANDLW 0x1
    07CB 00F7 MOVWF 0x77
    07CC 3001 MOVLW 0x1
    07CD 06F7 XORWF 0x77, F
    07CE 0EF7 SWAPF 0x77, F
    07CF 0DF7 RLF 0x77, F
    07D0 080C MOVF PORTA, W
    07D1 0677 XORWF 0x77, W
    07D2 39DF ANDLW 0xdf
    07D3 0677 XORWF 0x77, W
    07D4 008C MOVWF PORTA
    33:
    34: LAT_LED1 = !LAT_LED1;
    07D5 1003 BCF STATUS, 0
    07D6 1E8C BTFSS PORTA, 0x5
    07D7 1403 BSF STATUS, 0
    07D8 1C03 BTFSS STATUS, 0
    07D9 2FDD GOTO 0x7dd
    07DA 0022 MOVLB 0x2
    07DB 168C BSF PORTA, 0x5
    07DC 2FDF GOTO 0x7df
    07DD 0022 MOVLB 0x2
    07DE 128C BCF PORTA, 0x5
    35:
    36: LAT_LED1=LAT_LED1?0:1;
    07DF 1003 BCF STATUS, 0
    07E0 1E8C BTFSS PORTA, 0x5
    07E1 1403 BSF STATUS, 0
    07E2 1C03 BTFSS STATUS, 0
    07E3 2FE7 GOTO 0x7e7
    07E4 0022 MOVLB 0x2
    07E5 168C BSF PORTA, 0x5
    07E6 2FE9 GOTO 0x7e9
    07E7 0022 MOVLB 0x2
    07E8 128C BCF PORTA, 0x5
    37:
    38: LATA ^= (1 << LED1);
    07E9 3020 MOVLW 0x20
    07EA 00F7 MOVWF 0x77
    07EB 0877 MOVF 0x77, W
    07EC 068C XORWF PORTA, F
    #12
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/09/03 22:22:30 (permalink)
    0
    Here's one more:
     
    39:
    40: if (LAT_LED1)
    07E8 1E8C BTFSS PORTA, 0x5
    07E9 2FEC GOTO 0x7ec
    41: LAT_LED1 = 0;
    07EA 128C BCF PORTA, 0x5
    07EB 2FED GOTO 0x7ed
    42: else
    07EC 168C BSF PORTA, 0x5
    43: LAT_LED1 = 1;
    #13
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/09/03 22:49:16 (permalink)
    0
    ... and the winner is (without going ASM):
     
    44:
    45: LATA = LATA ^ (1 << LED1);
    07EA 080C MOVF PORTA, W
    07EB 3A20 XORLW 0x20
    07EC 008C MOVWF PORTA

    I would had thought LATA ^= (1 << LED1); take two instruction. :(
     
     
     
    #14
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Toggle a LED 2016/09/03 23:06:50 (permalink)
    0
    XC8 1.34 Pro mode.
    #1
    LATCbits.LATC5 ^= 1;
      3943  0CD5  3020                movlw 32
      3944  0CD6  068E                xorwf 14,f

    #2
    LATCbits.LATC5 = !LATCbits.LATC5;
      3947  0CD7  1003                clrc
      3948  0CD8  1E8E                btfss 14,5 ;volatile
      3949  0CD9  1403                setc
      3950  0CDA  1C03                btfss 3,0
      3951  0CDB  2CDF                goto u1570
      3952  0CDC  0022                movlb 2 ; select bank2
      3953  0CDD  168E                bsf 14,5 ;volatile
      3954  0CDE  2CE1                goto l2127
      3955  0CDF                     u1570:
      3956  0CDF  0022                movlb 2 ; select bank2
      3957  0CE0  128E                bcf 14,5 ;volatile
      3958  0CE1                     l2127:

    #3
    LATCbits.LATC5=LATCbits.LATC5?0:1;
      3961  0CE1  1003                clrc
      3962  0CE2  1E8E                btfss 14,5 ;volatile
      3963  0CE3  1403                setc
      3964  0CE4  1C03                btfss 3,0
      3965  0CE5  2CE9                goto u1590
      3966  0CE6  0022                movlb 2 ; select bank2
      3967  0CE7  168E                bsf 14,5 ;volatile
      3968  0CE8  2CEB                goto l2129
      3969  0CE9                     u1590:
      3970  0CE9  0022                movlb 2 ; select bank2
      3971  0CEA  128E                bcf 14,5 ;volatile
      3972  0CEB                     l2129:

    #4
    if (LATCbits.LATC5)
      3975  0CEB  1E8E                btfss 14,5 ;volatile
      3976  0CEC  2CEF                goto l200
      3977                          
      LATCbits.LATC5 = 0;
      3979  0CED  128E                bcf 14,5 ;volatile
      3980  0CEE  2CF0                goto l201
      3981  0CEF                     l200:
      3982                          
      else
      LATCbits.LATC5 = 1;
      3985  0CEF  168E                bsf 14,5 ;volatile
      3986  0CF0                     l201:

    #5
    if (LATCbits.LATC5)
      3989  0CF0  1A8E                btfsc 14,5 ;volatile
      3990                          
    LATCbits.LATC5 = 0;
      3992  0CF1  128E                bcf 14,5 ;volatile
      3993                          
    if (!LATCbits.LATC5)
      3995  0CF2  1E8E                btfss 14,5 ;volatile
      3996                          
    LATCbits.LATC5 = 1;
      3998  0CF3  168E                bsf 14,5 ;volatile

     
    So #1 does it in two instructions, corrupting W.
    #5 does it in four instructions, but doesn't corrupt W (but who cares in C anyway...)
    #15
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/09/03 23:49:14 (permalink)
    0
    qhb
    XC8 1.34 Pro mode.
    So #1 does it in two instructions, corrupting W.
    #5 does it in four instructions, but doesn't corrupt W (but who cares in C anyway...)

    I'm surprised (disappointed) PRO mode does not do most of those in two instructions. And #5 does not do the same toggle. ;)
    #16
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Toggle a LED 2016/09/04 00:01:05 (permalink)
    0
    1and0
    ...
    I'm surprised (disappointed) PRO mode does not do most of those in two instructions.

    Me too. I wouldn't take much effort to add these cases to their templates

    And #5 does not do the same toggle. ;)

    Agreed. I was remembering the most efficient way to copy a GP RAM bit to a pin. It doesn't work for toggling a pin.
    #17
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Toggle a LED 2016/09/04 00:06:59 (permalink)
    0
    and even in PRO mode
    LATA ^= (1 << LED1);

    still takes three instructions, when it could be done in two. That would be another simple optimisation.
    I wonder if LATA being volatile forces it do to a read and a write.
     
    Edit. The above is wrong. I must have tested "LATA = LATA ^ (1 << LED1);"
    which does produce three instructions, caused by the "volatile" qualifier.
     
     
    post edited by qhb - 2016/09/04 02:04:26
    #18
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/09/04 00:07:10 (permalink)
    0
    Thank you for posting the PRO code. That's pathetic for a $1000 super-optimized C compiler!
     
    #19
    1and0
    Access is Denied
    • Total Posts : 12079
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Toggle a LED 2016/09/04 00:22:24 (permalink)
    0
    qhb
    I wonder if LATA being volatile forces it do to a read and a write.

    Maybe. Could you post the disassembly replacing LATC5 with a regular SRAM bit 5?
     
    <edit> However, it does not bother to read and write for 
     LATCbits.LATC5 ^= 1;

    I wonder what PRO does with 
     LATCbits.LATC5 = LATCbits.LATC5 ^ 1;

    post edited by 1and0 - 2016/09/04 00:34:46
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2021 APG vNext Commercial Version 4.5