; Infrared remote control for Nikon D70
; 
; (C) 03/2005 by Bighignoli Michele - Laives (BZ) - ITALY
;
; Version 1.0.0 - 03/2005
;
; IR led is controlled by PD0 (with NPN transistor).
; Led is "on" when PD0 is high.
;
; This code has tested with ATTiny2313 and ATMEGA8535 with 8.0 MHz Xtal
;
; Should work with every Atmel 8bit MCU
;
; This code is provided as-is without warranty and is released under the GNU General Pulic License (GPL)
;
;
; Special thanks to:
; ------------------
; Gerhard Schmidt (DG4FAC) - http://www.avr-asm-tutorial.net/index.html
; Brian Hammill - http://www.ipass.net/~hammill
;
;

.include "tn2313def.inc" ; ATTiny2313


.DEF DelayReg  = R23
.DEF MainLoopC = R22
.DEF Counter   = R21
.DEF Counter2  = R20


reset:
	rjmp	startup
	reti				; ext int 0 (not used)
	reti				; ext int 1 (not used)
	reti				; timer1 (not used)
	reti				;
	reti				;
	reti				; timer0 (not used)
	reti				; UART RRF Not Used
	reti				; UART TRE Not Used	
	reti				; UART TRDE Not Used 
	reti				; analog comparator not used


delay125:
; This is a 12.5 uS delay (100 cycles @ 8MHz)
;
; sbi/cbi = 2 cycles
; rcall = 3 cycles
;
	ldi		DelayReg,30	; 1 cycle
delay125_0:
	dec 	DelayReg	; 1 cycle
	brne	delay125_0	; 2 cycle if jump to label, 1 if not
	ret					; 4 cycles


; Code executed at startup

startup:
; stack is needed!
; initialize the stack pointer
;
; ENABLE IF "SPH" EXISTS
;	ldi		R16,HIGH(RAMEND)
;	out		SPH,R16

	ldi		R16,LOW(RAMEND)
	out		SPL,R16

; Set PortD = OUT
	ldi		R16,0xFF
	out		DDRD,R16


	ldi		MainLoopC,2	; Send a complete waveform 2 times

mainloop:

; Send start pulse (2.25 mS)
	ldi		Counter,90	; (12.5 uS * 2 ) * 90 = 2.25 mS
startpulse:
	sbi		PORTD,0		; Turn on LED
	rcall	delay125	; Wait 12.5 uS
	cbi		PORTD,0		; Turn off LED
	rcall	delay125	; wait 12.5 uS
	dec		Counter
	brne	startpulse

; Pause for 27.60 mS (=1104 cycles @ 40KHz)
	ldi		Counter,255
longpause1:
	nop					; 2 cycles like SBI or CBI
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	dec		Counter
	brne	longpause1
; Total pause = 255 * (12.5 uS * 8) = 25500 uS = 25.5 mS

; Wait 2.1 mS (=84 cycles @ 40KHz)
	ldi		Counter,84
longpause2:
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	dec		Counter
	brne	longpause2

; Send first pulse (650uS)
	ldi		Counter,26
pulse1:
	sbi		PORTD,0		; Turn on LED
	rcall	delay125
	cbi		PORTD,0		; Turn off LED
	rcall	delay125
	dec		Counter
	brne	pulse1

; Pause (1.375 mS)
	ldi		Counter,55
pause1:
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	dec		Counter
	brne	pause1

; Send 2nd pulse (575 uS)
	ldi		Counter,23
pulse2:
	sbi		PORTD,0
	rcall	delay125
	cbi		PORTD,0
	rcall	delay125
	dec		Counter
	brne	pulse2

; Pause (3.35 mS)
	ldi		Counter,134
pause2:
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	dec		Counter
	brne	pause2

; Send 3th pulse (650 uS)
	ldi		Counter,26
pulse3:
	sbi		PORTD,0
	rcall	delay125
	cbi		PORTD,0
	rcall	delay125
	dec		Counter
	brne	pulse3

	dec		MainLoopC
; No long pause before sleep
	breq	ContinueToSleep


; Pause for about 63mS (=10*254 cycles @ 40KHz)
	ldi		Counter,254
longpause3:
	ldi		Counter2,10
longpause3b:	
	nop
	nop
	rcall	delay125
	nop
	nop
	rcall	delay125
	dec		Counter2
	brne	longpause3b
	dec		Counter
	brne	longpause3

	rjmp	mainloop

ContinueToSleep:
	sleep
	rjmp	ContinueToSleep
