*/
Love this site? Hate it? Leave us some comments.
*/

View \I2CINIT.ASM

Lets 8xC751 do system init of I2C and

Submitted By: WEBMASTER
Rating: (Not rated) (Rate It)


;*****************************************************************************

;            I2C Peripheral Initialization Program for the 83C751

; This program first provides a positive going reset pulse on port pins P3.4
; and P3.3, and a negative going reset pulse on port pins P3.2 and P3.1 to
; allow any system devices requiring a reset pulse to be initialized. The
; reset pulse width will be about 250 ms (when running at 12 MHz). Then, after
; about a 100 ms delay, the program will send out one or more I2C messages
; (from a table) to allow I2C devices to be initialized with specific data.
; The table is located at the end of the program at address 0200 hexadecimal.

;*****************************************************************************

$TITLE(83C751 I2C Peripheral Initialization Program)
$DATE(11/28/89)
$MOD751
$DEBUG


; Value definitions.

CTVAL      EQU     02h                 ;CT1, CT0 bit values for I2C.


; Masks for I2CFG bits.

BTIR      EQU     10h                 ;Mask for TIRUN bit.
BMRQ      EQU     40h                 ;Mask for MASTRQ bit.


; Masks for I2CON bits.

BCXA      EQU     80h                 ;Mask for CXA bit.
BIDLE      EQU     40h                 ;Mask for IDLE bit.
BCDR      EQU     20h                 ;Mask for CDR bit.
BCARL      EQU     10h                 ;Mask for CARL bit.
BCSTR      EQU     08h                 ;Mask for CSTR bit.
BCSTP      EQU     04h                 ;Mask for CSTP bit.
BXSTR      EQU     02h                 ;Mask for XSTR bit.
BXSTP      EQU     01h                 ;Mask for XSTP bit.


; RAM locations used by I2C routines.

BitCnt     DATA    21h                 ;I2C bit counter.
ByteCnt    DATA    22h
SlvAdr     DATA    23h                 ;Address of active slave.
SubAdr     DATA    24h

CmdSav     DATA    25h                 ;Saves last command byte.
PtrSav     DATA    26h                 ;Saves starting index for last command.
StackSave  DATA    27h                 ;Saves stack address for bus recovery.

Flags      DATA    20h                 ;I2C software status flags.
NoAck      BIT     Flags.0             ;Indicates missing acknowledge.
Fault      BIT     Flags.1             ;Indicates a bus fault of some kind.
Retry      BIT     Flags.2             ;Indicates that last I2C transmission
                                       ;  failed and should be repeated.

SCL        BIT     P0.0                ;Port bit for I2C serial clock line.
SDA        BIT     P0.1                ;Port bit for I2C serial data line.

PosRst1    BIT     P3.4                ;Port pin for 1st positive reset pulse.
PosRst2    BIT     P3.3                ;Port pin for 2nd positive reset pulse.
NegRst1    BIT     P3.2                ;Port pin for 1st negative reset pulse.
NegRst2    BIT     P3.1                ;Port pin for 2nd negative reset pulse.

;*****************************************************************************
;                                Begin Code
;*****************************************************************************

; Reset and interrupt vectors.

           AJMP    Reset               ;Reset vector at address 0.


; A timer I timeout usually indicates a 'hung' bus.

           ORG     1Bh                 ;Timer I (I2C timeout) interrupt.
TimerI:    SETB    CLRTI               ;Clear timer I interrupt.
           CLR     TIRUN
           ACALL   ClrInt              ;Clear interrupt pending.
           MOV     SP,StackSave        ;Restore stack for return to main.
           AJMP    Recover             ;Attempt bus recovery.
ClrInt:    RETI


;*****************************************************************************
;                    Main Transmit and Receive Routines
;*****************************************************************************

; Send data byte(s) to slave.
;   Enter with slave address in SlvAdr, data in XmtDat buffer, # of data
;   bytes to send in ByteCnt.

SendData:  CLR     NoAck               ;Clear error flags.
           CLR     Fault
           CLR     Retry
           MOV     StackSave,SP        ;Save stack address for bus fault.
           MOV     A,SlvAdr            ;Get slave address.
           ACALL   SendAddr            ;Get bus and send slave address.
           JB      NoAck,SDEX          ;Check for missing acknowledge.
           JB      Fault,SDatErr       ;Check for bus fault.

SDLoop:    ACALL   GetNext             ;Get next data byte for slave.
           ACALL   XmitByte            ;Send data to slave.
           JB      NoAck,SDEX          ;Check for missing acknowledge.
           JB      Fault,SDatErr       ;Check for bus fault.
           DJNZ    ByteCnt,SDLoop

SDEX:      ACALL   SendStop            ;Send an I2C stop.
           RET


; Handle a transmit bus fault.

SDatErr:   AJMP    Recover             ;Attempt bus recovery.


;*****************************************************************************
;                               Subroutines
;*****************************************************************************

; Send address byte.
;   Enter with address in ACC.

SendAddr:  MOV     I2CFG,#BMRQ+BTIR+CTVAL ;Request I2C bus.
           JNB     ATN,$               ;Wait for bus granted.
           JNB     Master,SAErr        ;Should have become the bus master.
           MOV     I2DAT,A             ;Send first bit, clears DRDY.
           MOV     I2CON,#BCARL+BCSTR+BCSTP ;Clear start, releases SCL.
           ACALL   XmitAddr            ;Finish sending address.
           RET

SAErr:     SETB    Fault               ;Return bus fault status.
           RET


; Byte transmit routine.
;   Enter with data in ACC.
;   XmitByte : transmits 8 bits.
;   XmitAddr : transmits 7 bits (for address only).

XmitAddr:  MOV     BitCnt,#8           ;Set 7 bits of address count.
           SJMP    XmBit2

XmitByte:  MOV     BitCnt,#8           ;Set 8 bits of data count.
XmBit:     MOV     I2DAT,A             ;Send this bit.
XmBit2:    RL      A                   ;Get next bit.
           JNB     ATN,$               ;Wait for bit sent.
           JNB     DRDY,XMErr          ;Should be data ready.
           DJNZ    BitCnt,XmBit        ;Repeat until all bits sent.
           MOV     I2CON,#BCDR+BCXA    ;Switch to receive mode.
           JNB     ATN,$               ;Wait for acknowledge bit.
           JNB     RDAT,XMBX           ;Was there an ack?
           SETB    NoAck               ;Return no acknowledge status.
XMBX:      RET

XMErr:     SETB    Fault               ;Return bus fault status.
           RET


; I2C stop routine.

SendStop:  CLR     MASTRQ              ;Release bus mastership.
           MOV     I2CON,#BCDR+BXSTP   ;Generate a bus stop.
           JNB     ATN,$               ;Wait for atn.
           MOV     I2CON,#BCDR         ;Clear data ready.
           JNB     ATN,$               ;Wait for stop sent.
           MOV     I2CON,#BCARL+BCSTP+BCXA ;Clear I2C bus.
           CLR     TIRUN               ;Stop timer I.
           RET


; Bus fault recovery routine.

Recover:   ACALL   FixBus              ;See if bus is dead or can be 'fixed'.
           JC      BusReset            ;If not 'fixed', try extreme measures.
           SETB    Retry               ;If bus OK, return to main routine.
           CLR     Fault
           CLR     NoAck
           SETB    CLRTI
           SETB    TIRUN               ;Enable timer I.
           SETB    ETI                 ;Turn on timer I interrupts.
           RET


; This routine tries a more extreme method of bus recovery.
;   This is used if SCL or SDA are stuck and cannot otherwise be freed.
;   (will return to the Recover routine when Timer I times out)

BusReset:  CLR     MASTRQ              ;Release bus.
           MOV     I2CON,#0BCh         ;Clear all I2C flags.
           SETB    TIRUN
           SJMP    $                   ;Wait for timer I timeout (this will
                                       ;  reset the I2C hardware).


; This routine attempts to regain control of the I2C bus after a bus fault.
;   Returns carry clear if successful, carry set if failed.

FixBus:    CLR     MastRQ              ;Turn off I2C functions.
           SETB    C
           SETB    SCL                 ;Insure I/O port is not locking I2C.
           SETB    SDA
           JNB     SCL,FixBusEx        ;If SCL is low, bus cannot be 'fixed'.
           JB      SDA,RStop           ;If SCL & SDA are high, force a stop.
           MOV     BitCnt,#9           ;Set max # of tries to clear bus.
ChekLoop:  CLR     SCL                 ;Force an I2C clock.
           ACALL   SDelay
           JB      SDA,RStop           ;Did it work?
           SETB    SCL
           ACALL   SDelay
           DJNZ    BitCnt,ChekLoop     ;Repeat clocks until either SDA clears
                                       ;  or we run out of tries.
           SJMP    FixBusEx            ;Failed to fix bus by this method.

RStop:     CLR     SDA                 ;Try forcing a stop since SCL & SDA
           ACALL   SDelay              ;  are both high.
           SETB    SCL
           ACALL   SDelay
           SETB    SDA
           ACALL   SDelay
           JNB     SCL,FixBusEx        ;Are SCL & SDA still high? If so,
           JNB     SDA,FixBusEx        ;  assume bus is now OK, and return
           CLR     C                   ;  with carry cleared.
FixBusEx:  RET


; Short delay routine (10 machine cycles).

SDelay:    NOP
           NOP
           NOP
           NOP
           NOP
           NOP
           NOP
           NOP
           RET


; Long delay routine (approx 250,000 machine cycles = 250 ms @12MHz).

LDelay:    MOV     R6,A
           MOV     R7,#250
LD1:       NOP
           NOP
           DJNZ    R7,LD1              ;250 x 4 cycles = 1 msec (@12MHz).
           DJNZ    R6,LD1              ;approx. 250 msec (@12MHz)
           RET


; This routine gets the next command/data byte from the command table.
;   Returns data in ACC.
;   Note: The table length can be 256 bytes maximum, due to the way this
;   routine is written.

GetNext:   MOV     A,R0                ;Set offset into table.
           MOV     DPTR,#CmdTab        ;Set table start address.
           MOVC    A,@A+DPTR           ;Get table entry
           INC     R0
           RET


;*****************************************************************************
;                               Main Program
;*****************************************************************************

Reset:     MOV     SP,#07h             ;Set stack location.
           SETB    ETI                 ;Enable timer I interrupts.
           SETB    EA                  ;Enable global interrupts.
           MOV     R0,#0               ;Set up initial command pointer.

           SETB    PosRst1             ;Assert 1st positive reset pulse.
           SETB    PosRst2             ;Assert 2nd positive reset pulse.
           CLR     NegRst1             ;Assert 1st negative reset pulse.
           CLR     NegRst2             ;Assert 2nd negative reset pulse.
           MOV     A,#250              ;Set for 250 msec delay.
           ACALL   LDelay              ;Wait.
           CLR     PosRst1             ;De-assert 1st positive reset pulse.
           CLR     PosRst2             ;De-assert 2nd positive reset pulse.
           SETB    NegRst1             ;De-assert 1st negative reset pulse.
           SETB    NegRst2             ;De-assert 2nd negative reset pulse.
           MOV     A,#100              ;Set for 100 msec delay.
           ACALL   LDelay              ;Wait.

MainLoop:  MOV     PtrSav,R0
           ACALL   GetNext             ;Get next command.
           JZ      Done                ;Found STOP command.
           MOV     ByteCnt,A           ;Set up byte count.
           ACALL   GetNext             ;Get slave address.
           MOV     SlvAdr,A            ;Set up slave address.
           ACALL   SendData            ;Send data to slave.
           SJMP    MainLoop

MainRetry: MOV     R0,PtrSav           ;Restore command pointer to retry.
           AJMP    MainLoop            ;Repeat last command.

Done:      MOV     PCON,#02h           ;Done, enter power down mode.
           NOP


; I2C INITIALIZATION DATA TABLE.

; Definition of data table contents:
; 1st byte = Command : 00 - Stop.
;                    : nonzero = data byte count (including subaddress).
; 2nd byte = Slave address.
; 3rd byte = First data byte or slave subaddress.
; 4th to last byte = Additional data bytes, if any.

           ORG     200h
CmdTab:    DB      01h,48h,55h                   ;1 data byte, no subaddr.
           DB      05h,74h,00h,0D0h,7Ah,63h,6Dh  ;4 data bytes, with subaddr.

           DB      0                             ;End of I2C data.

           END

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.