;------------------------------------------------------------------------------
; Title       : ps.asm
; Description : IR Object Perception Sensor
; Author      : KAWAMOTO "nanashino" Yasuhisa
; Email       : nanashi@yk.rim.or.jp
; Date        : 04/23/2000
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; History     : 04/23/2000  動作クロックを10MHzから4MHzに変更
;               04/22/2000  初期バージョン
;------------------------------------------------------------------------------

.include "1200def.inc"

;--  Modulation-freq(38.4KHz) and Baudrate(2400bps) setting --
.equ	N=52			; 13us@4.0MHz and R=1
;.equ	N=130			; 13us@10.0MHz and R=1
.equ	R=1			; 1/1
.equ	W=32			; 

;-- Global register --
.def	t_tmp		=r16	; Scratch register
.def	t_sr		=r17	; Status register storage
.def	t_reload	=r18	; Reload register
.def	t_msk		=r19	; PORT mask register
.def	t_trn_bit	=r20	; Tramsmit bit register
.def	t_trn_st	=r21	; Status register
.def	t_trn_wc	=r22	; Wait counter
.def	t_wave		=r23	; Modulation wave register
.def	tmp		=r24	; Scratch register
.def	tmp2		=r25	; Scratch register2
.def	trn_dt		=r26	; Tramsmit data register
.def	one_c		=r27	; one counter

;-- Bit position in Status register --
.equ	TD		=0	; Tramsmit ready bit

	.cseg
;-- Reset and interrupt vector --
	.org $0000
	rjmp	main		; Reset handler
	.org INT0addr
	reti			; External interrupt handler (Not Used)
	.org OVF0addr
	rjmp	tim0_ovf	; Timer0 overflow handler
	.org ACIaddr
	reti			; Analog comparator handler (Not Used)

;-- Timer0 overflow handler --
tim0_ovf:
	in	t_sr,SREG		; Store SREG
	out	TCNT0,t_reload		; Reload timer
;-- Modulation wave output --
	com	t_wave
	mov	t_tmp,t_trn_bit
	or	t_tmp,t_wave
	or	t_tmp,t_msk
	out	PORTB,t_tmp
	dec	t_trn_wc
	brne	trn_skip
	ldi	t_trn_wc,W
	sbr	t_trn_st,(1<<TD)
trn_skip:
	out	SREG,t_sr		; Restore SREG
	reti

;-- Init hardware --
init:
	ldi	t_reload,(256-N+8)	; Set reload value
	ldi	t_wave,0
	ldi	t_trn_bit,$ff
	ldi	t_trn_wc,W
	ldi	tmp,0b11111111
	out	DDRB,tmp
	ldi	tmp,0b11111111
	out	PORTB,tmp
	ldi	tmp,0b01111111
	out	DDRD,tmp
	ldi	tmp,0b01111111
	out	PORTD,tmp
	ldi	tmp,R
	out	TCCR0,tmp		; Start timer and set clock source
	out	TCNT0,t_reload
	ldi	tmp,(1<<TOV0)		; Clear T/C0 overflow flag
	out	TIFR,tmp
	ldi	tmp,(1<<TOIE0)		; Enable T/C0 overflow interrupt
	out	TIMSK,tmp
	ret

;-- Data transmit --
transmit:
	ldi	tmp,8
	ldi	one_c,0
trn_st:
	sbrs	t_trn_st,TD
	rjmp	trn_st
	cbr	t_trn_st,(1<<TD)
	clr	t_trn_bit
trn_d:
	sbrs	t_trn_st,TD
	rjmp	trn_d
	cbr	t_trn_st,(1<<TD)
	clr	tmp2
	ror	trn_dt
	brcc	trn_d0
	ser	tmp2
	inc	one_c
trn_d0:
	mov	t_trn_bit,tmp2
	dec	tmp
	brne	trn_d
trn_pt:
	sbrs	t_trn_st,TD
	rjmp	trn_pt
	cbr	t_trn_st,(1<<TD)
	clr	tmp2
	sbrs	one_c,0
	ser	tmp2
	mov	t_trn_bit,tmp2
trn_sp:
	sbrs	t_trn_st,TD
	rjmp	trn_sp
	cbr	t_trn_st,(1<<TD)
	ser	t_trn_bit
	ret

;-- Main --
main:
	rcall	init			; Init
	sei				; Enable interrupt
loop:
	ldi	t_msk,0b11111110	; Right LED
	ldi	trn_dt,$55
	rcall	transmit
	ldi	trn_dt,$ff
	rcall	transmit
	ldi	trn_dt,$00
	rcall	transmit
	ldi	trn_dt,$f7
	rcall	transmit
	ldi	trn_dt,$08
	rcall	transmit
	ldi	trn_dt,$be
	rcall	transmit
	ldi	trn_dt,$41
	rcall	transmit
	ldi	trn_dt,$b5
	rcall	transmit
	ldi	trn_dt,$4a
	rcall	transmit

	ldi	t_msk,0b11111101	; Left LED
	ldi	trn_dt,$55
	rcall	transmit
	ldi	trn_dt,$ff
	rcall	transmit
	ldi	trn_dt,$00
	rcall	transmit
	ldi	trn_dt,$f7
	rcall	transmit
	ldi	trn_dt,$08
	rcall	transmit
	ldi	trn_dt,$bf
	rcall	transmit
	ldi	trn_dt,$40
	rcall	transmit
	ldi	trn_dt,$b6
	rcall	transmit
	ldi	trn_dt,$49
	rcall	transmit

	rjmp	loop
