;erc1602
; I2C LCD DISPLAY Sample for MCS-48
; https://www.aitendo.com/product/17540
;
;	P24		I2C SDA		for ERC1602 I2C LCD DISPLAY
;	P25		I2C SCL		for ERC1602 I2C LCD DISPLAY
;
;	osc	6MHz

	cpu	8048
	page	0

ROMTOP	equ	0
RAMTOP	equ	020h		;Internal RAM Top Address
I2ADR_W	equ	3eh << 1	;ERC1602 I2C LCD DISPLAY ADDRESS to Write

	org	ROMTOP

	call	I2SETUP
	call	ldelay

	mov	R0,#38h	;Function (8bit N=1 2line 5x7fnt)
	call	I2CMD

	mov	R0,#39h	;Function (8bit N=1 2line 5x7fnt IS=1)
	call	I2CMD

	mov	R0,#1ch	;Internal OSC 183Hz bias 1/4
	call	I2CMD

	mov	R0,#72h	;Contrast low
	call	I2CMD

	mov	R0,#57h	;booster turn on
	call	I2CMD

	mov	R0,#6ch	;Follower control
	call	I2CMD

	mov	R0,#0fh	;Display On (display-on,cursor-on,cus.pos-on)
	call	I2CMD

	mov	R0,#01h	;Clear Display
	call	I2CMD

	mov	R0,#06h	;Entry Mode (directory-right)
	call	I2CMD

	mov	R0,#02h	;Return HOME
	call	I2CMD

	mov	R0,#'M'
	call	I2DATA
	mov	R0,#'C'
	call	I2DATA
	mov	R0,#'S'
	call	I2DATA
	mov	R0,#'4'
	call	I2DATA
	mov	R0,#'8'
	call	I2DATA

	mov	R0,#0C0h	;Pos.bottom line DDRAM=40h
	call	I2CMD
	mov	R0,#'>'	
	call	I2DATA

STOP:	jmp	STOP
;=======================================================================
;=======================================================================
; long delay Using R7,R6 (about 5ms)
ldelay:
	mov	R7,#100
$$j	mov	R6,#10
$$k	djnz	R6,$$k
	djnz	R7,$$j
	ret

; ----------------------------------------
; I2C Routine
; ----------------------------------------
SDA	equ	1<<4	;P24 I2C SDA
SCL	equ	1<<5	;P25 I2C SCL

SDA_LOW		MACRO
	anl	P2,#(~SDA)
	ENDM

SDA_HIGH	MACRO
	orl	P2,#(SDA)
	ENDM

SCL_LOW	MACRO
	anl	P2,#(~SCL)
	ENDM

SCL_HIGH	MACRO
	orl	P2,#(SCL)
	ENDM

; INIT I2C
I2SETUP:
	SDA_HIGH
	SCL_HIGH
	ret

; START I2C
I2START:
	SDA_HIGH
	SCL_HIGH
	nop
	nop
	nop
	nop
	SDA_LOW
	nop
	nop
	nop
	nop
	SCL_LOW
	ret

; STOP I2C
I2STOP:
	SDA_LOW
	SCL_HIGH
	nop
	nop
	SDA_HIGH
	nop
	nop
	ret

; PUT Acc to I2C FORMAT
; In Acc
; Broken: R7
; After Check SDA; L=ACK,H=BUSY
I2PUT:
	mov	R7,#8
$$loop 	jb7	$$set
	SDA_LOW
	jmp	$$next
$$set	SDA_HIGH
	nop
	nop
$$next	SCL_HIGH
	nop
	nop
	SCL_LOW
	rl	a
	djnz	R7,$$loop
	SCL_HIGH
	SDA_HIGH
;wait ACK
$$ack	in	a,P2
	anl	a,#SDA
	jnz	$$ack
	SCL_LOW
	ret

; CMD PUT Acc to I2C FORMAT
; In R0
; Broken: R7
I2CMD:
	call	I2START
	mov	a,#I2ADR_W
	call	I2PUT
	mov	a,#00h
	call	I2PUT
	mov	a,R0
	call	I2PUT
	call	I2STOP
	ret


; DATA PUT Acc to I2C FORMAT
; In R0
; Broken: R7
I2DATA:
	call	I2START
	mov	a,#I2ADR_W
	call	I2PUT
	mov	a,#40h
	call	I2PUT
	mov	a,R0
	call	I2PUT
	call	I2STOP
	ret


