⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sw_i2c_slave.s43

📁 msp430板子红外驱动
💻 S43
📖 第 1 页 / 共 2 页
字号:
            jc      SDA_High                ; Jmp if carry bit is set
SDA_Low     bic.b   #SDA_PIN,&SDA_OUT       ; Set SDA low
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            reti                            ; Return from interrupt
                                            ;
SDA_High    bis.b   #SDA_PIN,&SDA_OUT       ; Set SDA high
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            reti                            ; Return from interrupt
                                            ;
Tx_8HL                                      ; 1->0 edge for SCL clk 8
            bic.b   #SDA_PIN,&SDA_DIR       ; Release SDA (set SDA as input)
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            reti                            ; Return from interrupt
                                            ;

Addr_8HL                                    ; 1->0 edge for SCL clk 8
            bis.b   #SCL_PIN,&SCL_DIR       ; Hold SCL low (set SCL as output)
            bit.b   #SDA_PIN,&SDA_IES       ; SDA value saved in SDA_IES
            rlc.b   I2C_DATA                ; Left shift carry bit into I2C val
            bic.b   #001h,I2C_DATA          ; Clear R/W bit for address test
            cmp.b   #I2C_ADDR,I2C_DATA      ; Is my I2C address?
            jnz     NotMyAddr               ; Not my address
            bic.b   #SDA_PIN,&SDA_OUT       ; Set SDA output low
            bis.b   #SDA_PIN,&SDA_DIR       ; Hold SDA low (set SDA as output)
            bit.b   #SDA_PIN,&SDA_IES       ; SDA value saved in SDA_IES
            adc.b   I2C_DATA                ; Reset R/W bit to original value
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            bis.b   #I2C_MATCH,&I2CEvent    ; Set I2C address match event flag
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            bic.b   #SCL_PIN,&SCL_DIR       ; Release SCL (set SCL as input)
            reti                            ; Return from interrupt
                                            ;
NotMyAddr                                   ; Not my I2C address
            mov.w   #SCL_NMATbl+32,SCL_TBL  ; Point to Not My Address Table+16
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            bic.b   #SCL_PIN,&SCL_DIR       ; Release SCL (set SCL as input)
            reti                            ; Return from interrupt
                                            ;
Addr_9HL                                    ; 1->0 edge for SCL clk 9
            bis.b   #SCL_PIN,&SCL_DIR       ; Hold SCL low (set SCL as output)
            clr.w   &I2CIdx                 ; Clear I2C buffer index
            bit.b   #001h,I2C_DATA          ; Is R/W bit set?
            jc      I2C_Read                ; Yes, go to I2C_Read
I2C_Write                                   ; No, process I2C write
            bic.b   #SDA_PIN,&SDA_DIR       ; Release SDA (set SDA as input)
            mov.w   #SCL_RxTbl,SCL_TBL      ; Point to I2C receive table
            clr.b   I2C_DATA                ; Clear I2C data
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            bic.b   #SCL_PIN,&SCL_DIR       ; Release SCL (set SCL as input)
            reti                            ; Return from interrupt
                                            ;
I2C_Read                                    ; Process I2C read
            mov.w   #SCL_TxTbl,SCL_TBL      ; Point to I2C transmit table
            push.w  I2C_IDX                 ; Save register on stack
            mov.w   &I2CIdx,I2C_IDX         ; Load I2C buffer index
            mov.b   I2CTxBuff(I2C_IDX),I2C_DATA
                                            ; Load I2C data
            inc.w   I2C_IDX                 ; Increment I2C buffer index
            mov.w   I2C_IDX,&I2CIdx         ; Save I2C buffer index
            pop.w   I2C_IDX                 ; Restore register from stack
            rla.b   I2C_DATA                ; Shift I2C data left
            jnc     RlsSCL                  ; Jmp if carry bit is not set
            bis.b   #SDA_PIN,&SDA_OUT       ; Set SDA high
RlsSCL      bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            bic.b   #SCL_PIN,&SCL_DIR       ; Release SCL (set SCL as input)
            reti                            ; Return from interrupt
                                            ;
Rx_9HL                                      ; 1->0 edge for SCL clk 9
            bis.b   #SCL_PIN,&SCL_DIR       ; Hold SCL low (set SCL as output)
            bic.b   #SDA_PIN,&SDA_DIR       ; Release SDA (set SDA as input)
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            mov.w   #SCL_RxTbl,SCL_TBL      ; Point to I2C receive table
            mov.w   #0,&TACCTL2             ; Stop TA2
            cmp.w   #0,&I2CCBFunc           ; Is a callback func registered?
            jeq     SkipCB                  ; No, skip callback function
            push.w  R12                     ; Yes, save R12 on stack
            mov.w   I2C_DATA,R12            ; Copy I2C data to R12
            call    &I2CCBFunc              ; Call callback function
            pop.w   R12                     ; Restore R12
            jmp     Rx_9HL_End              ; Go to label
SkipCB      push.w  I2C_IDX                 ; Save register on stack
            mov.w   &I2CIdx,I2C_IDX         ; Load I2C buffer index
            mov.b   I2C_DATA,I2CRxBuff(I2C_IDX)
                                            ; Move I2C data reg to I2C buffer
            inc.w   I2C_IDX                 ; Increment I2C buffer index
            and.w   #I2CRXINDEXMASK,I2C_IDX ; Prevent buffer overflow
            mov.w   I2C_IDX,&I2CIdx         ; Save I2C buffer index
            pop.w   I2C_IDX                 ; Restore register from stack
Rx_9HL_End  clr.b   I2C_DATA                ; Clear I2C data
            mov.w   &TAR,&TACCR2            ; Load TAR into TACCR2
            add.w   #I2C_TIMEOUT,&TACCR2    ; Add I2C timeout to TACCR2
            mov.w   #CCIE,&TACCTL2          ; Enable TACCTL2 interrupt
            bic.b   #SCL_PIN,&SCL_DIR       ; Release SCL (set SCL as input)
            reti                            ; Return from interrupt
                                            ;
Tx_9HL                                      ; 1->0 edge for SCL clk 9
            bis.b   #SCL_PIN,&SCL_DIR       ; Hold SCL low (set SCL as output)
            bit.b   #SDA_PIN,&SDA_IES       ; SDA value saved in SDA_IES
            jc      NoAck                   ; Yes, no Ack from Master
            mov.w   #SCL_TxTbl,SCL_TBL      ; Point to I2C transmit table
            push.w  I2C_IDX                 ; Save register on stack
            mov.w   &I2CIdx,I2C_IDX         ; Load I2C buffer index
            mov.b   I2CTxBuff(I2C_IDX),I2C_DATA
                                            ; Load I2C data
            inc.w   I2C_IDX                 ; Increment I2C buffer index
            and.w   #I2CTXINDEXMASK,I2C_IDX ; Prevent buffer overflow
            mov.w   I2C_IDX,&I2CIdx         ; Save I2C buffer index
            pop.w   I2C_IDX                 ; Restore register from stack
            rla.b   I2C_DATA                ; Shift I2C data left
            jc      SDA_High1               ; Jmp if carry bit is set
            bic.b   #SDA_PIN,&SDA_OUT       ; Set SDA low
            jmp     SDA_Out                 ; Go to SDA out
SDA_High1   bis.b   #SDA_PIN,&SDA_OUT       ; Set SDA high
SDA_Out     bis.b   #SDA_PIN,&SDA_DIR       ; Set SDA (set SDA as output)
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            mov.w   &TAR,&TACCR2            ; Load TAR into TACCR2
            add.w   #I2C_TIMEOUT,&TACCR2    ; Add I2C timeout to TACCR2
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            bic.b   #SCL_PIN,&SCL_DIR       ; Release SCL (set SCL as input)
            reti                            ; Return from interrupt
                                            ;
NoAck                                       ; No ACK from Master
            mov.w   #SCL_NMATbl,SCL_TBL     ; Point to I2C not my address table
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            bic.b   #SCL_PIN,&SCL_DIR       ; Release SCL (set SCL as input)
            reti                            ; Return from interrupt
                                            ;
NMA_9HL                                     ; 1->0 edge for SCL clk 9
            bis.b   #SCL_PIN,&SCL_DIR       ; Hold SCL low (set SCL as output)
            bic.b   #SDA_PIN,&SDA_DIR       ; Release SDA (set SDA as output)
            mov.w   #SCL_NMATbl,SCL_TBL     ; Point to Not My Address Table
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            mov.w   &TAR,&TACCR2            ; Load TAR into TACCR2
            add.w   #I2C_TIMEOUT,&TACCR2    ; Add I2C timeout to TACCR2
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
            bic.b   #SCL_PIN,&SCL_DIR       ; Release SCL (set SCL as input)
            reti                            ; Return from interrupt
                                            ;
;------------------------------------------------------------------------------
port2_ISR   ; Port 2 Interrupt Service Routine
            ; I2C SDA input triggers this ISR
;------------------------------------------------------------------------------
            bit.b   #SCL_PIN,&SCL_IN        ; MW Sample I2C SCL in carry bit
            jc      Std_Entry               ; MW If SCL is low, ignore SDA transition
            bic.b   #SDA_PIN,&SDA_IFG       ; Clear SDA interrupt flag
            reti                            ; Return from interrupt
Std_Entry
;            xor.b   #8h,&P1OUT              ; Toggle debug pin DEBUG MW-+
            bit.b   #SDA_PIN,&SDA_IES       ; Is SDA set for 1->0 interrupt?
            jnc     Stop_Cond               ; No, go to stop condition
                                            ;
Start_Cond                                  ; Start condition
            mov.w   #SCL_AddrTbl,SCL_TBL    ; Point to I2C Address Table
            mov.w   &TAR,&TACCR2            ; Load TAR into TACCR2
            add.w   #I2C_TIMEOUT,&TACCR2    ; Add I2C timeout to TACCR2
            mov.w   #CCIE,&TACCTL2          ; Enable TACCTL2 interrupt
// MW FLAG            clr.b   &IE1                    ; Disable all IE1 interrupts
// MW FLAG            clr.b   &IE2                    ; Disable all IE2 interrupt
            mov.w   #0,&TACCTL0             ; Disable TA0
            mov.w   #0,&TACCTL1             ; Disable TA1
            bic.b   #SDA_PIN,&SDA_IE        ; Disable SDA interrupt
// MW            bis.w   #CPUOFF,0(SP)           ; Enter LPM0 on return
;            xor.b   #001h,&P3OUT            ; DEBUG MW
            clr.b   &i2cIndex               ; Clear I2C state MW
            reti                            ; Return from interrupt
                                            ;
Stop_Cond                                   ; Stop condition
            bis.b   #SDA_PIN,&SDA_IES       ; Set SDA for 1->0 edge interrupt
            bic.b   #SDA_PIN,&SDA_IFG       ; Clear SDA interrupt flag
            bic.b   #SCL_PIN,&SCL_IES       ; Set SCL for 0->1 interrupt edge
            bic.b   #SCL_PIN,&SCL_IFG       ; Clear SCL interrupt flag
            bis.b   #I2C_STOP,&I2CEvent     ; Set I2C stop event flag
;            xor.b   #008h,&P3OUT            ; DEBUG MW
            reti                            ; Return from interrupt
                                            ;
;------------------------------------------------------------------------------
            COMMON  INTVEC                  ; Interrupt Vectors
;------------------------------------------------------------------------------
            ORG     PORT1_VECTOR            ; Port 1 Vector
            DW      port1_ISR               ;
                                            ;
            ORG     PORT2_VECTOR            ; Port 2 Vector
            DW      port2_ISR               ;
                                            ;
            END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -