; EEPROM.asm
;
; Writes a character to EEPROM location 0.  Reads it and displays to the LCD.
;
;     WRITE_EE - writes what is in DAT to the address specified in ADR
;     READ_EE  - reads from address ADR into DAT  
;
;     SER_INIT - brings PORTC, 6 to output one - idle
;     SER_CHAR - outputs the content of W at 9600 baud
;
;     DELAY_SECS
;     DELAY_MS
;     DELAY_10US
;
;Peter H. Anderson, Mar 31, '08
;corrected error in READ_EE, Apr 10, '08

    LIST p=16f887
#include <p16f887.inc>   

    __CONFIG    _CONFIG1, 0x28e4
    __CONFIG    _CONFIG2, 0x3eff


DAT	EQU 0x30
ADR	EQU 0x31


NUM_SECS    EQU 0x70   
NUM_MS      EQU 0x71   
NUM_10US    EQU 0x72

_CH        EQU 0x73
_NUM_BITS  EQU 0x74
_DLY       EQU 0x75

    ORG 0x000    ;program code to start at 000H

    BSF STATUS, 5        ; switch to bank 1 and               
    MOVLW 0x61   
    MOVWF OSCCON        ; internal clock, 4 MHz
    BCF STATUS, 5
    
    CALL SER_INIT

                          
TOP:       


    MOVLW '?'
    CALL SER_CHAR
    MOVLW 'f'
    CALL SER_CHAR

    MOVLW '!'	; write something to EEPROM
    MOVWF DAT
    MOVLW 0x80
    MOVWF ADR
    CALL WRITE_EE
    MOVLW .250
    CALL DELAY_MS

    MOVLW 0x80
    MOVWF ADR
    CALL READ_EE
    MOVF DAT, W
    CALL SER_CHAR

DONE:
    GOTO DONE

WRITE_EE:
    BANKSEL DAT
    MOVF DAT, W
    BANKSEL EEDAT
    MOVWF EEDAT
    BANKSEL DAT
    MOVF ADR, W
    BANKSEL EEADR
    MOVWF EEADR
    BANKSEL EECON1
    BCF EECON1, EEPGD
    BSF EECON1, WREN
    MOVLW 0x55
    MOVWF EECON2
    MOVLW 0xaa
    MOVWF EECON2
    BSF EECON1, WR
    BANKSEL DAT
    MOVLW .30
    CALL DELAY_MS
    BANKSEL EECON1
    BCF EECON1, WREN
    BANKSEL DAT
    RETURN

READ_EE
    BANKSEL ADR
    MOVF ADR, F
    BANKSEL EEADR ; //////////////////// 
    MOVWF EEADR   ; ///// Apr 9, '08
    BANKSEL EECON1
    BCF EECON1, EEPGD
    BSF EECON1, RD
    BANKSEL EEDAT
    MOVF EEDAT, W
    BANKSEL DAT
    MOVWF DAT
    RETURN

                          
                   
SER_INIT:
    BSF STATUS, 5
    BCF TRISC, 6
    BCF STATUS, 5
    BSF PORTC, 6
    MOVLW .250
    CALL DELAY_MS
    RETURN

SER_CHAR:
                         ; 9600 TTL,
    MOVWF _CH
    MOVLW .9
    MOVWF _NUM_BITS

    BCF STATUS, C

SER_CHAR_1:

    BTFSS STATUS, C
    BCF PORTC, 6
    BTFSC STATUS, C
    BSF PORTC, 6
    MOVLW .32
    MOVWF _DLY

SER_CHAR_2:
    DECFSZ _DLY, F
    GOTO SER_CHAR_2
    RRF _CH, F
    DECFSZ _NUM_BITS, F
    GOTO SER_CHAR_1

  
    BSF PORTC, 6  ; stop bit
    MOVLW .100
    MOVWF _DLY

SER_CHAR_3:
    DECFSZ _DLY, F 
    GOTO SER_CHAR_3
  
    RETURN

DELAY_SECS:
    MOVWF NUM_SECS
DELAY_SECS_1:
    MOVLW .250
    CALL DELAY_MS
    MOVLW .250
    CALL DELAY_MS
    MOVLW .250
    CALL DELAY_MS
    MOVLW .250
    CALL DELAY_MS
    DECFSZ NUM_SECS, F
    GOTO DELAY_SECS_1
    RETURN
 
DELAY_MS:        ; delay.  number of ms passed in W
     MOVWF NUM_MS
DELAY_MS_1:       
    MOVLW .100    
    CALL DELAY_10US
   
    DECFSZ NUM_MS, F
    GOTO DELAY_MS_1
    RETURN

DELAY_10US:        ; delay.  number of 10us passed in W
    MOVWF NUM_10US   
DELAY_10US_1:   
    CLRWDT    ; 7 ~
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    DECFSZ NUM_10US, F
    GOTO DELAY_10US_1
    RETURN
                     
    END