; ; PWM wavetable program ; ; definitions ; .include "tn13def.inc" .def temp = R16 ; temporary storage .def temp1 = R17 ; temporary storage .def sample_count = R18 ;step through samples in wave .def cycle_count = R19 ;count number of waves .equ NUM_WAVES = 255 ;num waves to send .def delay_count = R20 ;count delay between samples .def sample_delay = R21 ;store the delay between samples .def temp2 = R22 .def txbyte = R23 .def bitcnt = R24 ; ; interrupt vectors ; .cseg .org 0 rjmp reset ;.org TIM0_OVF0addr ??? ; ; waveform ; first byte = number of samples ; wave: .db 99,191,195,199,203,207,211,215,218,222 .db 225,229,232,235,238,240,243,245,247,249 .db 250,252,253,254,254,254,254,254,254,253 .db 252,251,250,248,246,244,242,239,236,233 .db 230,227,224,220,216,213,209,205,201,197 .db 193,189,185,181,177,173,169,166,162,158 .db 155,152,149,146,143,140,138,136,134,132 .db 131,130,129,128,128,128,128,128,128,129 .db 130,132,133,135,137,139,142,144,147,150 .db 153,157,160,164,167,171,175,179,183,187 ; ; notes ; first byte = number of notes ; following notes are specified by the delay between samples ; and then the number of cycles ; ;notes: ; .db 18,5,250,5,250,5,250,5,250,5,250,5,250,10,250,10,250,10,250,20,250,20,250,20,250,15,250,30,200,40,100,35,100,35,100,25,200 ; ;send out NUM_WAVES of audio at our frequency. outputBurst: ldi cycle_count, NUM_WAVES AnotherCycle: ldi zl, low(wave*2) ldi zh, high(wave*2) lpm sample_count, Z+ SampleLoop: lpm temp, Z+; read sample out OCR0B, temp ; update PWM mov delay_count, sample_delay SampleDelayLoop: dec delay_count brne SampleDelayLoop dec sample_count ; decrease sample count brne SampleLoop ;done with one cycle dec cycle_count brne AnotherCycle ret ; ;this function takes the same time as the above that outputs audio, but doesn't output anything. ;this is useful for click timing. outputBurstNO: ldi cycle_count, NUM_WAVES AnotherCycleNO: ldi zl, low(wave*2) ldi zh, high(wave*2) lpm sample_count, Z+ SampleLoopNO: lpm temp, Z+; read sample nop ;out OCR0B, temp ; update PWM mov delay_count, sample_delay SampleDelayLoopNO: dec delay_count brne SampleDelayLoopNO dec sample_count ; decrease sample count brne SampleLoopNO ;done with one cycle dec cycle_count brne AnotherCycleNO ret clickdelay: ldi temp2, 5 DelayOuterOuter: ldi temp1, 250 DelayOuter: ldi temp, 250 DelayInner: dec temp brne DelayInner dec temp1 brne DelayOuter dec temp2 brne DelayOuterOuter ret ; ; putclick ; send char in txbyte clicks ; -converted from the dc-power example, calls to sbi(cbi) PORTB, mosfetpin have been changed to ; a call to outputBurst to output a "click" of audio putclick: ldi bitcnt, 8 sec; set start bit ; ; send start clicks ; rcall outputBurst ;sbi PORTB, mosfetpin ;rcall outputBurstNO ;cbi PORTB, mosfetpin rcall clickdelay rcall outputBurst ;sbi PORTB, mosfetpin ;rcall outputBurstNO ;cbi PORTB, mosfetpin rcall clickdelay ; ; send data clicks ; putclick0: lsr txbyte; get next bit brcc putclick1; if carry set, send a 1 click rcall outputBurst ;sbi PORTB, mosfetpin ;rcall outputBurstNO ;cbi PORTB, mosfetpin rcall clickdelay ;rcall outputBurstNO ;cbi PORTB, mosfetpin rcall outputBurstNO ;cbi PORTB, mosfetpin rcall clickdelay rjmp putclick2; otherwise ... putclick1: rcall outputBurstNO ;cbi PORTB, mosfetpin; ... send a 0 click ;rcall outputBurstNO ;cbi PORTB, mosfetpin rcall clickdelay rcall outputBurst ;sbi PORTB, mosfetpin ;rcall outputBurstNO ;cbi PORTB, mosfetpin rcall clickdelay putclick2: dec bitcnt; if not all bits sent brne putclick0; send next bit ; ; send stop clicks ; ;rcall outputBurst ;sbi PORTB, mosfetpin ;rcall outputBurstNO ;cbi PORTB, mosfetpin rcall clickdelay ;rcall outputBurst ;sbi PORTB, mosfetpin ;rcall outputBurstNO ;cbi PORTB, mosfetpin rcall clickdelay ret; ; ; clickdelay ; delay between clicks ; shortdelay: ldi temp, 200 clickdelayloop: dec temp brne clickdelayloop ret ; ; main program ; reset: ; ; initialization ; ldi temp, low(RAMEND) out SPL, temp ; set stack pointer to top of RAM ldi temp, (1<