*/
Want to see what people are talking about? See the latest forum posts.
*/

View \I2CDEMO.ASM

I2c evaluation board (part# s87c00k sd)

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


$title(SIGNETICS Evaluation Board Routine)
$date(8-mar-89)
$pagewidth(132)
$mod751
$debug
$object
;this is the code that went to signetics,not complete but emulates the
;old evaluation board. With cont now initialized!!!!
;
;************************************************************************
;                                                               *
;              This is the code for the SIGNETIC EVALUATION BOARD.    *
;              It is based on the code written        for the                 *
;              I2C EVALUATION BOARD 1987.                    *
;                                                               *
;              PHILIPS (NZ) LTD              G.D.MOSS              *
;                                                               *
;************************************************************************
;       This driver will make the board perform like the i2c evaluation
;       board. There are conditional statements to enable it to assemble
;       for any of the microcontrollers on the board.
;INTERNAL RAM ORGANIZATION
;       Internal memory varies from controller to controller, as does
;       the special function registers that are present.
;       LOCATION       USE        COMMENTS
;       255                top of ram 87C552, 87C652
;        :
;        63                top of ram 87C751, 87C752
;        :          user ram
;        :
;        32                32 to 47 are bit addressable
;        31
;        :          bank 3    free
;        :             8x8
;        24
;        23
;        :          bank 2    put the stack here
;        :          8x8    8 levels deep
;        16
;        15
;        :          bank 1    used by I2C routines
;        :          8x8
;         8
;         7
;        :          bank 0    for general use
;        :          8x8    during programme
;         0                operation
;
;SPECIAL FUNCTION REGISTERS
;       *      SFR that is bit addressable
;       #      SFR that is read only
;       -      SFR that is not on that chip
;       ADDRESS                87C51   87C552     87C652       87C751 87C752
;         ffh    - T3       -      -     -
;         feh    - PWMP     -    -   PWENA
;         fdh    - PWM1     -    -   -
;         fch    - PWM0     -    -   -
;         f8h    - IP1*     -    I2STA#      I2STA#
;         f0h    B*        B*      B*    B*  B*
;         efh    - RTE      -     -    -
;         eeh    - STE      -     -    -
;         edh    - TMH2#    -   -  -
;         ech    - TML2#    -   -  -
;         ebh    - CTCON    -   -  -
;         eah    - TM2CON   -  - -
;         e8h    - IEN1*    -   -  -
;         e0h    ACC*      ACC*  ACC*      ACC*  ACC*
;         dbh    - S1ADR    S1ADR       -      -
;         dah    - S1DAT    S1DAT       -      -
;         d9h    - S1STA#   S1STA#     -    -
;         d8h    - S1CON*   S1CON*     I2CFG*       I2CFG*
;         d0h    PSW*      PSW*  PSW*      PSW*  PSW*
;         cfh    - CTH3#    -   -  -
;         ceh    - CTH2#    -   -  -
;         cdh    - CTH1#    -   -  -
;         cch    - CTH0#    -   -  -
;         cbh    - CMH2     -    -   -
;         cah    - CMH1     -    -   -
;         c9h    - CMH0     -    -   -
;         c8h    - TM2IR*   -  - -
;         c6h    - ADCH     -    -   -
;         c5h    - ADCON    -   -  -
;         c4h    - P5#      -     -    -
;         c0h    - P4*      -     -    -
;         b8h    IP*       IP0*   IP*        -       -
;         b0h    P3*       P3*    P3* P3*      P3*
;         afh    - CTL3#    -   -  -
;         aeh    - CTL2#    -   -  -
;         adh    - CTL1#    -   -  -
;         ach    - CTL0#    -   -  -
;         abh    - CML2     -    -   -
;         aah    - CML1     -    -   -
;         a9h    - CML0     -    -   -
;         a8h    IE*       IEN0*  IE*       IE*    IE*
;         a0h    P2*       P2*    P2* -        ADCON*
;         99h    SBUF      S0BUF S0BUF    I2DAT       I2DAT
;         98h    SCON*     S0CON*       S0CON* I2CON*   I2CON*
;         90h    P1*       P1*    P1* P1*      P1*
;         8fh    - -        -       -      PWMP
;         8eh    - -        -       -      PWCM
;         8dh    TH1       TH1    TH1 RTH      RTH
;         8ch    TH0       TH0    TH0 TH       TH
;         8bh    TL1       TL1    TL1 RTL      RTL
;         8ah    TL0       TL0    TL0 TL       TL
;         89h    TMOD      TMOD  TMOD      -     -
;         88h    TCON*     TCON*        TCON*   TCON*      TCON*
;         87h    PCON      PCON  PCON      PCON  PCON
;         84h    - -        -       -      ADAT
;         83h    DPH       DPH    DPH DPH      DPH
;         82h    DPL       DPL    DPL DPL      DPL
;         81h    SP        SP      SP    SP  SP
;         80h    P0*       P0*    P0* P0*      P0*
;
;DEFINE REGISTER USAGE
;       bank 0
;       R0     general purpose pointer into the ram
;       R1     points into transfer buffer
;       R2     loop counter,general purpose 
;       R3     general purpose                 
;       R4     free    
;       R5     program control byte  
;              bits 1,0   4 mode counter
;       R6     switch data
;       R7     free
;
;       bank 1 for iic communications
;       R0     bit counter for 87c751/87c752 routine
;       R1     points into tbuff
;       R2     iic tx count
;       R3     iic rx count
;       R4     iic address
;       R5     iic loop counter
;       R6     free
;       R7     free
;
;THE SYSTEM CLOCK IS AT  11.059 MHz
;
;DEFINE CONSTANTS
true    equ -1              ;define "true"
false   equ        not true        ;define "false"
c552    equ false        ;NOTE: only one of these to
c652    equ false        ;   be true at any
c751    equ true          ;    one time!!!
c752    equ false        ;
;
        if      c751 or c752
;redefine bits for i2con for mov instructions
bcxa    equ 80h
bidle   equ        40h
bcdr    equ 20h
bcarl   equ        10h
bcstr   equ        08h
bcstp   equ        04h
bxstr   equ        02h
bxstp   equ        01h
;redefine bits for i2cfg for mov instructions
bslaven equ      80h
bmastrq equ      40h
bclrti  equ       20h
btirun  equ       10h   
;misc constants for the 87c751/87c752
maxscl  equ       00000010b      ;ct1,ct0 max xtal of 16MHz
intcon  equ       88h        ;ea=1, ei2=0, et1=1, ex1=0, et0=0, ex0=0
        endif
;
;DEFINE INTERNAL DATA STORAGE
stack   data       16          ;8 level stack, allow 2 register banks
cont    data        stack+16        ;control 'register' bit addressable
clk1    data        cont+1    ;clock 1, .10:.01 seconds
clk2    data        clk1+1    ;clock 2,  10:1 seconds
clk3    data        clk2+1    ;clock 3,  10:1 minutes
clk4    data        clk3+1    ;clock 4,  10:1 hours
dat1    data        clk4+1    ;clock 5,  10:1 days
dat2    data        dat1+1    ;clock 6,  10:1 months
alm1    data        dat2+1    ;clock 11, 10:1 minutes
alm2    data        alm1+1    ;clock 12, 10:1 hours
mod1    data        alm2+1    ;used by clock modify routine
mod2    data        mod1+1    ;also used by clock modify routine
dtoa    data        mod2+1    ;doa output value
keycnt  data      dtoa+1                ;key input counter
tone    data        keycnt+1        ;storage for dtmf tone
tbuff   data       tone+1  ;transfer buffer for I2C operations
ebuff   data       tbuff+8                ;eeprom buffer
free    data        ebuff+6  ;first free location
;
        if      free gt 63    ;keep below 87c751 limit
        out of internal memory
        endif
;
;DEFINE SFR BIT USAGE, FOR CONT REGISTER LOCATION MUST BE 20H !!
sdv     bit  0  ;switch data valid
dmod    bit 1                ;data modified
xmode   bit        2              ;extra mode switch
aset    bit 4                ;alarm is set flag
aring   bit        5              ;alarm ringing flag
;
;IIC CHIP ADDRESSES
iop     equ  01001110b ;PCF8574
iopa    equ 01111110b        ;PCF8574A
dtmf    equ 01001010b        ;PCD3312
irtc    equ 01001100b        ;SAA3028
led     equ  01110110b ;SAA1064
lcd     equ  01110100b ;PCF8577
atod    equ 10011110b        ;PCF8591
clock   equ        10100010b       ;PCF8583
ram     equ  10101110b ;PCF8570
eeprom  equ       10100110b      ;PCF8582
;
;SERIAL I/O CLOCK FREQUENCY AND CONTROL BYTES
;
;IIC CHIP CONTROL BYTES
lcdctl  equ       00000000b      ;lcd subaddress
ledctl  equ       01000111b      ;initial led brightness value
clkctl  equ       00001100b      ;clock control,masked,alarm active
alctl1  equ       11001001b      ;alarm control,no clock alarm,timer
alctl2  equ       11011001b      ;alarm control,clock daily alarm,timer
adcctl  equ       01000100b      ;output on,4 inputs,inc,a/d channel 0
dacctl  equ       01000000b      ;output on
;
;MISC CONSTANTS
dtmfb   equ        00111111b       ;tone for second beep 1768Hz
dtmft   equ        00110101b       ;first tone of alarm ringing 832Hz
dtmfo   equ        00000001b       ;turns the dtmf oscillator off
keyval  equ       5            ;number of key reads before valid
;
;
;THIS IS THE MAIN PROGRAMME.
        org     0000h
reset:  sjmp      start  ;allow for all 87c552 interrupts
        org     0003h
xint0:  sjmp      reset ;trap external interrupt 0, 87C652, 87C751
        org     000bh
t0of:   sjmp       reset  ;trap timer 0 overflow, 87C652, 87C751
        org     0013h
xint1:  sjmp      reset ;trap external interrupt 1, 87C652, 87C751
        org     001bh
t1of:   ajmp       tout   ;trap timer 1 overflow, 87C652, 87C751
        org     0023h
uart:   sjmp       reset  ;trap uart interrupt, 87C652
        org     002bh
i2c:    sjmp        reset   ;trap i2c interrupt, 87C652
        org     0033h
t2ct0:  sjmp      reset ;trap t2 capture 0 interrupt
        org     003bh
t2ct1:  sjmp      reset ;trap t2 capture 1 interrupt
        org     0043h
t2ct2:  sjmp      reset ;trap t2 capture 2 interrupt
        org     004bh
t2ct3:  sjmp      reset ;trap t2 capture 3 interrupt
        org     0053h
adccom: sjmp     reset        ;trap adc completion interrupt
        org     005bh
t2cm0:  sjmp      reset ;trap t2 compare 0 interrupt
        org     0063h
t2cm1:  sjmp      reset ;trap t2 compare 1 interrupt
        org     006bh
t2cm2:  sjmp      reset ;trap t2 compare 2 interrupt
        org     0073h
t2of:   sjmp       reset  ;trap timer 2 overflow
;
        org     0080h
;
;************************************************************************
;                                                               *
;       Here is the initialization routine.                *
;       The first job is to put the I2C interface into the          *
;       slave receive mode at the speed set in the equate table.       *
;                                                               *
;************************************************************************
;NOTE: some chips, inparticular large lcd drivers require some time
;to get ready before you write to them. You may want to alter the delay
;for your aplication.
;initialize iic interface
start:  mov       r0,#00h
        mov     r1,#20
        djnz    r0,$
        djnz    r1,$-2
        if      c552 or c652
        mov     p1,#p1init   ;initialize the i/o port
        mov     s1con,#clkack        ;sets up the iic hardware
        mov     ie,#00h            ;turn off all the interupts
        endif   
        if      c751 or c752
        mov     i2cfg,#bslaven+maxscl+btirun
        mov     ie,#intcon   ;interrupt control value
        endif
        mov     sp,#stack-1  ;initialize stack pointer
        mov     r5,#00h            ;set lcd,led mode time,seconds
        mov     r6,#00h            ;clear old data
        mov     cont,#00h    ;initialize control bits in sfr map
        mov     keycnt,#00h  ;initialize key counter
        mov     tone,#dtmft  ;initial tone value
;initialize clock /alarm control modes
        mov     tbuff,#00h   ;word address to 0
        mov     tbuff+1,#clkctl      ;clock control
        setb    rs0  ;select register bank 1
        mov     r2,#02h            ;tx = 2
        mov     r3,#00h            ;rx = 0
        mov     r4,#clock    ;address = clock
        acall   iic                ;send control to clock
;no need to restore the register bank yet
        mov     tbuff,#08h   ;word address to 8
        mov     tbuff+1,#alctl1      ;alarm control, no clock alarm
        mov     r2,#02h            ;tx = 2
        mov     r3,#00h            ;rx = 0
        mov     r4,#clock
        acall   iic                ;send alarm control to clock
;initialize the led brightness and operating mode
        mov     tbuff,#00h   ;instruction to 0
        mov     tbuff+1,#ledctl
        mov     r2,#02              ;tx = 2
        mov     r3,#00              ;rx = 0
        mov     r4,#led            ;address = led
        acall   iic
;now restore register bank
        clr     rs0    ;select register bank 0
;
;This is the return point for the main loop
main:   acall      keytin                ;get any key entry
        acall   rdclk            ;get time/alarm data from clock
;now increment and output the dtoa value
dtoaop: inc      dtoa    ;increment output value
        mov     tbuff,#dacctl        ;set digital control word
        mov     tbuff+1,dtoa ;output value
        setb    rs0  ;select register bank 1
        mov     r2,#02              ;tx = 2
        mov     r3,#00              ;rx = 0
        mov     r4,#atod     ;address = atod
        acall   iic
        clr     rs0    ;select register bank 0
;now get and decode the switch data
swip:   jb xmode,swipx      ;exit as in modify mode
        jb      sdv,swip1     ;test key valid flag and jump else
        sjmp    proc                ;otherwise process display modes
swip1:  mov       a,r6      ;get the switch data
        jb      acc.2,ledbr   ;decrement the led brightness
        jb      acc.1,almtog  ;toggle the alarm on/off
        jb      acc.0,lcdcnt  ;alter lcd mode byte
swipx:  sjmp      proc
;
;LEDBR controls the led brightness.
;There are 8 steps of led current available. Depending on the
;characteristics of the led used some brightness steps might not be visable.
;The program limits the led brightness to 4 steps because of the above.
ledbr:  clr       sdv        ;zero key valid flag
        mov     keycnt,#00   ;zero input counter
        mov     a,r4  ;get old value
        add     a,#-10h            ;decement
        mov     r4,a  ;save new value
        anl     a,#30h              ;limit values to 0 to 3
        mov     tbuff,#00    ;instruction = 0
        add     a,#17h              ;add 10h + led control bits
        mov     tbuff+1,a    ;so output values 1 to 4
        setb    rs0  ;select register bank 1
        mov     r2,#02              ;tx = 2
        mov     r3,#00              ;rx = 0
        mov     r4,#led            ;address = led
        acall   iic                ;write the led brightness value
        clr     rs0    ;select register bank 0
        sjmp    proc                ;done
;
;ALMTOG turns the alarm on if it was off and if it was off it
;turns it on. It reverts the display to time so the alarm status
;can be seen.
almtog: clr      sdv      ;zero key valid flag
        mov     keycnt,#00   ;zero key counter
        mov     a,r5
        anl     a,#00fh            ;check mode
        jnz     almtx                ;only turn alarm on if time displayed
        cpl     aset  ;toggle alarm bit
        clr     aring                ;make sure the alarm stops ringing
        mov     tbuff,#08h   ;alarm control register
        mov     tbuff+1,#alctl2      ;get ready to turn alarm on
        jb      aset,almt     ;jump if turning alarm on
        mov     tbuff+1,#alctl1      ;get ready to turn alarm off
almt:   setb       rs0        ;select register bank 1
        mov     r2,#02
        mov     r3,#00
        mov     r4,#clock
        acall   iic                ;send two bytes
        clr     rs0    ;select register bank 0
        mov     tbuff,#dtmfo ;turn off any tone
        setb    rs0  ;select register bank 1
        mov     r2,#01              ;tx = 1
        mov     r3,#00              ;rx = 0
        mov     r4,#dtmf     ;address of dtmf
        acall   iic                ;turn tone off
        clr     rs0    ;select register bank 0
almtx:  sjmp      proc
;
;LCDCNT controls both the lcd and the led modes of display.
;The lcd has 4 modes    00 = clock(set)     01 = alarm(set)     
;                     02 = date(set) 03 = A--d(display)
lcdcnt: clr      sdv      ;zero key valid flag
        mov     keycnt,#00   ;zero input counter
        mov     a,r5  ;get programme control byte
        inc     a
        anl     a,#0f3h            ;2 bit counter, leave led brightness
        mov     r5,a  ;put it back
lcdx:   sjmp       proc
;
;PROC processes the programme control byte
proc:   mov        a,r5        ;get programme control byte
        anl     a,#0fh              ;mask program mode
        acall   jlcd       ;decide where to jump
        jnb     aring,lcddis ;if alarm not ringing display normal
        mov     a,clk2              ;get the seconds
        jb      acc.0,lcddis
;blank display if alarm ringing and seconds are odd
        mov     r1,#tbuff+4
        mov     r2,#04h
blank:  mov       a,@r1    ;get non converted data
        anl     a,#20h              ;leave the colon bit
        orl     a,#10h              ;make it a blank
        mov     @r1,a                ;put it back
        dec     r1
        djnz    r2,blank    ;do all four characters
lcddis: mov      tbuff,#lcdctl
        mov     dptr,#lcdtbl
        mov     r1,#tbuff+1
        mov     r2,#04h            ;4 to encode
        acall   cnvrt            ;change to displayable
        setb    rs0  ;select register bank 1
        mov     r2,#05
        mov     r3,#00
        mov     r4,#lcd
        acall   iic                ;send to display
        clr     rs0    ;select register bank 0
        mov     a,r5  ;get programme control byte
        anl     a,#0fh              ;mask program mode
        acall   jled              ;decide where to jump
        mov     tbuff,#01h   ;led instruction address 01
        mov     dptr,#ledtbl
        mov     r1,#tbuff+1
        mov     r2,#04h            ;4 to encode
        acall   cnvrt            ;change it to displayable
        setb    rs0  ;select register bank 1
        mov     r2,#05h
        mov     r3,#00
        mov     r4,#led
        acall   iic                ;to display
        clr     rs0    ;select register bank 0
        mov     r0,#0ffh     ;this delay alters keyboard response
        mov     r1,#04fh     ;and dtoa ramp rate
delay:  djnz      r0,delay
        djnz    r1,delay
        ajmp    main
;
;************************************************************************
;                                                               *
;       The flow of data from the peripheral devices to the        *
;       displays is controlled by the low nibble stored in register R5 *
;       JLCD directs the programme to the lcd routines.                        *
;       JLED directs the programme to the led routines.                        *
;       NOTE this must be called so that each display processor                *
;       will return to PROC.                  *
;                                                               *
;************************************************************************
;
jlcd:   mov        dptr,#jmplcd
        rl      a
        jmp     @a+dptr
jled:   mov        dptr,#jmpled
        rl      a
        jmp     @a+dptr
;
;  short jumps
jmplcd: ajmp     clkp
        ajmp    almp
        ajmp    datp
        ajmp    atodp
;
jmpled: ajmp     secp
        ajmp    secp
        ajmp    secp
        ajmp    dtoap
;
atodp:  jb        xmode,atodm     ;jump to xmode routine
;Check to see if button 4 has been pressed etc.
atodp0: jnb      sdv,atodpd    ;jump if buttons not valid
        mov     a,r6  ;get key data
        jnb     acc.3,atodpd ;jump if not button 4
        clr     sdv    ;zero flag so that only 1 keypress
        mov     keycnt,#00h  ;zero input counter
        setb    xmode              ;turn on xmode bit
atodpd: mov      tbuff+1,#00ah ;A
        mov     tbuff+2,#017h        ;-
        mov     tbuff+3,#017h        ;-
        mov     tbuff+4,#00dh        ;d
        ret
atodm:  jnb       sdv,atodm1     ;test if valid button, jump if not
        clr     sdv    ;zero flag so that only 1 keypress
        mov     keycnt,#00h  ;zero input counter
        clr     xmode                ;zero extra mode
        mov     r5,#00h            ;lcd = time led = seconds
atodm1: mov      tbuff,#adcctl ;set analogue control word
        setb    rs0  ;select register bank 1
        mov     r2,#01              ;tx = 1
        mov     r3,#01              ;rx = 1
        mov     r4,#atod     ;address = atod
        acall   iic
        clr     rs0    ;select register bank 0
        mov     a,tbuff            ;get data
        mov     tbuff+1,#10h ;blank
        mov     r0,#tbuff+3
        acall   htod              ;convert to bcd
        ret               ;done
dtoap:  mov       a,dtoa  ;get byte
        mov     tbuff+1,#10h ;a blank
        mov     r0,#tbuff+3  ;point to where the 10's digit is to go
        acall   htod              ;convert to decimal
        ret
;
;ROMWR write to the PCF8582 eeprom chip.
;Due to the added complexity of the eeprom write routine,any data
;to be transfered is loaded into a special buffer.This buffer is
;10 bytes long but could be made longer by altering the equate table.
;The first byte in the buffer are the number of data bytes.The next
;byte is the internal word address and the rest of the buffer,upto 8
;bytes,is filled with data for consecutive memory locations in the chip.
;The PCB8582 takes 30ms to process each written byte.
;If the PCB8582 is still busy processing the last data written to it,
;it will not acknowledge its write address so the routine will exit
;without altering the buffer contents.If it is sucessful in writing
;upto 2 bytes to the chip then the buffer contents will be altered to
;reflect this fact.
;On exit,the first byte in the buffer will be the number of bytes
;still to be sent.This will be zero when the buffer is free.
;The second byte is the address of the next memory location to be written
;to.The buffer data contents are moved to the start of the buffer ready
;for the next time the routine is used.
romwr:  mov       r0,#ebuff      ;point to eeprom buffer
        mov     r1,#tbuff    ;point to transfer buffer
        mov     r2,#00h            ;number sent counter
        mov     a,@r0                ;get the number to send
        jz      romwrx                ;exit if none left to send
        mov     r3,a  ;save the number to send
        inc     r0      ;point to word address
        mov     a,@r0                ;get the word address
        mov     @r1,a                ;put word address into buffer
        inc     r0      ;point to 1st data byte
        inc     r1
        mov     a,@r0                ;get 1st data byte
        mov     @r1,a                ;put 1st data byte
        inc     r2      ;up the number sent counter
        dec     r3      ;down the number to send counter
        mov     a,r3
        jz      romwrs                ;only 1 to send
        inc     r0
        inc     r1
        mov     a,@r0                ;get 2nd data byte
        mov     @r1,a                ;put 2nd data byte
        inc     r2
        dec     r3
romwrs: mov      a,r2    ;get the number to send
        inc     a        ;make allowance for word address
        setb    rs0  ;select register bank 1
        mov     r2,a  ;tx = accu+1
        mov     r3,#00h            ;rx = 0
        mov     r4,#eeprom   ;set the address
        acall   iic
        clr     rs0    ;select register bank 0
jnz     romwrx              ;none zero is a failure
        mov     r1,#ebuff    ;point to start of ebuff
        mov     a,r3  ;get new number to send
        mov     @r1,a                ;save it for next time
        inc     r1      ;point to word address
        mov     a,@r1                ;get the old address
        add     a,r2  ;add in the number sent
        mov     @r1,a                ;save it for next time
romwrm: inc      r1        ;point to first data byte
        inc     r0      ;point to first non sent byte
        mov     a,r3  ;get number to send/move
        jz      romwrx                ;if zero exit
        mov     a,@r0
        mov     @r1,a
        dec     r3
        sjmp    romwrm            ;jump back more to move
romwrx: ret                  ;done until next time
;
;************************************************************************
;              THESE ARE THE IIC I/O ROUTINES ONLY            *
;              THEY EMULATE THE ROUTINES USED ON THE 1987          *
;              EVALUATION BOARD.AT THIS TIME THESE ARE NOT        *
;              PROVEN ON HARDWARE.                    *
;************************************************************************
;                                                               *
;       SERIAL INTERFACE SOFTWARE ROUTINES                    *
;       ACCESSED BY    call        iic                         *
;       REGISTER BANK 1 WILL BE USED EXCLUSIVELY FOR SIO ROUTINES      *
;       REGISTER USAGE       *
;       R'0    USED BY 87C751 AS A BIT COUNTER                    *
;       R'1    POINTS TO THE TX/RX BUFFER        *
;       R'2    HOLDS THE NUMBER TO TRANSMIT                                *
;       R'3    HOLDS THE NUMBER TO RECEIVE    *
;       R'4    SLAVE ADDRESS R/W BIT = 0            *
;       R'5    TX/RX COUNTER                                          *
;                                                               *
;************************************************************************
;       8 DATA BYTES IS THE MAXIMUM THAT CAN BE SENT OR RECIEVED       *
;       THIS IS DUE TO THE SIZE OF TBUFF BUT CAN BE EASILY ALTERED     *
;       ON ENTRY:                                          *
;              R'2    NUMBER OF BYTES TO TX                            *
;              R'3    NUMBER OF BYTE TO RX                                *
;              R'4    SLAVE ADDRESS                                   *
;       ON EXIT:                                                 *
;              ACCU   00 IF TRANSFER OK        *
;                     01 IF NOT ACKNOWLEDGED    *
;                     FF IF A BUS ERROR OCCURED                  *
;              R'1    POINTS TO LAST READ BYTE            *
;                                                               *
;************************************************************************
;
;
        if      c552 or c652
;************************************************************************
;                                                               *
;       TRIAL I2C ROUTINES FOR THE 80C552/652 DEVICES      *
;              Incoperating corrections from G.W.DUMBLETON        *
;              His corrections are in upper case to make them  *
;              easily seen, but some of them I feel are in fact       *
;              not required.This will be tested when I have some      *
;              hardware to play with.     *
;                                                               *
;                     24th NOVEMBER 1987                    *
;                                                               *
;              PHILIPS (NZ) LTD              G.D.MOSS              *
;                                                               *
;************************************************************************
iic:    mov r1,#tbuff
        mov     s1con,#clkack        ;reset sio status
;generate the address with the rd/wr bit correctly set
        mov     a,r2  ;get tx count
        jz      rdadd  ;r/w = 0
        mov     a,#01h              ;set for rx
rdadd:  orl       a,r4      ;get address
        xrl     a,#01h              ;invert rd wr bit
;       mov    s1dat,a          ;load address to send
        MOV     R7,A  ;TEMP SAVE WHY NOT IN THE DATA REGISTER
        setb    sta  ;generate a start condition
        sjmp    wsi1                ;wait for si = 1,status should be 08h
;the bus was not busy and a valid start condition was generated 08h
iics:   CLR        STA          ;SO WE DON'T GENERATED REPEATED STARTS
        MOV     A,R7  ;THIS SHOULD NOT BE REQUIRED
        MOV     S1DAT,A            ;BUT WE WILL SEE WITH SOME HARDWARE
        clr     si      ;this will now transmit the address
        sjmp    wsi1                ;wait for si = 1,status 18h 20h 40h 48h
;the bus was freed and a restart was generated 10h
iicrs:  CLR       STA        ;NOT REPEATED REPEATED STARTS
        mov     a,r4  ;get the address
        orl     a,#01h              ;make it a read
        mov     s1dat,a            ;ready it for sending
        clr     si      ;send the address on its way
        sjmp    wsi1                ;wait for si = 1,status 40h 48h
;now in master tx mode so tx first byte 18h
mtxa:   mov        a,r2        ;get the number to send
        mov     r5,a  ;load the tx counter with it
        mov     a,@r1                ;get data to send
        mov     s1dat,a            ;put it where it will be sent from
        clr     si      ;send it on its way
        sjmp    wsi1                ;wait for si = 1,status 28h 30h
;in master tx mode see if any more to tx 28h
mtxd:   djnz       r5,mtxd1       ;jump if multiple bytes to send
        mov     a,r3  ;get number to read
        jz      stopok                ;none so stop
        setb    sta  ;generate a repeated start
        CLR     SI      ;START THE REPEATED START
        sjmp    wsi1                ;wait for si = 1,status 10h
mtxd1:  inc       r1          ;point to next byte to send
        mov     a,@r1
        mov     s1dat,a            ;ready it for sending
        clr     si
        sjmp    wsi1                ;wait for si = 1,status 28h 30h
;read address sent and device acknowledged,read first byte 40h
mrxa:   mov        r1,#tbuff       ;point to buffer
        mov     a,r3  ;get receiver count
        mov     r5,a  ;load the counter with it
        djnz    r5,rdmlti   ;jmup if more than 1 byte to read
rdlast: clr      aa        ;set interface to not acknowledge
rdmlti: clr      si        ;start it on its way
        sjmp    wsi1                ;wait for si = 1,status 50h 58h
;read multiple bytes until its the last byte 50h
mrxd:   mov        a,s1dat  ;get the received byte
        mov     @r1,a                ;put it into tbuff