Massimo Spataro - 2009-08-01

This Versione of Sdcc

$ sdcc -v
SDCC : avr/pic16/pic14/xa51 2.8.0 #5117 (Jun  2 2008) (UNIX)

i have check this code and problem with 12F683

When compile code for Pic MicroChip i have check not correct generation of code and bad signal on output to GPIO port. Below i have insert code bad and generate asm code from sdcc and next to this section i have insert patch for correct run signal on GP1 port.

I have read manual of 12F683 on asm code for check where is problem but i have think only one problem with alignment of code when test BTFSC instruction and jump for test condiction not true.

this is bad ( GP1 isn't down )

    BTFSC    STATUS,0
    GOTO    _00164_DS_
    .line    287; "max7219.c"    CLK_0();
    BCF    _GPIO_bits,1

This is Correct ( GP1 is down after test of status false )

    BTFSC    STATUS,0
    GOTO    _00164_DS_
    .line    287; "max7219.c"    CLK_0();
    NOP                  <----- alignment jump problem of PIC?????
    BCF    _GPIO_bits,1

Bad code "C" and asm

void MAX7219_SendByte (unsigned char udata )
{
      uchar i, mask = 0x80;        // loop and mask test bit

    for (i = 0; i < 8; i++)
    {
        CLK_0();               // bring CLK low Line GP1
                                              
            if (udata & mask) {    // serialize first MSB
            DATA_1();      // Data out on GP0
        }
        else {
            DATA_0();     // output one data   
        }
            CLK_1();       
        udata <<= 1;          // shift data for next bit out
    }
}

_MAX7219_SendByte    ;Function start
    .line    280; "max7219.c"    void MAX7219_SendByte (unsigned char udata )
    BANKSEL    r0x1000
    MOVWF    r0x1000
    .line    284; "max7219.c"    for (i = 0; i < 8; i++)
    CLRF    r0x1001
_00160_DS_
    MOVLW    0x08
    BANKSEL    r0x1001
    SUBWF    r0x1001,W
    BTFSC    STATUS,0
    GOTO    _00164_DS_
    .line    287; "max7219.c"    CLK_0();
    BCF    _GPIO_bits,1
    .line    289; "max7219.c"    if (udata & mask) {
    BANKSEL    r0x1000
    BTFSS    r0x1000,7
    GOTO    _00158_DS_
    .line    290; "max7219.c"    DATA_1();
    BANKSEL    _GPIO_bits
    BSF    _GPIO_bits,0
    GOTO    _00159_DS_
_00158_DS_
    .line    293; "max7219.c"    DATA_0();     // output one data   
    BANKSEL    _GPIO_bits
    BCF    _GPIO_bits,0
_00159_DS_
    .line    295; "max7219.c"    CLK_1();
    BANKSEL    _GPIO_bits
    BSF    _GPIO_bits,1
    .line    296; "max7219.c"    udata <<= 1;
    BCF    STATUS,0
    BANKSEL    r0x1000
    RLF    r0x1000,F
    .line    284; "max7219.c"    for (i = 0; i < 8; i++)
    INCF    r0x1001,F
    GOTO    _00160_DS_
_00164_DS_
    RETURN   

My correction of code on "C" and asm code generate

void MAX7219_SendByte (unsigned char udata )
{
      uchar i, mask = 0x80;        // loop and mask test bit

    for (i = 0; i < 8; i++)
    {
        _asm
          NOP            // dummy for correct alignment problem of Pic??????
        _endasm;

        CLK_0();               // bring CLK low Line GP1
                                              
            if (udata & mask) {    // serialize first MSB
            DATA_1();      // Data out on GP0
        }
        else {
            DATA_0();     // output one data   
        }
            CLK_1();       
        udata <<= 1;          // shift data for next bit out
    }
}

_MAX7219_SendByte    ;Function start
    .line    280; "max7219.c"    void MAX7219_SendByte (unsigned char udata )
    BANKSEL    r0x1000
    MOVWF    r0x1000
    .line    284; "max7219.c"    for (i = 0; i < 8; i++)
    CLRF    r0x1001
_00160_DS_
    MOVLW    0x08
    BANKSEL    r0x1001
    SUBWF    r0x1001,W
    BTFSC    STATUS,0
    GOTO    _00164_DS_
    .line    287; "max7219.c"    CLK_0();
    NOP
    BCF    _GPIO_bits,1
    .line    289; "max7219.c"    if (udata & mask) {
    BANKSEL    r0x1000
    BTFSS    r0x1000,7
    GOTO    _00158_DS_
    .line    290; "max7219.c"    DATA_1();
    BANKSEL    _GPIO_bits
    BSF    _GPIO_bits,0
    GOTO    _00159_DS_
_00158_DS_
    .line    293; "max7219.c"    DATA_0();     // output one data   
    BANKSEL    _GPIO_bits
    BCF    _GPIO_bits,0
_00159_DS_
    .line    295; "max7219.c"    CLK_1();
    BANKSEL    _GPIO_bits
    BSF    _GPIO_bits,1
    .line    296; "max7219.c"    udata <<= 1;
    BCF    STATUS,0
    BANKSEL    r0x1000
    RLF    r0x1000,F
    .line    284; "max7219.c"    for (i = 0; i < 8; i++)
    INCF    r0x1001,F
    GOTO    _00160_DS_
_00164_DS_
    RETURN