;---- simple data transfer chip TX
;---- 簡易データ送信チップ・ファームウェア
;---- by K.I	since 020310

	LIST	P=12C509A
	INCLUDE	P12C509A.INC

	__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC
	__IDLOCS H'0100'	;V1.00

;--------------------------------
TXD		EQU	0		;GP0, O, 送信データ
IN0		EQU	1		;GP1, I, bit0
IN1		EQU	2		;GP2, I, bit1
TXEN		EQU	3		;GP3, I, /送信イネーブル
IN2		EQU	4		;GP4, I, bit2
IN3		EQU	5		;GP5, I, bit3
;--------------------------------

GPIODIR		EQU	B'00111110'	;GPIO入出力設定
GPIOINI		EQU	B'00001000'	;GPIO InitValue
OPT_INI		EQU	B'00011100'	;OPTION Init

TXMODEINI	EQU	B'00000000'	;Tx-Mode Init

TX_IDLE		EQU	B'00011111'	; 'idle'
TX_START	EQU	B'00011000'	; 'start'
TX_END		EQU	B'00001101'	; 'end'
TX_ERR		EQU	B'00000100'	; 'error'

;--------------------------------

	CBLOCK	H'08'

	TXDATA			;送信データ
	TXMODE			;Tx mode

	TABLEINDEX		;TABLE index
	WAIT_CN			;WAIT counter
	WAIT_CN2		;WAIT counter2

	ENDC

;--------------------------------
;--------------------------------

	ORG	0		;リセット・ベクタ

;--------------------------------


POWERUP

	GOTO	SETUPPORTS

SETUPPORTS

	MOVLW	OPT_INI		;WAKE-UP,PULL-UP,1:16 WDT PRESCALER
	OPTION

	MOVLW	GPIODIR		;Set I/O direction
	TRIS	GPIO

	MOVLW	GPIOINI		;Init I/O data
	MOVWF	GPIO

	MOVLW	TXMODEINI	;Tx-Modeを初期化(通常モード)
	MOVWF	TXMODE

;--------------------------------

	BTFSC	STATUS,GPWUF
	GOTO	START		;GP Wake-UpならばStartへ

	SLEEP			;それ以外はSLEEP

;--------------------------------------------------------

	DT	"SDTC TX020322 by K.I"

;--------------------------------------------------------

START

	BTFSC	GPIO,TXEN	;/TxEが'H'ならば、スリープへ
	SLEEP	

	MOVLW	TX_IDLE
	CALL	SEND_TXDATA	;Idle信号送信
	CALL	WAIT_10US
	CALL	WAIT_10US
	MOVLW	TX_START
	CALL	SEND_TXDATA	;Start信号送信

	CALL	WAIT_4US
	NOP

REPEAT

	CALL	GET_TXDATA	;Switchデータを5ビット化して
	CALL	SEND_TXDATA	;Data送信

	BTFSC	GPIO,TXEN	;/TxEが'H'ならば、FINISHへ
	GOTO	FINISHX	

	BTFSC	TXMODE,0	;リピートモードなら繰り返す
	GOTO	REPEAT
	GOTO	FINISH

FINISHX

	CALL	WAIT_4US

FINISH

	CALL	WAIT_10US
	CALL	WAIT_4US
	MOVLW	TX_END
	CALL	SEND_TXDATA	;End信号送信

	GOTO	$+1		;WAIT_2US
	BCF	GPIO,TXD	;一応、TxDを'L'に戻すようにした

	CALL	WAIT_250MS	;約1秒待ち
	CALL	WAIT_250MS
	CALL	WAIT_250MS
	CALL	WAIT_250MS

	BTFSC	GPIO,TXEN	;/TxEが'H'ならスリープへ
	SLEEP

	BSF	TXMODE,0	;リピートモードへ移行して
	GOTO	START		;繰り返す

;--------------------------------

SEND_TXDATA

	MOVWF	TXDATA		;TXDATAの値を送信する(MSB first, Clock 833us)
				;送信クロック833us間隔(約1200bps)にWAIT調整

	BTFSC	TXDATA,4	;bit4 SEND
	CALL	XOR_TX
	CALL	WAIT_800US

	BTFSC	TXDATA,3	;bit3 SEND
	CALL	XOR_TX
	CALL	WAIT_826US

	BTFSC	TXDATA,2	;bit2 SEND
	CALL	XOR_TX
	CALL	WAIT_826US

	BTFSC	TXDATA,1	;bit1 SEND
	CALL	XOR_TX
	CALL	WAIT_826US

	BTFSC	TXDATA,0	;bit0 SEND
	CALL	XOR_TX
	CALL	WAIT_826US

	RETLW	0

;--------------------------------

XOR_TX
				;NRZIで送信するために
	MOVLW	1		;GP0を反転させる
	XORWF	GPIO,F		;(6US)

	RETLW	0

;--------------------------------

GET_TXDATA	;Switchの値を読んで、4B/5B変換する(16US)

	MOVLW	0
	MOVWF	TABLEINDEX	;CLEAR TABLEINDEX
	BTFSC	GPIO,IN0	;IN0 check
	BSF	TABLEINDEX,0
	BTFSC	GPIO,IN1	;IN1 check
	BSF	TABLEINDEX,1
	BTFSC	GPIO,IN2	;IN2 check
	BSF	TABLEINDEX,2
	BTFSC	GPIO,IN3	;IN3 check
	BSF	TABLEINDEX,3

	MOVF	TABLEINDEX,W	;Wに4bitデータを入れる

;--------------------------------
TAB4B5B		;4B/5B変換用テーブル

	ADDWF	PCL,F
	RETLW	B'00011110'	; '0'
	RETLW	B'00001001'	; '1'
	RETLW	B'00010100'	; '2'
	RETLW	B'00010101'	; '3'
	RETLW	B'00001010'	; '4'
	RETLW	B'00001011'	; '5'
	RETLW	B'00001110'	; '6'
	RETLW	B'00001111'	; '7'
	RETLW	B'00010010'	; '8'
	RETLW	B'00010011'	; '9'
	RETLW	B'00010110'	; 'A'
	RETLW	B'00010111'	; 'B'
	RETLW	B'00011010'	; 'C'
	RETLW	B'00011011'	; 'D'
	RETLW	B'00011100'	; 'E'
	RETLW	B'00011101'	; 'F'

;--------------------------------

WAIT_250MS

	MOVLW	250	;1001*250+5+1US=250.256MS

WAIT_MS

	MOVWF	WAIT_CN		;1001*CN+5 US

WAIT_MS0

	MOVLW	249		;1;249
	MOVWF	WAIT_CN2	;1;

WAIT_MS1

	NOP			;1;
	DECFSZ	WAIT_CN2,1	;1;
	GOTO	WAIT_MS1	;2;4usx249

	DECFSZ	WAIT_CN,1	;1;
	GOTO	WAIT_MS0	;2;WAIT_CN*1001us

	RETLW	0	;CALL(2)+(1)+(5+4*249)*CN+RET(2)=1001*CN+5US

;--------------------------------

WAIT_826US			;826US遅延(1200bps用)

	NOP			;1;
	GOTO	$+1		;2;
	MOVLW	163		;1;
	GOTO	WAIT_US		;2;3+5*163+5+3=826US

WAIT_800US			;800US遅延(1200bps用)

	GOTO	$+1		;2;
	MOVLW	158		;1;
	GOTO	WAIT_US		;2;2+5*158+5+3=800US

WAIT_10US

	GOTO	$+1		;2;
	GOTO	$+1		;2;
	GOTO	WAIT_4US	;2;

WAIT_101US

	MOVLW	19		;5*19+5+1=101US

WAIT_US

	MOVWF	WAIT_CN		;1;

WAIT_US0

	GOTO	$+1		;2;
	DECFSZ	WAIT_CN,1	;1;
	GOTO	WAIT_US0	;2;WAIT_CN*5us

WAIT_4US

	RETLW	0	;2;CALL(2)+(1)+(5)*CN+RET(2)=5*CN+5US

;--------------------------------

	END