Why does this trivial program not work?

Corona688
2006-12-30
2013-03-12
  • Corona688
    Corona688
    2006-12-30

    ----SOURCE FILE----
    #define __16f628
    #include "pic/pic16f628a.h"
    typedef unsigned int    Uint16;

    // Set the __CONFIG word:
    Uint16 at 0x2007  __CONFIG = CONFIG_WORD;

    #define VREF_PIN        2       // Pin 2 of Port A.  This is hardwired.
    #define INPUT_PIN       3       // Pin 3 of Port A.  We chose this.
    #define OUTPUT_PIN      0       // Pin 1 of Port A.  We chose this.

    #define GET_BIT(X)              (1<<(X))
    #define MASK_BIT(X)             ~GET_BIT(X)
    #define SET_BIT(PORT,BIT)       PORT|=GET_BIT(BIT)
    #define CLEAR_BIT(PORT,BIT)     PORT&=~GET_BIT(BIT)

    #define IS_SET(PORT,BIT)        ((PORT)&GET_BIT(BIT))
    #define NOT_SET(PORT,BIT)       (!IS_SET(PORT,BIT))

    static void main(void)
    {
            TRISA=GET_BIT(VREF_PIN)|GET_BIT(INPUT_PIN);     // These two are inputs.
            TRISB=0x00;     // All outputs

            while(1)
            {
                    if(IS_SET(PORTA, INPUT_PIN))
                            SET_BIT(PORTA,OUTPUT_PIN);
                    else
                            CLEAR_BIT(PORTA,OUTPUT_PIN);
            }
    }
    ---RESULTING ASM----
    ;--------------------------------------------------------
    ; File Created by SDCC : FreeWare ANSI-C Compiler
    ; Version 2.5.6 # (Dec 23 2006)
    ; This file generated Sat Dec 30 16:57:12 2006
    ;--------------------------------------------------------
    ; PIC port for the 14-bit core
    ;--------------------------------------------------------
    ;       .module 0008_vref
            list    p=16f628a
            radix dec
            include "p16f628a.inc"
    ;--------------------------------------------------------
    ; config word
    ;--------------------------------------------------------
            __config 0x3f63
    ;--------------------------------------------------------
    ; extern variables in this module
    ;--------------------------------------------------------
            extern _VRCON
            extern _EECON2
            extern _EECON1
            extern _EEADR
            extern _EEDATA
            extern _SPBRG
            extern _TXSTA
            extern _PR2
            extern _PCON
            extern _PIE1
            extern _TRISB
            extern _TRISA
            extern _OPTION_REG
            extern _CMCON
            extern _RCREG
            extern _TXREG
            extern _RCSTA
            extern _CCP1CON
            extern _CCPR1H
            extern _CCPR1L
            extern _T2CON
            extern _TMR2
            extern _T1CON
            extern _TMR1H
            extern _TMR1L
            extern _PIR1
            extern _INTCON
            extern _PCLATH
            extern _PORTB
            extern _PORTA
            extern _FSR
            extern _STATUS
            extern _TMR0
            extern _VRCON_bits
            extern _TXSTA_bits
            extern _T2CON_bits
            extern _T1CON_bits
            extern _STATUS_bits
            extern _RCSTA_bits
            extern _PIR1_bits
            extern _PIE1_bits
            extern _PCON_bits
            extern _OPTION_REG_bits
            extern _INTCON_bits
            extern _EECON1_bits
            extern _CMCON_bits
            extern _CCP1CON_bits
            extern _PCL
            extern _INDF
    ;--------------------------------------------------------
    ; publics variables in this module
    ;--------------------------------------------------------
    ;--------------------------------------------------------
    ; special function registers
    ;--------------------------------------------------------
    ;--------------------------------------------------------
    ; absolute symbol definitions
    ;--------------------------------------------------------

            global PSAVE
            global SSAVE
            global WSAVE
            global STK12
            global STK11
            global STK10
            global STK09
            global STK08
            global STK07
            global STK08
            global STK07
            global STK06
            global STK05
            global STK04
            global STK03
            global STK02
            global STK01
            global STK00
    sharebank udata_ovr 0x0070
    PSAVE   res 1
    SSAVE   res 1
    WSAVE   res 1
    STK12   res 1
    STK11   res 1
    STK10   res 1
    STK09   res 1
    STK08   res 1
    STK07   res 1

    STK08   res 1
    STK07   res 1
    STK06   res 1
    STK05   res 1
    STK04   res 1
    STK03   res 1
    STK02   res 1
    STK01   res 1
    STK00   res 1
    ;       .area   RSEG    (DATA)
    ;--------------------------------------------------------
    ; udata
    ;--------------------------------------------------------
    data_0008_vref  udata
    ;       .area   DSEG    (DATA)
    ;--------------------------------------------------------
    ; overlayable items in internal ram
    ;--------------------------------------------------------
    ;       udata_ovr
    ;--------------------------------------------------------
    ; bit data
    ;--------------------------------------------------------
    ;       .area   BSEG    (BIT)
    ;--------------------------------------------------------
    ; reset vector
    ;--------------------------------------------------------
    STARTUP code
            nop
            goto    __sdcc_gsinit_startup
    code_init       code
    __sdcc_gsinit_startup
            pagesel _main
            goto _main
    ;--------------------------------------------------------
    ; code
    ;--------------------------------------------------------
    code_0008_vref  code
    ;***
    ;  pBlock Stats: dbName = M
    ;***
    ;entry:  _main  ;Function start
    ; 2 exit points
    ;has an exit
    ;; Starting pCode block
    _main   ;Function start
    ; 2 exit points
    ;       .line   31; "0008-vref.c"       TRISA=GET_BIT(VREF_PIN)|GET_BIT(INPUT_PIN);
            MOVLW   0x0c
            BSF     STATUS,5
            BCF     STATUS,6
            MOVWF   _TRISA
    ;       .line   32; "0008-vref.c"       TRISB=0x00;     // All outputs
            CLRF    _TRISB
    _00109_DS_
    ;       .line   41; "0008-vref.c"       if(IS_SET(PORTA, INPUT_PIN))
            BCF     STATUS,5
            BTFSS   _PORTA,3
            GOTO    _00106_DS_
    ;       .line   42; "0008-vref.c"       SET_BIT(PORTA,OUTPUT_PIN);
            BSF     _PORTA,0
            GOTO    _00109_DS_
    _00106_DS_
    ;       .line   44; "0008-vref.c"       CLEAR_BIT(PORTA,OUTPUT_PIN);
            BCF     _PORTA,0
            GOTO    _00109_DS_
            RETURN
    ; exit point of _main

    ;       code size estimation:
    ;          13+    0 =    13 instructions (   26 byte)

            end
    --------

    So the program compiles fine, etc.  But when I twiddle INPUT_PIN, nothing happens -- OUTPUT_PIN just stays set at 0.  Even when I *reset* with INPUT_PIN held high, OUTPUT_PIN just outputs 0.  What gives?

     
    • Corona688
      Corona688
      2006-12-30

      Upgraded to SDCC 2.6.0, to no effect.  This trivial program stil does not work.  I suspect missing BANKSELs and the like.

       
    • Corona688
      Corona688
      2006-12-31

      Attempting to build sdcc SVN, it doesn't even compile:

      make[1]: Entering directory `/var/tmp/portage/sdcc-svn-2.5.0/work/sdcc-svn-2.5.0/src'
      Makefile:10: ..Makefile.common: No such file or directory
      Makefile:99: Makefile.dep: No such file or directory
      f ./version.awk ../ChangeLog > version.h
      /bin/sh: f: command not found
      make[1]: [version.h] Error 127 (ignored)
      yacc -d -v -o SDCCy.c SDCC.y
      lex -t SDCC.lex >SDCClex.c
      make[1]: *** No rule to make target `/SDCCerr.c', needed by `Makefile.dep'.  Stop.
      make[1]: Leaving directory `/var/tmp/portage/sdcc-svn-2.5.0/work/sdcc-svn-2.5.0/src'
      make: *** [sdcc-cc] Error 2

       
    • Corona688
      Corona688
      2006-12-31

      SOLUTION!  My program needed this line:

      CMCON = 0x07;           // Disable comparators.

      Apparently, PORTA is *not* configured to work normally by default -- you have to turn things OFF to get normal PORTA behavior in the pic16f628a!  Bizzare.