?? usi_i2cmaster.s43
字號:
;Control flow
;Data Transmit : state 0 -> 2 -> 4 -> 10 -> 12 -> 14
;Data Recieve : state 0 -> 2 -> 4 -> 6 -> 8 -> 14
;------------------------------------------------------------------------------
add.w &TI_I2CState,PC ; I2C State Machine
jmp STATE0
jmp STATE2
jmp STATE4
jmp STATE6
jmp STATE8
jmp STATE10
jmp STATE12
jmp STATE14
STATE0 ; Send out slave address
cmp.b #1,&TI_GenStop ; Generate stop condn?
jz Generatestop
clr.b &TI_AckResult ; Clear result of previous oprn.
clr.b &USISRL ; Generate start condition
bis.b #USIGE+USIOE,&USICTL0 ;
bic.b #USIGE,&USICTL0 ;
mov.b &TI_SlavAdd,&USISRL ; and transmit address R/W =1
bis.b #8,&USICNT ; bit counter = 8
mov.w #2,&TI_I2CState ; goto next state rx address (N)ACK
bic.b #USIIFG,&USICTL1
reti
Generatestop
clr.b &TI_GenStop ; Clear generate-stop bit
clr.b &USISRL ; Pre-stop
jmp Prestop
STATE2 ; rx slave address acknowledge
bic.b #USIOE,&USICTL0 ; SDA = input
bis.b #1,&USICNT ; Bit counter = 1, rx (N)ACK
mov.w #4,&TI_I2CState ; Goto next state, chk (N)ACK
bic.b #USIIFG,&USICTL1
reti
STATE4 ; chk address ack and do one of three options - exit loop,tx data,rxdata
cmp.b #1,TI_AckPoll ; ack poll? only for slave select fn
jz chkackpoll
bit.b #0x01,&USISRL ; did slave ack? usisrl = 0?
jnc Loopchk ; ACK received, go to Tx/Rx
mov.b #1,&TI_AckResult ; Slave did not respond
clr.b &USISRL
jmp Prestop ; generate prestop
Loopchk clr.b &TI_AckResult
bit.b #1,&TI_SlavAdd ; Chk last bit for R/W
jnz Data_Rx ; if R/w = 1
jmp Data_Tx ; if R/w = 0
chkackpoll
mov.b #1,&TI_AckResult ; Ack result = 1
bit.b #0x01,&USISRL ; if nack rxed go to pre-stop
jnz test_nack
clr.b &TI_AckResult ; Slave ack recieved, store result
test_nack
clr.b &USISRL
jmp Prestop ; generate prestop
Data_Rx
bic.b #USIOE,&USICTL0 ; SDA = input
bis.b #8,&USICNT ; bit counter = 8, Rx data
mov.w #6,&TI_I2CState ; goto next state: Send (N)ACK
bic.b #USIIFG,&USICTL1
reti
Data_Tx
push.w R6
bis.b #USIOE,&USICTL0 ; SDA = output
mov.w &TI_TxPtr,R6 ; Pointer to tx data
mov.b @R6,&USISRL
bis.b #8,&USICNT ; bit counter = 8, Tx data
mov.w #10,&TI_I2CState ; Go to next state: Receive (N)ACK
bic.b #USIIFG,&USICTL1
pop.w R6
reti
STATE6 ;Data received, move to buffer and transmit ack (nack if last byte)
push.w R6
mov.w &TI_RxPtr,R6 ; Pointer to received data
mov.b &USISRL,0(R6)
inc.w &TI_RxPtr ; Increment pointer for next rx
pop.w R6
cmp.b #1,&TI_ByteCtr ; Last byte?
jz data_NACK ; If yes send Nack to slave
bis.b #USIOE,&USICTL0 ; SDA = output
clr.b &USISRL ; If no send ACK
jmp STATE6_Exit
data_NACK
mov.b #0xFF,&USISRL ; Send NACK
STATE6_Exit
bis.b #1,&USICNT ; Bit counter = 1, send NACK bit
mov.w #8,&TI_I2CState ; goto next state, pre-stop
bic.b #USIIFG,&USICTL1
reti
STATE8 ; Pre-stop condition for Rx, loop back if ctr!=0
dec.b &TI_ByteCtr ; Decrement rx counter
cmp.b #0,&TI_ByteCtr ; More bytes to receive?
jnz Data_Rx
mov.b #0xFF,&USISRL ; If no, go to prestop
cmp.b #0,&TI_StopBit ; if user requested "no stop" condn.
jnz Prestop ; branch to exit w/o stop condition
clr.b &USISRL
Prestop
bis.b #USIOE,&USICTL0 ; SDA =output
bis.b #1,&USICNT ; Bit counter = 1, SCL high, SDA low
mov.w #14,&TI_I2CState ; goto next state, generate stop
bic.b #USIIFG,&USICTL1
reti
STATE10 ; Data transmitted, get ready to rx ack/nack byte from slave
bic.b #USIOE,&USICTL0 ; SDA = input
bis.b #1,&USICNT ; Bit counter = 1, rx (N)Ack bit
mov.w #12,&TI_I2CState ; Goto next state: check (N)Ack
bic.b #USIIFG,&USICTL1
reti
STATE12 ;Check if slave (N)acked
;Pre-stop condition for Tx, generate stop condition if ctr = 0 else loop back
bit.b #0x01,&USISRL ; Process data (N)Ack bit
jz Data_Ack ; if ACK received
mov.b #1,&TI_AckResult ; Nack, result of oprn. = 1
clr.b &USISRL ;
jmp Prestop ; generate prestop
Data_Ack
clr.b &TI_AckResult ; Ack, result of oprn. = 0
inc.w &TI_TxPtr ; Increment tx pointer
dec.b &TI_ByteCtr ; Dec byte counter
cmp.b #0,&TI_ByteCtr ; More bytes to transmit?
jnz Data_Tx
mov.b #0xFF,&USISRL ; Last byte, go to prestop
cmp.b #0,&TI_StopBit ; if user requested "no stop" condn.
jnz Prestop ; branch to exit w/o stop condition
clr.b &USISRL
jmp Prestop
STATE14 ;common stop condition for Tx/Rx
mov.b #0xFF,&USISRL ; USISRL=1 to release SDA
bis.b #USIGE,&USICTL0 ; Transparent latch enabled
bic.b #USIGE+USIOE,&USICTL0 ; Latch/SDA output disabled
mov.w #0,&TI_I2CState ; Reset state machine for next oprn.
bic.b #USIIFG,&USICTL1
cmp.b #1,&TI_AckPoll ; If I2C_Select, exit w/o callback
jz LPMSelect
cmp.b #1,&TI_GenStop ; If I2C_Stop, exit w/o callback
jz LPMSelect
Stop cmp.w #0,&TI_FuncPtr ; chk for callbackfn
jz LPMSelect ; no callback, exit active
push.w R12 ; save registers used in callback
#ifdef USE_C_CONTEXT_SAVE
push.w R13
push.w R14
push.w R15
#endif
mov.b &TI_AckResult,R12 ; Result of oprn. to Callback fn.
call &TI_FuncPtr
cmp.w #1,R12 ; Did user set/clear LPMbit?
#ifdef USE_C_CONTEXT_SAVE
pop.w R15
pop.w R14
pop.w R13
#endif
pop.w R12 ; restore register used in callback
jnz exitISR ; stay in LPM
LPMSelect
mov.b &TI_AckResult,R12
bic.w #LPM4,0(SP) ; Exit active for next transfer
exitISR
reti
;------------------------------------------------------------------------------
; Interrupt Vectors
;------------------------------------------------------------------------------
COMMON INTVEC
ORG USI_VECTOR ; USI interrupt
DW USI_ISR ;
END
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -