📄 i2cbus.a30
字号:
.endif ; --- DEBUG ---
push.b R1L ; Place R1L on to Stack.
or.b #S2RIPL,S2RIC ; clear interrupt status register.
btst 2,U2SMR ; Bit test
jz stop_int ; Jump if BBS = 1
;;; ----------------------------------------------------------------------------
;; If Bus Busy Flag == 0 Continue with start-int.
;;; ----------------------------------------------------------------------------
start_int: ;
mov.b #00h,STSPIC ; Disable Start Stop interrupt request.
btst 1,m_iic ; Test for master / slave operation.
jz stsp_int_end ; Jump if master.
start_int10: ;
;;
;;
jsr make_stop ; Jump to make_stop and return.
mov.b #04h,R1L ; Status return value: "Improper Start Condition Detected."
jmp stsp_common_master
;;; ----------------------------------------------------------------------------
;;
;;; ----------------------------------------------------------------------------
.align ;
stop_int: ;
mov.b #00h,STSPIC ; Disable interrupt.
mov.b #0d1h,U2SMR2 ;
cmp.b #00h,m_iic ; Set I2C bus mode condition to "Wait mode stop to start condition."
jeq stsp_int_end ;
stop_int10: ;
;;; ----------------------------
btst 1,m_iic ; Test for Master mode.
jz stsp_int_end ; If not master mode jump to stsp_int_end.
;;
;; Master mode
mov.b #05h,R1L ;
;;; ------------------------------------------------------------------------------
;; Master common function.
;;; ------------------------------------------------------------------------------
stsp_common_master: ;
push.b md_cnt ; Push Master Receive Data Count on to stack.
;
btst 0,m_iic ; Bit test for Read or Write mode.
jc stsp_common_master10 ; If Read
;; W
jsr $iic_mw_end ;
jmp stsp_common_master_end
;; R
.align ;
stsp_common_master10: ;
jsr $iic_mr_end ; Jump to Master Data Receive End.
stsp_common_master_end: ;
pop.b md_cnt ; Pop Master Receive Data Count
mov.b #00h,md_cnt ; Init Master Receive Data Count to zero.
;;; ------------------------------------------------------------------------------
;; Slave Command function
;;; ------------------------------------------------------------------------------
stsp_int_end: ;
; bclr 3,U2RB+1 ; Reset Arbitration lost flag
mov.b #00h,m_iic ; Init I2C bus mode condition register.
pop.b R1L ; Return value.
.if DEBUG == 1 ; ---DEBUG---
bclr 5,dp ; ---DEBUG---
.endif ; ---DEBUG---
reit ;
;;; ******************************************************************************
;; UART2 RECV INTERRUPT.
;;; ******************************************************************************
.align ;
u2rcv_int: ;
.if DEBUG == 1 ; --- DEBUG ---
bset 6,dp ; --- DEBUG ---
.endif ; --- DEBUG ---
pushm A0,R1 ; Push multiple registers on to stack.
bclr 6,U2SMR2 ; Bit clear SDHI, SDA output enable.
btst 3,STSPIC ; Bit test for first byte.
jz byte_n ; If not first byte jump.
;; ------------------------------------------------------------------------------
;; End of first byte process timing.
;; ------------------------------------------------------------------------------
bclr 3,STSPIC ; Clear Stop Start interrupt request.
or.b #STSPIPL,STSPIC ; Enable Stop Start interrupt.
byte_1: ;
btst 3,U2RB+1 ; Test for Arbitration.
jc slave_1 ; If Arbitration interrupt, jump.
;
master_1: ;
cmp.b #02h,m_iic ; Test I2C bus mode condition register for master transmission mode.
jz ms_snd_1 ; if master jump.
cmp.b #03h,m_iic ; Test I2C bus mode condition register for master receive mode.
jz ms_rcv_1 ; if slave jump.
slave_1: ;
jsr wait_20usec ; New counter delay July 1999 by Bruce Embry.
mov.w U2RB,R1 ; Copy receive buffer to R1
and.b #7fh,R1L ; Filter out bit number 7.
cmp.b id_adr,R1L ; Compare SLAVE ID to ID value received.
jeq sl_next ; Jump if ID's match.
;
btst 1,m_iic ; Test I2C bus mode condition register for Master operation.
jz slave_taiki ; if 0 jump to slave_taiki.
jsr abt_lost ; Jump to abt_lost and return.
jmp slave_taiki ; jump to slave_taiki.
.align ;
;
sl_next: ;
bclr 3,U2SMR2 ; Disable SDA output stop bit.
and.b #0fch,P7 ; Set SDA output to low "ACK" "Slave ID Address"
or.b #03h,PD7 ; Direction change to output
mov.b #00h,U2MR ; Disable I2C mode.
btst 8,R1 ; Test received data for READ /WRITE mode.
jc sl_snd_1 ; If slave READ, jump to transmit data function.
jmp sl_rcv_1 ; If slave WRITE, jump to slave receive data function.
;;
byte_n: ;
cmp.b #00h,m_iic ; Test I2C bus mode condition register for "wait mode stop to start condition.
jeq u2rcv_int_end ; IF equal jump to u2rcv_int_end.
btst 1,m_iic ; Test I2C bus mode condition register for master operation.
jz slave_n ; Jump if slave operation.
;
master_n: ;
btst 0,m_iic ; Test I2C bus mode condition register for write or read.
jc ms_rcv_n ; Jump for master receive.
jmp ms_snd_n ; Else, this is master write.
;
slave_n: ;
btst 0,m_iic ; Test I2C bus mode condition register for write or read.
jc sl_rcv_n ; Jump for slave receive mode.
jmp sl_snd_n ; jump for slave transmission mode.
;;; ===========================================================================
;; Master Transmit 1st data byte
;; Test for ID byte ACK ---> If true send 1st data byte
;;; ===========================================================================
.align ;
ms_snd_1: ;
.if DEBUG == 1 ; --- DEBUG ---
bset 1,dp ; --- DEBUG ---
.endif ; --- DEBUG ---
mov.w mw_data,A0 ; Copy transmit data address to A0.
mov.b [A0],R1L ; Copy data -> by A0 to R1L.
mov.b #01h,R1H ; Set 9th bit high, future test for ACK/NACK.
mov.b #83h,U2SMR2 ; SCL output disable
ms_s_l1: ;
btst 1,P7 ; --- Wait for SCL == HIGH.
jz ms_s_l1 ; --/
btst 0,P7 ; Bit test for ACK.
jnz snd_nack_err_1 ; If no ACK, jump to snd_nack_err_1.
mov.w R1,U2TB ; ACK received continue. move data to UART2 transmit buffer.
mov.b #8fh,U2SMR2 ; Authorize master transmit on I2C bus.
jsr wait_2usec ; New counter delay July 1999 by Bruce Embry.
bset 5,U2SMR2 ; Enable master transmit. Keep SCL low.
bclr 3,U2RB+1 ; Clear arbitration bit.
jsr wait_5usec ; New counter delay July 1999 by Bruce Embry
bclr 5,U2SMR2 ; Release SCL and start transmitting on I2C bus.
jmp u2rcv_int_end ; Jump to u2rcv_int_end.
;;; ===========================================================================
;; Master Transmit
;; Test for data byte ACK --> Set for next data byte.
;;; ===========================================================================
.align ;
ms_snd_n: ;
.if DEBUG == 1 ; --- DEBUG ---
bset 1,dp ; --- DEBUG ---
.endif ; --- DEBUG ---
btst 3,U2RB+1 ; Test arbitration bit.
jz ms_snd_n10 ; If arbitration bit is cleared, then jump to ms_snd_n10
jsr abt_lost ; else jump arbitration bit is set jump to sub-routine abt_lost.
jmp slave_taiki ; Jump to slave_taiki.
.align ;
ms_snd_n10: ;
;
inc.b md_cnt ; Increment master data counter.
mov.b md_cnt,R1L ; Copy master data counter to R1L register.
mov.b #00h,R1H ; Init R1H register to 00.
mov.w mw_data,A0 ; Copy master write data address pointer to A0.
add.w R1,A0 ; Add data counter to data address.
mov.b [A0],R1L ; Get data pointed to by A0 and copy to R1L
mov.b #01h,R1H ; Set 8th bit to 1, "Not ACK."
mov.b #83h,U2SMR2 ; Set I2C bus to not enable.
ms_s_ln: ;
btst 1,P7 ; ---Wait for SCL to go high.
jz ms_s_ln ; -/
btst 0,P7 ; Check SDA.
jnz snd_nack_err_n ; If SDA is high, this is NACK, jump to snd_nack_err_n.
cmp.b md_cnt,mw_lng ; Else, ACK received, compare master data count to data length.
jeq snd_end ; If all data has been sent, then jump to snd_end "Stop Bit."
; Else set up to send next data byte.
mov.w R1,U2TB ; Copy next data byte to UART2 transmit buffer.
mov.b #8fh,U2SMR2 ; Enable transmit of start character.
jsr wait_2usec ; New counter delay July 1999 by Bruce Embry.
bset 5,U2SMR2 ; Set set SWC2, "SCL goes low."
bclr 3,U2RB+1 ; Clear arbitration bit.
jsr wait_15usec ; New counter delay July 1999 by Bruce Embry
bclr 5,U2SMR2 ; Clear bit SWC2, "SCL goes high and enable transmission of next byte.
jmp u2rcv_int_end ;
;;; ---------------------------------------------------------------------------
;; END of Master transmission.
;;; ---------------------------------------------------------------------------
.align ;
snd_nack_err_1: ;
mov.b #01h,R1L ; Return value; "NO ACK" ---> ID error.
jmp ms_s_end ;
;;; ----------------------------
.align ;
snd_nack_err_n: ;
mov.b #02h,R1L ; Return value "NO ACK" ---> data error.
jmp ms_s_end ;
;;; ----------------------------
.align ;
snd_end: ; Normal end!
mov.b #00h,R1L ; Clear R1L.
ms_s_end: ;
jsr make_stop ; Jump sub-routine make stop function.
mov.b #00h,m_iic ; Set I2C bus mode condition to Stop to Start condition.
;;; for C
push.b md_cnt ; Push master data counter on to stack.
jsr $iic_mw_end ; Jump sub-routine iic_mw_end, "part of c code return number of data bytes writter and status."
pop.b md_cnt ; Pop master data counter from stack.
mov.b #00h,md_cnt ; Init master data counter for next I2C bus operation.
jmp u2rcv_int_end ; End interrupt service routine.
;;; ===========================================================================
;; Master receive "READ"
;;; ===========================================================================
.align ;
ms_rcv_1: ;
.if DEBUG == 1 ; ---DEBUG---
bset 2,dp ; ---DEBUG---
.endif ; ---DEBUG---
mov.b #83h,U2SMR2 ; SCL output disable.
ms_r_l1: ;
btst 1,P7 ; --- Wait for SCL to go high.
jz ms_r_l1 ; -/
btst 0,P7 ; Bit test SDA for ACK.
jnz rcv_nack_err ; If no ACK received jump to rcv_nack_err.
;
;; ELSE
;;1999,6,25 miho ; Code added to fixed problem with number of data bytes being return.
cmp.b #0,mr_lng ; Compare master read data length.
jz point0 ; If zero jump to point0.
mov.w #0ffh,U2TB ; else init UART2 transmit buffer to 0FF, "ACK."
jmp point1 ;
point0:
mov.w #1ffh,U2TB ; Bit8 =1 "NO ACK."
point1:
;;;
bset 2,U2SMR2 ; At end of address comparison, "see note 3.4.1."
jsr wait_2usec ; New counter delay July 1999 by Bruce Embry.
bset 5,U2SMR2 ; First bit startup, disable SCL .
jsr wait_20usec ; New counter delay by Bruce Embry, July 1999.
bclr 5,U2SMR2 ; Bit clear SWC2, enable SCL clk and start reception of next data byte.
jmp u2rcv_int_end ; Jump to end of interrupt service routine.
;;; ===========================================================================
;; Master receive "DATA"
;;; ===========================================================================
.align ;
ms_rcv_n: ;
.if DEBUG == 1 ; ---DEBUG---
bset 2,dp ; ---DEBUG---
.endif ; ---DEBUG---
;
mov.b #00h,R1H ; Init R1H
mov.b md_cnt,R1L ; Load master receive data count.
mov.w mr_data,A0 ; Copy master receive data pointer to A0
add.w R1,A0 ; Calculate data pointer offset.
;
mov.w U2RB,R1 ; Copy UART2 receive buffer to R1
btst 8,R1 ; Test 8th bit
rolc.b R1L ; if 8th bit == 1, then shift left Restoring normal byte.
mov.b R1L,[A0] ; Copy data to memory location pointed to by A0.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -