;-------------------------------------------
; EEPROM SUBROUTINES
;
; LAST MODIFIED: 17.04.2002
;
; DISCLAIMER:
; This software is provided "as is" for evaluation of our MSP430-1121STK
; development board. You are free to use this code in your projects, but 
; without warranty of any kind. If you can't understand how and what the 
; code does it's better to start by learning the MSP430 datasheets, and 
; assembly language, but don't call OLIMEX with questions regarding this 
; software. OLIMEX will not teach you how to write assembly language nor 
; how to use MSP430 peripherials, there is plenty of datasheets about them.
;
; (C) 2002 OLIMEX Ltd, All rights reserved
;-------------------------------------------------------------------------

#define     INDEX     R6                    /* INDEX variable               */
#define     EEADDR    R9                    /* EEPROM ADDRESS REGISTER      */
#define     TEMP      R11                   /* ISR REGISTER temporary vars  */

EEBYTE      db      1                       ;EEPROM working byte
EEOFSET     db      1                       ;EEPROM control byte
EEDATA      db      1                       ;EEPROM data
EECNTR      db      1                       ;EEPROM bit counter
EEPGCNTR    db      1                       ;EEPROM page write counter

#define     EE_OK   BIT7,EEOFSET            /* EEPROM OK FLAG               */

;--------------------------------------------
; EEPROM routines                              
;--------------------------------------------
EE_pg_write mov.b   #8Bh,EEOFSET            ;page byte write
            jmp     EE_init_wr              ;
;--------------------------------------------
EE_pg_open  mov.b   #89h,EEOFSET            ;Page write sequence
            jmp     EE_init                 ;
;--------------------------------------------
EE_write    mov.b   #80h,EEOFSET            ;Write command sequence
            jmp     EE_init                 ;
;--------------------------------------------
EE_read     mov.b   #84h,EEOFSET            ;Read command sequence
;--------------------------------------------
EE_init     mov.b   #0A0h,EEBYTE            ;
EE_start    bic.b   #SDAOUT                 ;Start condition SCL=1,SDA=0
EE_prep     mov.b   #P2SDAOUT,&P2DIR        ;
            mov.b   #8,EECNTR               ;
EE_out      bic.b   #SCL                    ;SCL=0
            rla.b   EEBYTE                  ;set SDA
            jnc     EE_noset                ;
            bis.b   #SDAOUT                 ;
            jmp     EE_1                    ;
EE_noset    bic.b   #SDAOUT                 ;
EE_1        bis.b   #SCL                    ;SCL=1
            nop                             ;
            nop                             ;
            nop                             ;
            nop                             ;
            dec.b   EECNTR                  ;
            jnz     EE_out                  ;
            bic.b   #SCL                    ;SCL=0
            mov.b   #P2SDAIN,&P2DIR         ;SDA=input            
            nop                             ;delay to pull up SDA
            nop                             ;
            nop                             ;
            nop                             ;
            bis.b   #SCL                    ;
            bit.b   #SDAIN                  ;check SDA for acknowledge
            jz      EE_ack                  ;
            bic.b   #EE_OK                  ;     
EE_ack      bic.b   #SCL                    ;release the bus
            bit.b   #EE_OK                  ;
            jz      EE_stop                 ;
            mov.b   EEOFSET,INDEX           ;
            and.w   #000Fh,INDEX            ;
            rla.w   INDEX                   ;
            br      JTBL(INDEX)             ;
JTBL        dw      EE_initHi               ;high address  0
            dw      EE_initLo               ;low address   1
            dw      EE_init_wr              ;write data    2
            dw      EE_stop_wr              ;stop bit      3
            dw      EE_initHi               ;high address  4
            dw      EE_initLo               ;low address   5
            dw      EE_init_rd              ;read data cmd 6
            dw      EE_read_bit             ;read data     7
            dw      EE_stop                 ;stop bit      8
            dw      EE_initHi               ;high address  9
            dw      EE_initLo               ;low address   A
            dw      EE_page_opened          ;page opened   B
            dw      EE_pgwrdone             ;page wr done  C
;--------------------------------------------
EE_initHi   inc.b   EEOFSET                 ;send HI address
            swpb    EEADDR                  ;
            mov.b   EEADDR,EEBYTE           ;
            swpb    EEADDR                  ;
            jmp     EE_prep                 ;
;--------------------------------------------
EE_initLo   inc.b   EEOFSET                 ;send LO address
            mov.b   EEADDR,EEBYTE           ;
            jmp     EE_prep                 ;
;--------------------------------------------
EE_init_wr  inc.b   EEOFSET                 ;send WRITE data
            mov.b   EEDATA,EEBYTE           ;
            jmp     EE_prep                 ;
;--------------------------------------------
EE_init_rd  bis.b   #SCL                    ;
            inc.b   EEOFSET                 ;
            mov.b   #0A1h,EEBYTE            ;
            jmp     EE_start                ;
;--------------------------------------------
EE_read_bit mov.b   #8,EECNTR               ;
EE_in       bis.b   #SCL                    ;
            setc                            ;
            bit.b   #SDAIN                  ;
            jnz     EE_hi                   ;
            clrc                            ;
EE_hi       rlc.b   EEDATA                  ;
            bic.b   #SCL                    ;
            dec.b   EECNTR                  ;
            jnz     EE_in                   ;
;--------------------------------------------
EE_stop     bic.b   #SDAOUT                 ;
            mov.b   #P2SDAOUT,&P2DIR        ;
            bis.b   #SCL                    ;
            nop                             ;
            bis.b   #SDAOUT                 ;
            bit.b   #EE_OK                  ;
            jz      EE_err                  ;
            ret                             ;
;--------------------------------------------
EE_stop_wr  bic.b   #SDAOUT                 ;
            mov.b   #P2SDAOUT,&P2DIR        ;
            bis.b   #SCL                    ;
            nop                             ;
            bis.b   #SDAOUT                 ;
            bit.b   #EE_OK                  ;
            jz      EE_err                  ;
            mov.w   #01000h,INDEX           ;
write_dly                                   ;
            dec.w   INDEX                   ;
            jnz     write_dly               ;
            ret                             ;
;--------------------------------------------
EE_page_opened                              ;page write is initialized
            mov.b   #0,EEPGCNTR             ;
            ret                             ;
;--------------------------------------------
EE_pgwrdone inc.b   EEPGCNTR                ;page write byte done
            ret                             ;
;--------------------------------------------
EE_err      bic.b   #LED_RED                ;
            call    #Delay                  ;
            bis.b   #LED_RED                ;
            call    #Delay                  ;
            jmp     EE_err                  ;
;--------------------------------------------