;--------------------------------------------------------
; File: Sinewave.asm
; December 21 2006
; Wagner Lipnharski (wagner@ustr.net)
; processor Atmel AVR AtTiny13
;
; Description: Example of how to use the fast PWM of the
;		ATtiny13 to generate "sine-wave" signal.
;
;		The PWM output requires filtering to shape
;		the sine wave form.  The filter may be composed
;       by a simply 10k resistor connected to the PB1 pin
;       to a 100nF capacitor to ground. This output may
;       be boosted by an operational amplifier.
;
;---------------------------------------------------------
;
; You must program AtTiny13 Fuse:
; Internal RC Oscillator 9.6MHz Start-Up time: 14CK + 64ms
;
;---------------------------------------------------------

.include "tn13def.inc"		

.Def	Temp1		= R15
.Def	Temp		= R16
.Def	Temp2		= R17

.Def	TablePtr	= R18

.Def	Tone1		= R19
.Def	Tone1Temp	= R20

.Def	Tempo		= R21

.Def	SineCntr	= R22
.Def	SineCntrTmp	= R23

.Def	Skipper		= R24
.Def	KeyNumber	= R25		; Key A5=0, Key B7=15

.Def	PlayerL		= R26
.Def	PlayerH		= R27



;Initialization

.cseg
.org $000
			Rjmp	Init


;***********************************************
; MUSIC TO PLAY - Change this Table
;***********************************************
		; [Zero, KeyNumber, Tempo, Pause]
		; KeyNumber 0-15
		; Tempo 1-50 (aprox 200ms each)
		; Pause 1-50 (aprox 5ms each)
		; End table with 255,255,255,255

Music:
	; We wish you a Merry Christmas
	.db	0,6,4,3
	.db    	0,9,4,4
	.db	0,9,2,3
	.db    	0,10,2,3
	.db    	0,9,2,3
	.db    	0,8,2,3
	.db    	0,7,4,3
	.db    	0,7,2,15

	.db	0,7,4,3
	.db	0,10,4,4
	.db	0,10,2,3
	.db	0,11,2,3
	.db	0,10,2,3
	.db	0,9,2,3
	.db	0,8,4,3
	.db	0,6,2,15

	.db	0,6,4,3
	.db	0,11,4,4
	.db	0,11,2,3
	.db	0,12,2,3
	.db	0,11,2,3
	.db	0,10,2,3
	.db	0,9,4,3
	.db	0,7,2,15
	.db	0,6,2,3
	.db	0,6,2,3
	.db	0,7,4,3
	.db	0,10,4,3
	.db	0,8,4,3
	.db	0,9,8,80

	; NOEL First Part
	.db	0,4,2,3		; Key=4, Tempo=2, Pause=3
	.db	0,3,2,3		; Key=3, Tempo=2, Pause=3
	.db	0,2,6,3
	.db	0,3,2,3
	.db	0,4,2,3
	.db	0,5,2,3
	.db	0,6,6,15
	.db	0,7,2,3
	.db	0,8,2,3
	.db	0,9,4,3
	.db	0,8,4,3
	.db	0,7,4,3
	.db	0,6,6,30
	.db	0,9,4,3
	.db	0,8,4,3
	.db	0,7,4,3
	.db	0,6,4,3
	.db	0,7,4,3
	.db	0,8,4,3
	.db	0,9,4,3
	.db	0,6,4,3
	.db	0,5,4,3
	.db	0,4,4,30

	; NOEL Second Part
	.db	0,4,2,3		
	.db	0,3,2,3		
	.db	0,2,6,3
	.db	0,3,2,3
	.db	0,4,2,3
	.db	0,5,2,3
	.db	0,6,6,15
	.db	0,9,2,3
	.db	0,8,2,3
	.db	0,9,4,3
	.db	0,8,4,3
	.db	0,7,4,3
	.db	0,6,6,30
	.db	0,9,4,3
	.db	0,8,4,3
	.db	0,7,4,3
	.db	0,6,4,3
	.db	0,7,4,15
	.db	0,8,2,3
	.db	0,9,4,3
	.db	0,6,4,3
	.db	0,5,4,3
	.db	0,4,4,80

	.db	255,255,255,255  ; <=== End of Music to Play 


;***********************************************
; INITIALIZATION
;***********************************************

INIT:

; Set PB0 and PB1 as output

		Ldi 	Temp, (1<<PB0) | (1<<PB1)	
		Out 	DDRB, Temp

; Set PWM Mode
; Togle OC1A on Compare

		Ldi	Temp, (1<<COM0A1) |(1<<WGM00) |(1<<WGM01)
		Out	TCCR0A, Temp						

; Set PWM Clock equal to Internal Clock

		Ldi 	Temp,  (1<<CS00) 
		Out 	TCCR0B, Temp						

		Clr 	TablePtr
		Clr 	r18

;***********************************************
; WILL READ "MUSIC TO PLAY" AND PLAY IT
;***********************************************

MusicLoop:	
		Ldi 	PlayerH,High(Music*2)
		Ldi 	PlayerL,Low(Music*2)
MusicLoop1:
		Mov	ZL,PlayerL
		Mov	ZH,PlayerH
		Clr	Temp
		Adiw	ZL,1
		Lpm
		Mov	KeyNumber,R0
		Cpi	KeyNumber,255
		Breq	MusicLoop

		Adiw	ZL,1
		Lpm
		Mov	Tempo,R0

		Adiw	ZL,1
		Lpm
		Mov	Temp2,R0

		Push	Temp2
		Adiw	ZL,1
		Mov	PlayerL,ZL
		Mov	PlayerH,ZH
		Rcall	Get_Tone
		Pop	Temp2

		Rcall	Delay1	
		Rjmp	MusicLoop1

;***********************************************
; FIND PIANO KEY PROPERTIES (Frequency, etc)
;***********************************************

Get_Tone:	Ldi 	ZH,High(KeysTable*2)	
		Ldi 	ZL,Low(KeysTable*2)
		Lsl	KeyNumber
		Lsl	KeyNumber
		Inc	KeyNumber
		Clr	Temp

		Add 	ZL,KeyNumber	
		Adc 	ZH,Temp
		Lpm				
		Mov 	Tone1,R0

		Adiw	ZL,1
		Lpm
		Mov	SineCntr,R0

		Adiw	ZL,1
		Lpm
		Mov	Skipper,R0

;***********************************************
; CREATE SINEWAVE AND TEMPO IT, According to Key
;***********************************************

Player1:	Clr	Temp1
Player2:	Mov	SineCntrTmp,SineCntr
Player3:	Mov	Tone1Temp,Tone1
		Rcall	Set_PWM

		Dec	Tone1Temp
		Brne	PC-1

		Dec	Temp1
		Brne	Player3
				
		Sub	SineCntrTmp,Skipper
		Brcc	Player3

		Dec	Tempo
		Brne	Player2

		Ret


Delay1:		Clr	Temp
		Dec	Temp
		Brne	Pc-1

		Dec	Temp1
		Brne	PC-3

		Dec	Temp2
		Brne	Pc-5

		Ret


Set_PWM:
		Ldi 	ZH, High(sine_table*2)	
		Ldi 	ZL, Low(sine_table*2)
  		Clr	Temp
		Add 	ZL, TablePtr	
		Adc 	ZH, Temp
		Lpm				
		Out 	OCR0A, R0
		Add 	TablePtr,Skipper
		Ret

;***********************************************
; PIANO KEY PROPERTIES (Frequency, etc)
;***********************************************

KeysTable:
	
	; 00, Tone, SineCntr, Skipper

	.db	00,22,44,1		; A5
	.db	00,44,49,2		; B5
	.db     00,65,53,3		; C5
	.db	00,36,59,2		; D5
	.db	00,88,66,5		; E5
	.db	00,47,70,3		; F5
	.db	00,89,79,6		; G5
	.db	00,107,88,8		; A6
	.db	00,95,99,8		; B6
	.db	00,89,106,8		; C6
	.db	00,79,119,8		; D6
	.db	00,79,132,9		; E6
	.db	00,74,141,9		; F6
	.db	00,73,159,10		; G6
	.db	00,41,176,8		; A7
	.db	00,36,198,8		; B7

;***********************************************
; SINEWAVE VALUES
;***********************************************

sine_table:
	.db 128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174
	.db 177,179,182,185,188,191,193,196,199,201,204,206,209,211,213,216
	.db 218,220,222,224,226,228,230,232,234,235,237,239,240,241,243,244
	.db 245,246,248,249,250,250,251,252,253,253,254,254,254,254,254,254
	.db 254,254,254,254,254,254,254,253,253,252,251,250,250,249,248,246
	.db 245,244,243,241,240,239,237,235,234,232,230,228,226,224,222,220
	.db 218,216,213,211,209,206,204,201,199,196,193,191,188,185,182,179
	.db 177,174,171,168,165,162,159,156,153,150,147,144,140,137,134,131
	.db 128,125,122,119,116,112,109,106,103,100,97,94,91,88,85,82
	.db 79,77,74,71,68,65,63,60,57,55,52,50,47,45,43,40
	.db 38,36,34,32,30,28,26,24,22,21,19,17,16,15,13,12
	.db 11,10,8,7,6,6,5,4,3,3,2,2,2,1,1,1
	.db 1,1,1,1,2,2,2,3,3,4,5,6,6,7,8,10
	.db 11,12,13,15,16,17,19,21,22,24,26,28,30,32,34,36
	.db 38,40,43,45,47,50,52,55,57,60,63,65,68,71,74,77
	.db 79,82,85,88,91,94,97,100,103,106,109,112,116,119,122,125


;  Piano Scale, the first note below, "C", is from the
;  the 4th octave, 262Hz (261.6256Hz) and so on.
;  The first "A" below, 440Hz is the A5 (fifth octave).
;  The numbers nnn/x, means values to be loaded at Tone1
;  and Skipper at the Keys on the Key Labels setup.
;  The value in (parentesys) below is the aproximately
;  frequency the circuit generates based on the setup.

;  C4:  262Hz 109/3 (265.4)
;  Db4: 277
;  D4:  297    99/3 (298)
;  Eb4: 311
;  E4:  330    89/3 (329.5)
;  F4:  349    83/3 (351.5)
;  Gb4: 370
;  G4:  392    73/3 (396)
;  Ab4: 415
;  A5:  440Hz  22/1 (440.5) 
;  Bb5: 466Hz
;  B5:  494Hz  44/2 (496)   78/4 (497)
;  C5:  523Hz  65/3 (530)   73/4 (528)
;  Db5: 554
;  D5:  587Hz 46/3 (600)   64/4 (595)
;  Eb5: 622
;  E5:  659Hz 41/3 (664)   57/4 (664) 
;  F5:  698Hz 38/3 (708)   53/4 (706)  68/5 (704.4)
;  Gb5  740
;  G5:  784Hz 33/3 (798)   46/4 (800)  60/5 (789)
;  Ab5  831  
;  A6:  880Hz 29/3 (889)   40/4 (885)  53/5 (882)
;  Bb6  932
;  B6:  987Hz 26/3 (971)   36/4 (989)
;  C6:  1046  23/3 (1071)  32/4 (1065) 47/5 (1061)  53/6(1059) 63/7(1058)
;  Db6  1109
;  D6:  1174  20/3 (1193)  28/4 (1185) 38/5 (1181)
;  Eb6  1245
;  E6:  1318  17/3 (1346)  25/4 (1336) 33/5 (1331)  41/6(1327)
;  F6:  1396  16/3 (1407)
;  Gb6  1480
;  G6:  1567  15/3 (1545)  20/4 (1591) 27/5 (1570)  33/6(1597) 40/7(1582)
;  Aa6  1661
;  A7:  1760
;  Bb7  1865  35/7(1774)   41/8(1770)
;  B7:  1975  31/7(1963)   36/8(1978)   
;  C7:  2093  58/13(2116)  53/12(2117) 63/14(2114) 
;  Dd7  2217
;  D7:  2349  7/3(2356)    20/6(2386) 29/8(2371) 
