I2C communication using HC08

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C communication using HC08

607 Views
lukasztrojanows
Contributor I

Hi. Did anyone use the MC68HC908QB8 to establish communication with a peripheral device using I2C, and would be so kind to share the code?

Labels (1)
Tags (2)
0 Kudos
Reply
1 Reply

380 Views
CustomSarge
Contributor III

Howdy, I use this code I wrote before any 9S08s had an I2C module.

This copy is from a 9S08AC16 32pin QFP, managing an I/O expander, 2 Digital pots, 3 DACs & a 24C02 flash.

DPots & DACs are MicroChip series.  I/O expander is NXP.  Good Hunting...   <<<)))

;* Port C: b0;1=I2C SCl;SDa /flash(a0)/10k DPot(52)/100k DPot(54)/

;*         compressor DAC(c0)/balance DAC(c1)/LCD contrast DAC(c2)

; I2C direct constants

flhadr  equ     $a0             ;flash RAM address (LSb=R/W*)(=0)

tnKdev  equ     $52             ;10k DPot Amp device addr (LSb=R/W*)(=1)

hnKdev  equ     $54             ;100k DPot Amp device addr (LSb=R/W*)(=2)

rlydev  equ     $c0             ;relay driver/Refl % selector

rlybas  equ     $05             ; relay base: 00=Off, 01=On, 10=70%, 11=20%

baldev  equ     $c2             ;DAC OptoFET LED driver/Balance

condev  equ     $c4             ;DAC LCD display contrast

; I2C  RAM

devreg  ds.b    1               ;RAM data page base addr

devadr  ds.b    1               ;I2C DPot address

;Initialize

;* read parmset from flash, parms all stay in these spots

        jsr     I2CStp          ;send a couple Stops to clear I2C protocol

        jsr     I2CStp

;* read flash parms

        ldhx    #prmtnk         ;set parameter base address

        mov     #flhadr,devadr  ;set device address

        mov     #$00,devreg     ;set flash addr

        jsr     RdPage

;        ldhx    #RefTbl         ;lamp life ref table

;        mov     #$10,devreg     ;set flash addr

;        jsr     RdPage

;        mov     #$20,devreg     ;set flash addr

;        jsr     RdPage

;        mov     #$30,devreg     ;set flash addr

;        jsr     RdPage

;* init relay driver, Duty Cycle parms NOT USED, Init as proof

IniRly: jsr     I2CSrt          ;xfr START

        lda     #rlydev         ;put/send devsel/addr (LSb=W*)

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     IRDErr          ;C=1: error

        lda     #$11            ;register select & autoincr

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     IRDErr          ;C=1: error

        lda     #$00            ;register PreScale 0 = max freq

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     IRDErr          ;C=1: error

        lda     #hld_dc         ;register PWM 0 = Hold %

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     IRDErr          ;C=1: error

        lda     #$00            ;register PreScale 1 = max freq

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     IRDErr          ;C=1: error

        lda     #cls_dc         ;register PWM 1 = Close %

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

IRDErr: nop                     ;error trace trap

        jsr     I2CStp          ;nml exit as stop

;------------------------------------------------------------------

;* init balance DAC, direct I2C calls: addr & cfg only

        jsr     DacRst          ;reset DACs' I2C

        jsr     I2CSrt          ;xfr START, ALT entry/set unit addr

        lda     #baldev         ;put/send devsel/addr (LSb=W*)

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        lda     #cfgDaI         ;page=reg select & cfg: DAC Config

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        jsr     I2CStp          ;xfr STOP

;* init contrast DAC, direct I2C calls: addr & cfg only

        jsr     DacRst          ;reset DACs' I2C

        jsr     I2CSrt          ;xfr START, ALT entry/set unit addr

        lda     #condev         ;put/send devsel/addr (LSb=W*)

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        lda     #cfgDaI         ;page=reg select & cfg: DAC Config

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        jsr     I2CStp          ;xfr STOP

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

; LCD, DAC & DPot ~ I2C Manager Routines

;* RdPage - get <gpctr1>(16) bytes, put to (H:X)+; page base in devsel & chrtnk

RdPage: mov     #15,gpctr       ;16 bytes (15 loops + last)

RdAddr: jsr     I2CSrt          ;xfr START, ALT entry/read unit addr

        lda     devadr          ;put/send devsel/addr (LSb=W*)

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     RxErr           ;C=1: error

        lda     devreg          ;page base addr 7-0

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     RxErr           ;C=1: error

        jsr     I2CClk

        jsr     I2CClk          ;pause for page addr write to take

        jsr     I2CSrt          ;send ANOTHER START after page addr write

        lda     devadr          ;put/send devsel/addr (LSb=W*)

        ora     #$01            ;chg to Read

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     RxErr           ;C=1: error

SRDRd:  sta     SRS 

        jsr     I2CRx8          ;read a byte

        clc                     ;clr Carry & send as Ack

        jsr     I2CTx1

        sta     ,x              ;save data to ram

        aix     #1              ;inc index

        dbnz    gpctr,SRDRd     ;dec ctr & loop

        jsr     I2CRx8          ;read last byte

        sec                     ;set Carry & send as NAck

        jsr     I2CTx1          ; not really a NAck: 1 bit time B4 stop

RxErr:  jsr     I2CStp          ;xfr STOP

        sta     ,x              ;save last of data

        aix     #1              ;inc index

        rts

;-------------------------------------------------------------------

;* WrPage - put <gpctr>(16) bytes, from (H:X)+; page addr in devreg

WrPage: bsr     Wr8Flh          ;AT24C02 Writes 8 bytes/page

        lda     devreg          ;next page

        add     #$08

        sta     devreg

        bsr     Wr8Flh

        rts

Wr8Flh: sta     SRS             ;Page Writes to FlashRAM only

        bclr    i2cWC,PTGD      ;low enables write to flash

;* Note: flash roms can have 8/16/32 byte pages

WrAddr: mov     #8,gpctr        ;8 bytes

        jsr     I2CSrt          ;xfr START, ALT entry/set unit addr

        lda     devadr          ;put/send devsel/addr (LSb=W*)

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxErr           ;C=1: error

        lda     devreg          ;RAM data page base addr

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxErr           ;C=1: error

SRDWrt: sta     SRS 

        lda     ,x              ;put/send byte

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxErr           ;C=1: error

        aix     #1              ;incr index

        dbnz    gpctr,SRDWrt    ;dec ctr, send all

        jsr     I2CStp          ;xfr STOP

        pshh                    ;save source addr

        pshx

        ldhx    #wrtrom         ;24C01 10mS write time

SRWDly: sta     SRS 

        aix     #-1

        cphx    #0

        bhi     SRWDly

        pulx                    ;restore source addr

        pulh

TxErr:  jsr     I2CStp          ;nml exit does 2 stops: no problem

        bset    i2cWC,PTGD      ;high disables write to flash

        rts

;-------------------------------------------------------------------

;  WrByte: Standard DPot setting: devadr, devreg=dev, reg sel, gptnk=value

WrDPot: jsr     I2CSrt          ;xfr START

        lda     devadr          ;put/send devsel/addr (LSb=W*)

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxBErr          ;C=1: error

        lda     devreg          ;register select

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxBErr          ;C=1: error

        sta     SRS 

        lda     gptnk           ;put/send byte

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxBErr          ;C=1: error

        jsr     I2CStp          ;xfr STOP

TxBErr: nop                     ;error trace trap

        jsr     I2CStp          ;nml exit does 2 stops: no problem

        rts

;-------------------------------------------------------------------

;  WrtDAC: devadr, devreg=register & value MSn, gptnk=value 2Sn/LSn

WrtDAC: jsr     I2CSrt          ;xfr START

        lda     devadr          ;put/send devsel/addr (LSb=W*)

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxDErr          ;C=1: error

        lda     devreg          ;register select

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxDErr          ;C=1: error

        sta     SRS 

        lda     gptnk           ;put/send byte

        jsr     I2CTx8

        jsr     I2CRx1          ;get NAck/Ack* (NAck=error)

        bcs     TxDErr          ;C=1: error

        jsr     I2CStp          ;xfr STOP

TxDErr: nop                     ;error trace trap

        jsr     I2CStp          ;nml exit does 2 stops: no problem

        rts

; Low Level bit-bang drivers ******************************************************

;-------------------------------------------------------------------

;* I2C routines: read byte/bit, start, stop, clk delay, write byte/bit

I2CRx8: bsr     I2CRx1           ;Rx byte to A, get b7 in C

        rola                     ;C->b0

        bsr     I2CRx1

        rola                     ;C->b0, b0->b1...etc

        bsr     I2CRx1

        rola                     ;C->b0

        bsr     I2CRx1

        rola                     ;C->b0

        bsr     I2CRx1

        rola                     ;C->b0

        bsr     I2CRx1

        rola                     ;C->b0

        bsr     I2CRx1

        rola                     ;C->b0

        bsr     I2CRx1

        rola                     ;C->b0

        rts           ;----------

I2CRx1: sta     SRS 

        bclr    i2cDta,PTCDD     ;Rx 1 bit to Carry, chg to In

        bsr     I2CClk

        bset    i2cClk,PTCD      ;clock high

        bsr     I2CClk

        sec                      ;init Carry=1

        brset   i2cDta,PTCD,IRx_0 ;=1: go clk

        clc                      ; else: data = Lo

IRx_0:  bsr     I2CClk

        bclr    i2cClk,PTCD      ;clock low

        bsr     I2CClk

        bclr    i2cDta,PTCD      ;reset as low

        bset    i2cDta,PTCDD     ;chg to Out, data out reg bit=0

        bsr     I2CClk

        rts           ;----------

;* I2C Common routines: start, stop, clk delay

I2CSrt: bset    i2cClk,PTCD      ;Start: inits a xfer

        bset    i2cDta,PTCD      ;enters w/clk & data High

        bsr     I2CClk

        bclr    i2cDta,PTCD

        bsr     I2CClk

        bclr    i2cClk,PTCD      ;exits w/clk & data Low

        bsr     I2CClk

        rts           ;----------

I2CStp: bsr     I2CClk           ;Stop: closes a xfer

        bset    i2cClk,PTCD      ;enters w/clk & data Low

        brn     I2CClk

        bset    i2cDta,PTCD      ;exits w/clk & data High

        brn     I2CClk

        rts           ;----------

;* Delay timer

I2CClk: mov     scltnk,bittmr   ;load clk count: 400kHz=2.5uS

I2CCLp: sta     SRS 

        nop

        dbnz    bittmr,I2CCLp    ;=3+1+5 :: ct=3->27cyc

        rts           ;----------

;* I2C Tx routines

I2CTx8: asla                     ;Tx byte in A, b7->C, 0->b0

        bsr     I2CTx1           ;send bit in Carry

        asla                     ;b6->C

        bsr     I2CTx1

        asla                     ;b5->C

        bsr     I2CTx1

        asla                     ;b4->C

        bsr     I2CTx1

        asla                     ;b3->C

        bsr     I2CTx1

        asla                     ;b2->C

        bsr     I2CTx1

        asla                     ;b1->C

        bsr     I2CTx1

        asla                     ;b0->C

        bsr     I2CTx1

        rts           ;----------

I2CTx1: sta     SRS 

        bset    i2cDta,PTCD      ;Tx 1 bit from Carry, init Hi

        bcs     I2CTxH           ;Carry set: go clk

        bclr    i2cDta,PTCD      ; else: set data Lo

I2CTxH: bsr     I2CClk

        bset    i2cClk,PTCD      ;clock set

        bsr     I2CClk        

        bclr    i2cClk,PTCD      ;clock clr

        bsr     I2CClk

        bclr    i2cDta,PTCD      ;put data Lo

        bsr     I2CClk

        rts           ;----------

0 Kudos
Reply