welcome: please sign in
location: Diff for "Delay700msStereo"
Differences between revisions 2 and 3
Revision 2 as of 2010-08-13 07:41:38
Size: 8391
Editor: guest
Comment:
Revision 3 as of 2010-08-13 07:42:46
Size: 8395
Editor: guest
Comment:
Deletions are marked like this. Additions are marked like this.
Line 4: Line 4:
[[attachment:delay_700ms_stereo|delay_700ms_stereo.asm]] [[attachment:delay_700ms_stereo.asm|delay_700ms_stereo.asm]]

700ms Stereo Delay

delay_700ms_stereo.asm


; program: delay-16b-pot.asm
; UID = 000003 - unique id to eliminate conflicts between variables
; 16b address space (.7s delay time)
; stereo data
; pot (MOD1) controlled delay time (3ms - 700ms)

; program overview
;
; data is read in from memory and written out the codec at the same time
; new data is written to the memory from the codec.  ADC0 (MOD1) is read
; and averaged over 256 samples to reduce jitter.  this value is subtracted
; from the write address to create the desired read address.  if the actual
; read address doesnt match the desired read address, it is either
; incremented or decremented by one sample each sample period until it
; matches.  this reduces noise during delay time transitions.

; register usage - may be redefined in other sections
;
; r0  
; r1  
; r2  left lsb out
; r3  left msb out
; r4  right lsb out
; r5  right msb out
; r6  left lsb in
; r7  left msb in
; r8  right lsb in
; r9  right msb in
; r10 adc accumulator fractional byte
; r11 adc accumulator lsb
; r12 actual delay lsb
; r13 actual delay msb
; r14 adc sample counter
; r15 switch sample counter
; r16 temporary swap register
; r17 temporary swap register
; r18 
; r19 adc accumulator msb
; r20 
; r21 
; r22 null register
; r23 read address third byte
; r24 write address lsb
; r25 write address msb
; r26 desired delay lsb
; r27 desired delay msb
; r28 read address lsb
; r29 read address msb
; r30 jump location for interrupt lsb
; r31 jump location for interrupt msb
; t   

;program starts here first time
ldi r30,$25 ; set jump location to program start
clr r24 ; clear write register
clr r25
ldi r22,$00 ; setup write address high byte
clr r18 ; setup r18 as null register for carry addition and ddr setting
ldi r17,$ff ; setup r17 for ddr setting

clear_000003: ; clear delay buffer
; eliminates static when first switching to the delay setting

adiw r25:r24,$01 ; increment write register
adc r22,r18 ; increment write third byte
cpi r22,$01 ; check if 16b memory space has been cleared
breq cleardone_000003 ; continue until end of buffer reached
out portd,r24 ; set address
sts porth,r25
out portg,r22 ; pull ce low,we low,and set high bits of address
out ddra,r17 ; set porta as output for data write
out ddrc,r17 ; set portc as output for data write
out porta,r18 ; set data
out portc,r18 ; r18 is cleared above
sbi portg,portg2 ; pull we high to write
out ddra,r18 ; set porta as input for data lines
out ddrc,r18 ; set portc as input for data lines
rjmp clear_000003 ; continue clearing

cleardone_000003: ; reset registers

clr r24 ; clear write register
clr r25
ldi r22,$00 ; setup null register
clr r28 ; set read address to minimum delay
ldi r29,$ff
ldi r23,$04 ; setup read address high byte
clr r21 ; set actual delay time to minimum delay
ldi r16,$01
mov r13,r16
clr r12
clr r2 ; initialize data output registers
clr r3
clr r4
clr r5
reti ; finish with initialization and wait for next interrupt

;program starts here every time but first
;initiate data transfer to codec
sbi portb,portb0 ; toggle slave select pin
out spdr,r3 ; send out left channel msb
cbi portb,portb0

;increment sram address
adiw r25:r24,$01 ; increment write address
adiw r29:r28,$01 ; increment read address

wait1_000003: ; check if byte has been sent

in r17,spsr
sbrs r17,spif
rjmp wait1_000003
in r7,spdr ; recieve in left channel msb
out spdr,r2 ; send out left channel lsb

;get left channel data from sram
out portd,r28 ; set address
sts porth,r29
nop ; wait input latch time of 2 clock cycles
nop ; wait input latch time of 2 clock cycles
in r2,pina ; get data
in r3,pinc ; get data
adiw r29:r28,$01 ; increment read address

wait2_000003: ; check if byte has been sent

in r17,spsr
sbrs r17,spif
rjmp wait2_000003
in r6,spdr ; recieve in left channel lsb
out spdr,r5 ; send out right channel msb

;write left channel data to sram
out portd,r24 ; set address
sts porth,r25
out portg,r22 ; pull ce low,we low,and set high bits of address
ldi r17,$ff
out ddra,r17 ; set porta as output for data write
out ddrc,r17 ; set portc as output for data write
out porta,r6 ; set data
out portc,r7
sbi portg,portg2 ; pull we high to write
out ddra,r22 ; set porta as input for data lines
out ddrc,r22 ; set portc as input for data lines

wait3_000003: ; check if byte has been sent

in r17,spsr
sbrs r17,spif
rjmp wait3_000003
in r9,spdr ; recieve in right channel msb
out spdr,r4 ; send out right channel lsb

;get right channel data from sram
out portd,r28 ; set address
sts porth,r29
nop ; wait input latch time of 2 clock cycles
nop ; wait input latch time of 2 clock cycles
in r4,pina ; get data
in r5,pinc ; get data
adiw r25:r24,$01 ; increment write address

wait4_000003: ; check if byte has been sent

in r17,spsr
sbrs r17,spif
rjmp wait4_000003
in r8,spdr ; recieve in left channel lsb

;write right channel data to sram
out portd,r24 ; set address
sts porth,r25
out portg,r22 ; pull ce low,we low,and set high bits of address
ldi r17,$ff
out ddra,r17 ; set porta as output for data write
out ddrc,r17 ; set portc as output for data write
out porta,r8 ; set data
out portc,r9
sbi portg,portg2 ; pull we high to write
out ddra,r22 ; set porta as input for data lines
out ddrc,r22 ; set portc as input for data lines

;get delay settings
lds r17,adcsra ; get adc control register
sbrs r17,adif ; check if adc conversion is complete
rjmp shift_000003 ; skip adc sampling
lds r16,adcl ; get low byte adc value
lds r17,adch ; get high byte adc value
add r10,r16 ; accumulate adc samples
adc r11,r17
adc r19,r22 ; r22 is cleared above
ldi r17,$f7
sts adcsra,r17 ; clear interrupt flag
dec r14 ; countdown adc sample clock
brne shift_000003 ; get delay time if its been long enough
lsr r19 ; divide adc sample by 4
ror r11 ; makes adc value a 16b number
ror r10
lsr r19
ror r11
ror r10
ldi r16,$01 ; check if delay is below minimum
cp r10,r22 ; r22 is cleared above
cpc r11,r16
brsh deadband_000003 ; check if adc value changed enough to update delay
clr r10 ; set minimum delay to $0100 = 3ms
mov r11,r16

deadband_000003: ; set the low value of the delay

movw r17:r16,r11:r10 ; move adc sample to temporary register
sbc r16,r26 ; find difference between adc sample and desired delay time
sbc r17,r27
brsh check_000003 ; check for deadband if positive
neg r16 ; invert if negative
adc r17,r22 ; r22 is cleared above
neg r17 ; converts ones complement to twos complement

check_000003: ; check if difference is greater than deadband

cpi r16,$40 ; check if difference is less than 1 lsb of adc
cpc r17,r22 ; r22 cleared above
brlo empty_000003 ; do nothing if less than 1 lsb
movw r27:r26,r11:r10 ; move adc sample to delay time if large enough change
andi r26,$fc ; make sure delay time is a multiple of 4

empty_000003: ; empty accumulation registers and finish off

clr r10 ; empty accumulation registers
clr r11
clr r19

shift_000003: ; check if delay time is correct

cp r26,r12 ; compare desired delay to actual delay
cpc r27,r13
breq switchsample_000003 ; do nothing if the same
brlo indexdown_000003
ldi r17,$04 ; increment delay register (4 is used for stereo data)
add r12,r17 ; this makes it play forward at double speed
adc r13,r22 ; until desired delay is reached
rjmp switchsample_000003

indexdown_000003:

ldi r17,$02 ; decrement delay register (2 is used for stereo data)
sub r12,r17 ; this makes is play backwards until desired delay is reached
sbc r13,r22 ; r22 is cleared above

switchsample_000003: ; check state of rotary switch

dec r15 ; countdown switch counter
brne done_000003 ; finish off if not ready yet
lds r16,pinj ; get switch data
andi r16,$78 ; mask off rotary switch
lsr r16 ; adjust switch position to program memory location
lsr r16
ldi r17,$02
add r16,r17
cp r16,r31 ; check if location has changed
breq done_000003 ; finish off if no change
clr r30 ; reset jump register to new function if changed
mov r31,r16

done_000003:

movw r29:r28,r25:r24 ; move write address to read destination register
sub r28,r12 ; remove delay time
sbc r29,r13
reti ; return to waiting

Delay700msStereo (last edited 2010-08-21 02:04:28 by guest)