'****************************************************************
'*  Name    : 4 bit 7 segment display                           *
'*  Author  : RICHARD                                           *
'*  Notice  :                                                   *
'*          :                                                   *
'*  Date    : 18. 2. 2018                                       *
'*  Version : 1.0                                               *
'*  Notes   : CHIP MUST HAVE AUTO CONTEXT SAVE AND MSSP MODULE  *
'*  MCU     : PIC 12F1822 @32MHZ                                *
'****************************************************************
#CONFIG
  __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
  __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG

 goto overasm
ASM
   
seg_val 
    CHK?RP  _TM_TMP
    MOVWF   _TM_TMP
    SUBLW   0x21
    btfsc   STATUS, C
    retlw   0   ;" "
    MOVF    _TM_TMP,W
    SUBLW   0x2f
    btfsc   STATUS, C
    retlw   64   ;"-"
    MOVF    _TM_TMP,W
    MOVLW   0X40
    SUBWF   _TM_TMP,W
    btfsC   STATUS, C
    GOTO    TM_ALPHA
    MOVF    _TM_TMP,W
    ANDLW   0X0F
    GOTO    TM_LU
TM_ALPHA 
    ANDLW   0xdf    ;ucase
    SUBLW   6
    btfsS   STATUS, C
    retlw   0       ;ERROR
    MOVLW   0X37
    SUBWF   _TM_TMP,W
    ANDLW   0xdf    ;ucase
TM_LU     
    BRW                                         
    retlw 	0X3F    ;0   
    retlw 	6            	
    retlw 	0X5B   
    retlw 	0X4F 
    retlw 	0X66
    retlw 	0X6D                        
    retlw 	0X7D  
    retlw 	7   
    retlw 	0X7F          
    retlw 	0X67    ;9
    retlw 	0X77    ;A
    retlw 	0X7C    ;b
    retlw 	0X39    ;C
    retlw 	0X5E    ;d
    retlw 	0X79    ;E
    retlw 	0X71    ;F 
endasm 



overasm:

DEFINE OSC 32            ; Use internal clock 
ANSELA=0
SSP1CON1=$22  
SSP1STAT=$40
OSCCON=$70
DEFINE INTHAND   _DISP        ;COMMENT OUT IF DT_INTS USED


TRISA = %11111000
@LPORT=LATA 
LPIN CON 2     ;var LATa.2         ; Latch
DPIN var porta.0         ; Data  SDO
CPIN var porta.1         ; Clock SCK

segment var byte
value var word
d_index var byte
buff var byte[5]
seg_buff   var byte[4]
seg_cnt    var byte
seg_dat    var byte 
tmp var byte 
TM_TMP    var byte         
d_pointer      var byte  

timer1_reload con    33543  ;4mS
                       

PIR1.0=0                 ;COMMENT OUT IF DT_INTS USED
INTCON=$C0               ;COMMENT OUT IF DT_INTS USED
PIE1.0=1                 ;COMMENT OUT IF DT_INTS USED

d_index = 0                                  ;INITIALISE DISPLAY  INDEX
d_pointer = 1 ;USE 8 FOR REV DIR             ;INITIALISE DISPLAY  POINTER
T1CON = $1

;---[simple counter 0 - to ffff]------------------------------------------------ 
Main:
    for value = 0 to 65535
        arraywrite buff ,[HEX4 value,0]
        gosub load_seg
        pause 100
    next value
    value = 0
GOTO Main

load_seg :
    for seg_cnt=0 to 3
        seg_dat= buff[seg_cnt]
        asm
            MOVE?BA  _seg_dat 
            L?CALL seg_val
            MOVE?AB _seg_dat
        endasm
        seg_buff[seg_cnt]= seg_dat
    next
return




;---[TMR1 - interrupt handler]--------------------------------------------------
DISP:

asm
    MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
    MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the 
    ADDWF TMR1L,F ; 1 value in Timer1
    BTFSC STATUS,C ; 1/2
    INCF TMR1H,F ; 1
    MOVLW HIGH(_timer1_reload) ; 1
    ADDWF TMR1H,F ; 1
    MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
    ;GET THE SEGMENT DATA FROM SEG_BUFFER
    MOVE?CB  high _seg_buff, FSR0H         ;load highbyte 
    MOVE?CB  low  _seg_buff, FSR0L         ;load low byte
    MOVE?BA  _d_index  
    ADDWF  FSR0L,F
    MOVF   INDF0,W
    MOVE?AB _segment
    BANKSEL  LPORT       ;LOW LATCH
    BCF LPORT ,_LPIN
    BANKSEL PIR1
    BCF     PIR1,3 
    BANKSEL  _segment
    MOVF    _segment,W   ;COMMENT USED TO INVERT DATA FOR COMMON cathode DISPLAY
    ;COMF    _segment,W  ;COMMENT USED TO INVERT DATA FOR COMMON ANODE DISPLAY
    BANKSEL SSP1BUF
    movwf   SSP1BUF
    BANKSEL PIR1
    BTFSs   PIR1,3
    GOTO    $-1
    BANKSEL  _d_pointer    ;PICK WHICH DISP TO LIGHT UP
    COMF    _d_pointer,W   ;COMMENT USED FOR COMMON cathode DISPLAY
    ;MOVF    _d_pointer,W  ;COMMENT USED FOR COMMON ANODE DISPLAY
    BANKSEL PIR1
    BCF     PIR1,3 
    BANKSEL SSP1BUF
    movwf   SSP1BUF
    BANKSEL PIR1
    BTFSs   PIR1,3
    GOTO    $-1
    BANKSEL  LPORT
    BSF LPORT ,_LPIN         ;HIGH LATCH
    ;INC THE DIGIT INDEX
    BANKSEL  _d_index
    INCF  _d_index,F
    MOVLW 3 
    ANDWF  _d_index,F       ;LIMIT COUNT TO 0-3
    ;MOVE THE POINTER TO NEXT DISP
    BANKSEL   _d_pointer 
    BCF STATUS ,C        ;MAKE SURE WE SHIFTIN 0'S
    ;RRF    _d_pointer,F            ;REV DIR
    RLF    _d_pointer,F             ;FWD DIR
    ;BTFSS STATUS,C                 ;REV DIR
    BTFSS   _d_pointer,4            ;FWD DIR
    GOTO N_BIT
    ;MOVLW 8                        ;REV DIR
    MOVLW 1                         ;FWD DIR
    movwf _d_pointer
N_BIT
    ;INT_RETURN  ;UNCOMMENT IF DT_INTS USED
    BANKSEL PIR1      ;COMMENT OUT IF DT_INTS USED
    BCF PIR1   ,0     ;COMMENT OUT IF DT_INTS USED
    RETFIE            ;COMMENT OUT IF DT_INTS USED
endasm 




