
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	ＰＩＣ１６Ｆ１ｘ ＭＳＳＰモジュール
;	Ｉ２Ｃマスターモード制御サブルーチン群
;
;									Ver0.2b JA0QON
;
;		使用ワーク
;		wrk1
;
;		履歴
;		マスタ送信のみ		Ver0.1
;		マスタ受信追加		Ver0.2
;		Ver0.2の小修正		Ver0.2a
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;
;   I2C　マスタモード初期化サブルーチン
;
;       RC0     SCL         I2Cクロック
;       RC1     SDA         I2Cデータ
;
MSSP_MAS
			movlb	04h
			movlw	038h        ;38H=00111000
			movwf	SSP1CON1    ;SSP1ﾏｽﾀｰﾓｰﾄﾞ ｲﾈｰﾌﾞﾙ
			movlw	04fh
			movwf	SSP1ADD		;100KHZボーレート
			clrf	BSR
            call	MSSP_IDLE	;
			return

;
;		MSSPアイドル待ち
;
;   R/WとSEN,RSEN,PEN,RCEN,ACKENのどれかとOR演算すると
;   MSSP1がアイドルかどうかが分かる
;
MSSP_IDLE
            movlb   04h
msid01      movf    SSP1CON2,W
            andlw   01fh        ;1FH=00011111B
            btfss	STATUS,Z
			bra		msid01		;MSSP not idle
            btfsc	SSP1STAT,R_NOT_W
            bra		$-1			;R/Wbit=1 not idle
            clrf    BSR
            return
;
;		MSSP STARTCON 送信
;
STARTCON
			bcf		PIR1,SSP1IF	;
			call	MSSP_IDLE	;アイドル待ち
            movlb   04h
            bcf SSP1CON1,WCOL   ;衝突フラグクリア
            bsf SSP1CON2,SEN    ;スタート出力
            btfsc   SSP1CON1,WCOL
            goto    STARTCON    ;スタート再出力
            btfsc   SSP1CON2,SEN
            bra     $-1         ;送信完了チェック
            clrf    BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
            return

;
;		MSSP反復スタート
;
RESTART
			bcf		PIR1,SSP1IF	;
            movlb   04h
            bsf SSP1CON2,RSEN	;リスタート出力
            btfsc   SSP1CON2,RSEN
            bra     $-1         ;送信完了チェック
            clrf    BSR
            return

;
;   マスターモード　1バイト送信
;   送信データはＷレジスタ
;
SEND_BYTE
;	SSP1CON2,SEN=1で、START条件の生成
;	START完了でﾊｰﾄﾞｳｴｱがSSP1IFをセット
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb	04h
			movwf	SSP1BUF		;送信開始、BF=1
			btfsc	SSP1STAT,BF	;BF=0で送信完了
			bra		$-1			;送信終了待ち
			btfsc   SSP1CON2,ACKSTAT
			bra		$-1			;ACK返信待ち
;	ACK確認終了で、SSP1IFがセットされる、STOP確認でもSSP1IFがセット
;	ｿﾌﾄｳｴｱでSSP1IFをクリアする
			clrf	BSR
			call    MSSP_IDLE   ;アイドル待ち（これをしないと送信失敗する）
			return

;
;   マスターモード　1バイト受信
;   受信データはＷレジスタ
;
RCV_BYTE
;	SSP1CON2,SEN=1で、START条件の生成
;	STARAT完了でﾊｰﾄﾞｳｴｱがSSP1IFをセット
;	ｿﾌﾄｳｴｱでSSP1IFをクリア
;	ｽﾚｰﾌﾞｱﾄﾞﾚｽ送信、R/W=1
;	ﾏｽﾀがｽﾚｰﾌﾞからの/ACKをACKSTATで確認
;	ACK確認終了で、SSP1IFがセットされる
;	ｿﾌﾄｳｴｱでSSP1IFをクリアする

			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb   04h
			bsf	SSP1CON2,RCEN	;ﾏｽﾀｰﾓｰﾄﾞ受信許可
			btfss SSP1STAT,BF	;BF=1で受信完了
			bra		$-1			;受信終了待ち
			clrf	BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb	04h
			movf	SSP1BUF,W	;受信データ読み出し、BF=0
			clrf	BSR
			movwf	wrk1		;受信データ一時保管

			movlb	04h
			bcf SSP1CON2,ACKDT	;ACK応答する、にセット
			bsf SSP1CON2,ACKEN	;ｽﾚｰﾌﾞにACK返送
			btfsc	SSP1CON2,ACKEN
			bra		$-1
			bcf SSP1CON1,SSPOV	;受信OFフラグリセット
			clrf	BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			call	MSSP_IDLE	;アイドル待ち
			movf	wrk1,W
			return
;
;   最終バイト受信
;
;		通常受信と違うのは、データ8bit受信後のACK応答
;		連続受信-ACK応答する
;		1バイト受信あるいは最終受信-ACK応答しない
;
LAST_RCV
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
            movlb   04h
            bsf SSP1CON2,RCEN   ;受信許可
            btfss   SSP1STAT,BF
            bra     $-1         ;受信終了待ち
			clrf	BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb	04h
			movf	SSP1BUF,W	;受信データ読み出し、BF=0
			clrf	BSR
			movwf	wrk1		;受信データ一時保管

			movlb	04h
			bsf SSP1CON2,ACKDT	;NACK（ACK応答しない)にセット
			bsf SSP1CON2,ACKEN	;ｽﾚｰﾌﾞにACK返送
			btfsc	SSP1CON2,ACKEN
			bra		$-1
			clrf	BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			call	MSSP_IDLE	;アイドル待ち
			movf	wrk1,W
			return
;
;		MSSP STOPCON送信
;
STOPCON
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb	04h
			bsf	SSP1CON2,PEN
			btfsc	SSP1CON2,PEN
			bra		$-1
			clrf	BSR
			bcf		PIR1,SSP1IF	;ｿﾌﾄｳｴｱがSSP1IFをクリア
			call	MSSP_IDLE	;アイドル待ち
			return

