📄 i2c.asm
字号:
.ifnz I2C_SUPPORT
;;**************************************************************
;;Function : fProcessI2cRead
;;Description : process I2C write function
;;Input : IOP_DATA1_H=rCtrlByte,IOP_DATA1_L=rAddr
;;Output : NONE
;;**************************************************************
fProcessI2cRead:
;;fetch parameter
lda IOP_DATA1_H
sta rCtrlByte
lda IOP_DATA1_L
sta rAddr
jsr fI2cSendCmdAddr
bcs lReadI2CFail
jsr fI2cStart
;;change control byte to read
lda rCtrlByte
ora #$01
sta rCtrlByte
;;control byte
lda rCtrlByte
sta rOutBuffer
jsr fI2cWriteByte
jsr fCheckI2cAck
bcs lReadI2CFail
lReadI2cAgain:
;;read data
jsr fI2cReadByte
;;response data
lda rOutBuffer
sta IOP_DATA4_L
smb I2C_DATA_RDY_bit,IOP_DATA0_L
;;check read next
bbr I2C_READ_CONT_bit,IOP_DATA0_L,lEndI2cRead
jsr fResponseAck
;;wait the data fetch by user
lWaitDataFetch:
lda IOP_DATA0_L
and #I2C_DATA_RDY
bne lWaitDataFetch
bra lReadI2cAgain
lEndI2cRead:
jsr fI2cStop
rts
lReadI2CFail:
jsr fI2cStop
lda IOP_DATA0_L
ora #I2C_DATA_ERR
sta IOP_DATA0_L
rts
;;**************************************************************
;;Function : fProcessI2cWrite
;;Description : process I2C write function
;;Input : IOP_DATA1_H=rCtrlByte
;; IOP_DATA1_L=rAddr
;; IOP_DATA4_L=rDat1
;; IOP_DATA4_H=rDat2
;; IOP_DATA0_L= len
;;Output : NONE
;;**************************************************************
fProcessI2cWrite:
;;fetch data
lda IOP_DATA1_H
sta rCtrlByte
lda IOP_DATA1_L
sta rAddr
lda IOP_DATA4_L
sta rData
lSendNextData:
jsr fI2cSendCmdAddr
bcs lWriteI2CFail
lI2cSendNextByte:
;;data
lda rData
sta rOutBuffer
jsr fI2cWriteByte
jsr fCheckI2cAck
bcs lWriteI2CFail
;;lda IOP_DATA0_L
;;ora #I2C_DATA_RDY
;;sta IOP_DATA0_L
smb I2C_DATA_RDY_bit,IOP_DATA0_L
;;check the mode
;;lda IOP_DATA0_L
;;and #I2C_WRITE_PAGE
;;beq lWriteByteMode
bbr I2C_WRITE_PAGE_bit,IOP_DATA0_L,lWriteByteMode
;;page mode
;;wait the data fetch by user
lWaitDataSet:
;;lda IOP_DATA0_L
;;and #I2C_DATA_RDY
;;bne lWaitDataFetch
bbs I2C_DATA_RDY_bit,IOP_DATA0_L,lWaitDataSet
lda IOP_DATA4_L
sta rData
bra lI2cSendNextByte
lWriteByteMode:
jsr fI2cStop
;;check the send leght
lda IOP_DATA0_L
and #VFD_DAT_LN_MASK
beq lI2cSendEnd
dec IOP_DATA0_L
inc rAddr ;;send next addr
lda IOP_DATA4_H
sta rData
;;jmp lSendNextData
bra lSendNextData
lI2cSendEnd:
rts
lWriteI2CFail:
jsr fI2cStop
lda IOP_DATA0_L
ora #I2C_DATA_ERR
sta IOP_DATA0_L
rts
;;**************************************************************
;;Function : fI2cSendCmdAddr
;;Description : start a I2C operate
;;Input : NONE
;;Output : NONE
;;**************************************************************
fI2cSendCmdAddr:
ldx #0
lSendCmdAgain01:
;;send start
jsr fI2cStart
;;control byte
lda rCtrlByte
sta rOutBuffer
jsr fI2cWriteByte
jsr fCheckI2cAck
bcc lGotAck01
dex
bne lSendCmdAgain01
;;jmp lSendCmdAddrErr
bra lSendCmdAddrErr
lGotAck01:
;;address
lda rAddr
sta rOutBuffer
jsr fI2cWriteByte
jsr fCheckI2cAck
bcs lSendCmdAddrErr
clc
rts
lSendCmdAddrErr:
sec
rts
;;**************************************************************
;;Function : fI2cStart
;;Description : start a I2C operate
;;Input : NONE
;;Output : NONE
;;**************************************************************
fI2cStart:
.ifnz I2C_8202_16bit
;;SDA=SCL=1
;;smb I2C_SDA_bit,I2C_SDA_PORT
;;smb I2C_SCL_bit,I2C_SCL_PORT
smb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_SDA_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
jsr fDelay
;;SDA 1 -> 0
;;rmb I2C_SDA_bit,I2C_SDA_PORT
rmb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_SDA_PORT
jsr fDelay
;;SCL 1 -> 0
;;rmb I2C_SCL_bit,I2C_SCL_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
rts
.else
;;SDA=SCL=1
;;smb I2C_SDA_bit,I2C_PORT
;;smb I2C_SCL_bit,I2C_PORT
smb I2C_SDA_bit,bPortBuff
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
jsr fDelay
;;SDA 1 -> 0
;;rmb I2C_SDA_bit,I2C_PORT
rmb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
jsr fDelay
;;SCL 1 -> 0
;;rmb I2C_SCL_bit,I2C_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
rts
.endif
;;**************************************************************
;;Function : fI2cStop
;;Description : stop a I2C operate
;;Input : NONE
;;Output : NONE
;;**************************************************************
fI2cStop:
.ifnz I2C_8202_16bit
;;SDA=0
;;rmb I2C_SDA_bit,I2C_SDA_PORT
rmb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_SDA_PORT
;;SCL=1
;;smb I2C_SCL_bit,I2C_SCL_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
jsr fDelay
;;SDA=1
;;smb I2C_SDA_bit,I2C_SDA_PORT
smb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_SDA_PORT
jsr fDelay
rts
.else
;;SDA=0
;;rmb I2C_SDA_bit,I2C_PORT
rmb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
;;SCL=1
;;smb I2C_SCL_bit,I2C_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
jsr fDelay
;;SDA=1
;;smb I2C_SDA_bit,I2C_PORT
smb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
jsr fDelay
rts
.endif
;;**************************************************************
;;Function : fResponseAck
;;Description : Response a ACK to I2C device
;;Input : NONE
;;Output : NONE
;;**************************************************************
fResponseAck:
.ifnz I2C_8202_16bit
;;SDA=0
;;rmb I2C_SDA_bit,I2C_SDA_PORT
rmb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_SDA_PORT
jsr fDelay
;;SCL=1
;;smb I2C_SCL_bit,I2C_SCL_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
jsr fDelay
;;SCL 1 -> 0
;;rmb I2C_SCL_bit,I2C_SCL_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
rts
.else
;;SDA=0
;;rmb I2C_SDA_bit,I2C_PORT
rmb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
jsr fDelay
;;SCL=1
;;smb I2C_SCL_bit,I2C_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
jsr fDelay
;;SCL 1 -> 0
;;rmb I2C_SCL_bit,I2C_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
rts
.endif
;;**************************************************************
;;Function : fCheckI2cAck
;;Description : Check the ACK response
;;Input : NONE
;;Output : c=0 -> response detect
;; c=1 -> response fail
;;**************************************************************
fCheckI2cAck:
.ifnz I2C_8202_16bit
;;change port to input
rmb I2C_SDA_bit,I2C_SDA_PORT_CFG
;;SCL=1
;;smb I2C_SCL_bit,I2C_SCL_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
jsr fDelay
lda #$ff
sta rDataLen
lCheckAckAgain:
bbr I2C_SDA_bit,I2C_SDA_PORT,lAckIsOk
dec rDataLen
bne lCheckAckAgain
sec
;;jmp fCheckI2cAckRts
bra fCheckI2cAckRts
lAckIsOk:
clc
fCheckI2cAckRts:
;;SCL=0
;;rmb I2C_SCL_bit,I2C_SCL_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
;;change port to output
smb I2C_SDA_bit,I2C_SDA_PORT_CFG
rts
.else
;;change port to input
rmb I2C_SDA_bit,I2C_PORT_CFG
;;SCL=1
;;smb I2C_SCL_bit,I2C_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
jsr fDelay
lda #$ff
sta rDataLen
lCheckAckAgain:
bbr I2C_SDA_bit,I2C_PORT,lAckIsOk
dec rDataLen
bne lCheckAckAgain
sec
;;jmp fCheckI2cAckRts
bra fCheckI2cAckRts
lAckIsOk:
clc
fCheckI2cAckRts:
;;SCL=0
;;rmb I2C_SCL_bit,I2C_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
;;change port to output
smb I2C_SDA_bit,I2C_PORT_CFG
rts
.endif
;;**************************************************************
;;Function : fI2cWriteByte
;;Description : output one byte data to I2C port
;;Input : rOutBuffer
;;Output : NONE
;;**************************************************************
fI2cWriteByte:
ldy #8
lI2cSendNextBit:
rol rOutBuffer
bcc lI2cOutLow
.ifnz I2C_8202_16bit
;;smb I2C_SDA_bit,I2C_SDA_PORT
smb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_SDA_PORT
bra lI2cSendOutOk
lI2cOutLow:
;;rmb I2C_SDA_bit,I2C_SDA_PORT
rmb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_SDA_PORT
lI2cSendOutOk:
;;out to port
;;hold at least 4.7us for 5v system
jsr fDelay
;;SCL=1
;;smb I2C_SCL_bit,I2C_SCL_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
;;hold at least 4.7us for 5v system
jsr fDelay
;;SCL=0
;;rmb I2C_SCL_bit,I2C_SCL_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
dey
bne lI2cSendNextBit
;;hold for read ack
jsr fDelay
rts
.else
;;smb I2C_SDA_bit,I2C_PORT
smb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
bra lI2cSendOutOk
lI2cOutLow:
;;rmb I2C_SDA_bit,I2C_PORT
rmb I2C_SDA_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
lI2cSendOutOk:
;;out to port
;;hold at least 4.7us for 5v system
jsr fDelay
;;SCL=1
;;smb I2C_SCL_bit,I2C_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
;;hold at least 4.7us for 5v system
jsr fDelay
;;SCL=0
;;rmb I2C_SCL_bit,I2C_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
dey
bne lI2cSendNextBit
;;hold for read ack
jsr fDelay
rts
.endif
;;**************************************************************
;;Function : fI2cReadByte
;;Description : read one byte data to I2C port
;;Input : NONE
;;Output : rOutBuffer
;;**************************************************************
fI2cReadByte:
.ifnz I2C_8202_16bit
;;change port to input
rmb I2C_SDA_bit,I2C_SDA_PORT_CFG
ldy #8
lI2cRecvNextBit:
;;smb I2C_SCL_bit,I2C_SCL_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
;;hold at least 4.7us
jsr fDelay
bbr I2C_SDA_bit,I2C_SDA_PORT,lI2cIsLow
sec
bra lI2cMakeData
lI2cIsLow:
clc
lI2cMakeData:
rol rOutBuffer
;;SCL=0
;;rmb I2C_SCL_bit,I2C_SCL_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_SCL_PORT
;;hold max = 900ns or 3500ns
jsr fDelay
dey
bne lI2cRecvNextBit
;;change port to output
smb I2C_SDA_bit,I2C_SDA_PORT_CFG
rts
.else
;;change port to input
rmb I2C_SDA_bit,I2C_PORT_CFG
ldy #8
lI2cRecvNextBit:
;;smb I2C_SCL_bit,I2C_PORT
smb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
;;hold at least 4.7us
jsr fDelay
bbr I2C_SDA_bit,I2C_PORT,lI2cIsLow
sec
bra lI2cMakeData
lI2cIsLow:
clc
lI2cMakeData:
rol rOutBuffer
;;SCL=0
;;rmb I2C_SCL_bit,I2C_PORT
rmb I2C_SCL_bit,bPortBuff
lda bPortBuff
sta I2C_PORT
;;hold max = 900ns or 3500ns
jsr fDelay
dey
bne lI2cRecvNextBit
;;change port to output
smb I2C_SDA_bit,I2C_PORT_CFG
rts
.endif
.endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -