#ifndef _i2cs_inc_ #define _i2cs_inc_ messg "include 'i2cs.inc'" LIST ; Title : I2C slave interface ; By : komi ; Last update : 2005.09.26 ; Version : 0.2 NOLIST ; 10bitモード対応は後回し ;---------------------------------------------------------------------------- ; 解説 ;---------------------------------------------------------------------------- ; ; ;---------------------------------------------------------------------------- #ifndef I2C_SLAVE_ADDRESS error "Please define that is 7 or 10 bit address.(I2CS.INC)" #endif #if !(I2C_SLAVE_ADDRESS == D'7' || I2C_SLAVE_ADDRESS == D'10') error "Please define that is 7 or 10 bit address.(I2CS.INC)" #endif ;------------------------------------------------------------------ ; アドレス保存エリア U_I2C UDATA I2C_ADDR2 res 1 ; 10bit least 8bit I2C_ADDR1 res 1 ; 7bit, 10bit most 2bit I2C_STAT res 1 ; Temporary ;------------------------------------------------------------------ if (I2C_SLAVE_ADDRESS == D'7') ;------------------------------------------------------------------ ; I2C slave 初期化 ; I2C_slave_init_W MACRO banksel I2C_ADDR1 MOVWF I2C_ADDR1 banksel SSPADD MOVWF SSPADD banksel SSPCON MOVLW B'00110110' MOVWF SSPCON banksel SSPSTAT CLRF SSPSTAT ENDM I2C_slave_init_V1 MACRO addrV1 MOVLW addrV1 I2C_slave_init_W ENDM I2C_slave_init_U1 MACRO addrU1 banksel addrU1 MOVF addrU1, W I2C_slave_init_W ENDM ;------------------------------------------------------------------ ; 何か受信されるのを待つ ; I2C_slave_WAIT MACRO banksel PIR1 BTFSS PIR1, SSPIF GOTO $-1 BCF PIR1, SSPIF banksel SSPSTAT MOVF SSPSTAT, W ANDLW B'00101101' banksel I2C_STAT MOVWF I2C_STAT ENDM ; ; 待たない.何か受信したら label へジャンプする. ; I2C_slave_WAIT_nw MACRO label banksel PIR1 BTFSS PIR1, SSPIF GOTO $+3 BCF PIR1, SSPIF banksel SSPSTAT MOVF SSPSTAT, W ANDLW B'00101101' banksel I2C_STAT MOVWF I2C_STAT GOTO label ENDM ;------------------------------------------------------------------ ; write operation, address byte. I2C_slave_address_wr MACRO label banksel I2C_STAT MOVLW B'00001001' ; address & buffer full XORWF I2C_STAT, W BTFSC STATUS, Z GOTO label ENDM ;------------------------------------------------------------------ ; write operation, data byte. I2C_slave_data_wr MACRO label banksel I2C_STAT MOVLW B'00101001' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO label ENDM ;------------------------------------------------------------------ ; read operation, address byte. I2C_slave_address_rd MACRO label banksel I2C_STAT MOVLW B'00001100' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO label ENDM ;------------------------------------------------------------------ ; read operation, data byte. I2C_slave_data_rd MACRO label banksel I2C_STAT MOVLW B'00101100' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO label ENDM ;------------------------------------------------------------------ ; NACK from master. I2C_slave_NACK MACRO label banksel I2C_STAT MOVLW B'00101000' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO label ENDM ;------------------------------------------------------------------ ; Write data I2C_slave_write_data MACRO varU1 local label0 banksel varU1 MOVF varU1, W banksel SSPSTAT BTFSC SSPSTAT, BF GOTO $-1 banksel SSPCON label0: BCF SSPCON, WCOL MOVWF SSPBUF BTFSC SSPCON, WCOL GOTO label0 BSF SSPCON, CKP ENDM ;------------------------------------------------------------------ ; Read data W_I2C_slave_read_data MACRO banksel SSPBUF MOVF SSPBUF, W ENDM U1_I2C_slave_read_data MACRO resU1 W_I2C_slave7bit_read_data banksel resU1 MOVWF resU1 ENDM ;------------------------------------------------------------------ endif if (I2C_SLAVE_ADDRESS == D'10') ;------------------------------------------------------------------ ; I2C slave 初期化 ; I2C_slave_init_V2 MACRO addrV2 variable addrA, addrB addrA = (B'11110000' | ((addrV2 & B'1100000000') >>7)) addrB = low addrV2 banksel I2C_ADDR1 MOVLW addrB MOVWF I2C_ADDR2 MOVLW addrA MOVWF I2C_ADDR1 banksel SSPADD MOVWF SSPADD banksel SSPCON MOVLW B'00110111' MOVWF SSPCON CLRF SSPSTAT ENDM I2C_slave_init_U2 MACRO addrU2 banksel addrU2 MOVF addrU2, W banksel I2C_ADDR2 MOVWF I2C_ADDR2 banksel addrU2 RLF (addrU2+1), W ANDLW B'00000110' IORLW B'11110000' banksel I2C_ADDR1 MOVWF I2C_ADDR1 banksel SSPADD MOVWF SSPADD banksel SSPCON MOVLW B'00110111' MOVWF SSPCON CLRF SSPSTAT ENDM ;------------------------------------------------------------------ endif ;------------------------------------------------------------------ ; モジュールリセット I2C_reset MACRO banksel SSPCON BCF SSPCON, SSPEN ; 一度無効にして BSF SSPCON, SSPEN ; 再度有効にする. ENDM ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; I2C割込初期化 I2C_intr_init MACRO banksel PIR1 BCF PIR1, SSPIF banksel PIE1 BSF PIE1, SSPIE ENDM ;------------------------------------------------------------------ ; I2C割込 I2C_INTR_START MACRO banksel PIE1 BTFSS PIE1, SSPIE GOTO i2c_intr_end banksel PIR1 BTFSS PIR1, SSPIF GOTO i2c_intr_end BCF PIR1, SSPIF banksel SSPSTAT MOVF SSPSTAT, W ANDLW B'00101101' banksel I2C_STAT MOVWF I2C_STAT ; write & address MOVLW B'00001001' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO i2c_intr_s1 ; write & data MOVLW B'00101001' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO i2c_intr_s2 ; read & address MOVLW B'00001100' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO i2c_intr_s3 ; read & data MOVLW B'00101100' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO i2c_intr_s4 ; NACK MOVLW B'00101000' XORWF I2C_STAT, W BTFSC STATUS, Z GOTO i2c_intr_s5 GOTO i2c_intr_err ; ERROR ENDM I2C_INTR_S1 MACRO GOTO i2c_intr_end i2c_intr_s1: banksel SSPBUF MOVF SSPBUF, F ; ダミーリード BCF SSPCON, SSPOV BCF SSPCON, WCOL ENDM I2C_INTR_S2 MACRO GOTO i2c_intr_end i2c_intr_s2: banksel SSPCON BCF SSPCON, SSPOV ENDM I2C_INTR_S3 MACRO GOTO i2c_intr_end i2c_intr_s3: banksel SSPCON BCF SSPCON, SSPOV BCF SSPCON, WCOL ENDM I2C_INTR_S4 MACRO GOTO i2c_intr_end i2c_intr_s4: ENDM I2C_INTR_S5 MACRO GOTO i2c_intr_end i2c_intr_s5: ENDM I2C_INTR_ERR MACRO GOTO i2c_intr_end i2c_intr_err: ENDM I2C_INTR_END MACRO i2c_intr_end: ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- LIST #endif