Attachment 'delay_700ms_stereo.asm'
Download 1 ; program: delay-16b-pot.asm
2 ; UID = 000003 - unique id to eliminate conflicts between variables
3 ; 16b address space (.7s delay time)
4 ; stereo data
5 ; pot (MOD1) controlled delay time (3ms - 700ms)
6
7 ; program overview
8 ;
9 ; data is read in from memory and written out the codec at the same time
10 ; new data is written to the memory from the codec. ADC0 (MOD1) is read
11 ; and averaged over 256 samples to reduce jitter. this value is subtracted
12 ; from the write address to create the desired read address. if the actual
13 ; read address doesnt match the desired read address, it is either
14 ; incremented or decremented by one sample each sample period until it
15 ; matches. this reduces noise during delay time transitions.
16
17 ; register usage - may be redefined in other sections
18 ;
19 ; r0
20 ; r1
21 ; r2 left lsb out
22 ; r3 left msb out
23 ; r4 right lsb out
24 ; r5 right msb out
25 ; r6 left lsb in
26 ; r7 left msb in
27 ; r8 right lsb in
28 ; r9 right msb in
29 ; r10 adc accumulator fractional byte
30 ; r11 adc accumulator lsb
31 ; r12 actual delay lsb
32 ; r13 actual delay msb
33 ; r14 adc sample counter
34 ; r15 switch sample counter
35 ; r16 temporary swap register
36 ; r17 temporary swap register
37 ; r18
38 ; r19 adc accumulator msb
39 ; r20
40 ; r21
41 ; r22 null register
42 ; r23 read address third byte
43 ; r24 write address lsb
44 ; r25 write address msb
45 ; r26 desired delay lsb
46 ; r27 desired delay msb
47 ; r28 read address lsb
48 ; r29 read address msb
49 ; r30 jump location for interrupt lsb
50 ; r31 jump location for interrupt msb
51 ; t
52
53 ;program starts here first time
54 ldi r30,$25 ; set jump location to program start
55 clr r24 ; clear write register
56 clr r25
57 ldi r22,$00 ; setup write address high byte
58 clr r18 ; setup r18 as null register for carry addition and ddr setting
59 ldi r17,$ff ; setup r17 for ddr setting
60
61 clear_000003: ; clear delay buffer
62 ; eliminates static when first switching to the delay setting
63
64 adiw r25:r24,$01 ; increment write register
65 adc r22,r18 ; increment write third byte
66 cpi r22,$01 ; check if 16b memory space has been cleared
67 breq cleardone_000003 ; continue until end of buffer reached
68 out portd,r24 ; set address
69 sts porth,r25
70 out portg,r22 ; pull ce low,we low,and set high bits of address
71 out ddra,r17 ; set porta as output for data write
72 out ddrc,r17 ; set portc as output for data write
73 out porta,r18 ; set data
74 out portc,r18 ; r18 is cleared above
75 sbi portg,portg2 ; pull we high to write
76 out ddra,r18 ; set porta as input for data lines
77 out ddrc,r18 ; set portc as input for data lines
78 rjmp clear_000003 ; continue clearing
79
80 cleardone_000003: ; reset registers
81
82 clr r24 ; clear write register
83 clr r25
84 ldi r22,$00 ; setup null register
85 clr r28 ; set read address to minimum delay
86 ldi r29,$ff
87 ldi r23,$04 ; setup read address high byte
88 clr r21 ; set actual delay time to minimum delay
89 ldi r16,$01
90 mov r13,r16
91 clr r12
92 clr r2 ; initialize data output registers
93 clr r3
94 clr r4
95 clr r5
96 reti ; finish with initialization and wait for next interrupt
97
98 ;program starts here every time but first
99 ;initiate data transfer to codec
100 sbi portb,portb0 ; toggle slave select pin
101 out spdr,r3 ; send out left channel msb
102 cbi portb,portb0
103
104 ;increment sram address
105 adiw r25:r24,$01 ; increment write address
106 adiw r29:r28,$01 ; increment read address
107
108 wait1_000003: ; check if byte has been sent
109
110 in r17,spsr
111 sbrs r17,spif
112 rjmp wait1_000003
113 in r7,spdr ; recieve in left channel msb
114 out spdr,r2 ; send out left channel lsb
115
116 ;get left channel data from sram
117 out portd,r28 ; set address
118 sts porth,r29
119 nop ; wait input latch time of 2 clock cycles
120 nop ; wait input latch time of 2 clock cycles
121 in r2,pina ; get data
122 in r3,pinc ; get data
123 adiw r29:r28,$01 ; increment read address
124
125 wait2_000003: ; check if byte has been sent
126
127 in r17,spsr
128 sbrs r17,spif
129 rjmp wait2_000003
130 in r6,spdr ; recieve in left channel lsb
131 out spdr,r5 ; send out right channel msb
132
133 ;write left channel data to sram
134 out portd,r24 ; set address
135 sts porth,r25
136 out portg,r22 ; pull ce low,we low,and set high bits of address
137 ldi r17,$ff
138 out ddra,r17 ; set porta as output for data write
139 out ddrc,r17 ; set portc as output for data write
140 out porta,r6 ; set data
141 out portc,r7
142 sbi portg,portg2 ; pull we high to write
143 out ddra,r22 ; set porta as input for data lines
144 out ddrc,r22 ; set portc as input for data lines
145
146 wait3_000003: ; check if byte has been sent
147
148 in r17,spsr
149 sbrs r17,spif
150 rjmp wait3_000003
151 in r9,spdr ; recieve in right channel msb
152 out spdr,r4 ; send out right channel lsb
153
154 ;get right channel data from sram
155 out portd,r28 ; set address
156 sts porth,r29
157 nop ; wait input latch time of 2 clock cycles
158 nop ; wait input latch time of 2 clock cycles
159 in r4,pina ; get data
160 in r5,pinc ; get data
161 adiw r25:r24,$01 ; increment write address
162
163 wait4_000003: ; check if byte has been sent
164
165 in r17,spsr
166 sbrs r17,spif
167 rjmp wait4_000003
168 in r8,spdr ; recieve in left channel lsb
169
170 ;write right channel data to sram
171 out portd,r24 ; set address
172 sts porth,r25
173 out portg,r22 ; pull ce low,we low,and set high bits of address
174 ldi r17,$ff
175 out ddra,r17 ; set porta as output for data write
176 out ddrc,r17 ; set portc as output for data write
177 out porta,r8 ; set data
178 out portc,r9
179 sbi portg,portg2 ; pull we high to write
180 out ddra,r22 ; set porta as input for data lines
181 out ddrc,r22 ; set portc as input for data lines
182
183 ;get delay settings
184 lds r17,adcsra ; get adc control register
185 sbrs r17,adif ; check if adc conversion is complete
186 rjmp shift_000003 ; skip adc sampling
187 lds r16,adcl ; get low byte adc value
188 lds r17,adch ; get high byte adc value
189 add r10,r16 ; accumulate adc samples
190 adc r11,r17
191 adc r19,r22 ; r22 is cleared above
192 ldi r17,$f7
193 sts adcsra,r17 ; clear interrupt flag
194 dec r14 ; countdown adc sample clock
195 brne shift_000003 ; get delay time if its been long enough
196 lsr r19 ; divide adc sample by 4
197 ror r11 ; makes adc value a 16b number
198 ror r10
199 lsr r19
200 ror r11
201 ror r10
202 ldi r16,$01 ; check if delay is below minimum
203 cp r10,r22 ; r22 is cleared above
204 cpc r11,r16
205 brsh deadband_000003 ; check if adc value changed enough to update delay
206 clr r10 ; set minimum delay to $0100 = 3ms
207 mov r11,r16
208
209 deadband_000003: ; set the low value of the delay
210
211 movw r17:r16,r11:r10 ; move adc sample to temporary register
212 sbc r16,r26 ; find difference between adc sample and desired delay time
213 sbc r17,r27
214 brsh check_000003 ; check for deadband if positive
215 neg r16 ; invert if negative
216 adc r17,r22 ; r22 is cleared above
217 neg r17 ; converts ones complement to twos complement
218
219 check_000003: ; check if difference is greater than deadband
220
221 cpi r16,$40 ; check if difference is less than 1 lsb of adc
222 cpc r17,r22 ; r22 cleared above
223 brlo empty_000003 ; do nothing if less than 1 lsb
224 movw r27:r26,r11:r10 ; move adc sample to delay time if large enough change
225 andi r26,$fc ; make sure delay time is a multiple of 4
226
227 empty_000003: ; empty accumulation registers and finish off
228
229 clr r10 ; empty accumulation registers
230 clr r11
231 clr r19
232
233 shift_000003: ; check if delay time is correct
234
235 cp r26,r12 ; compare desired delay to actual delay
236 cpc r27,r13
237 breq switchsample_000003 ; do nothing if the same
238 brlo indexdown_000003
239 ldi r17,$04 ; increment delay register (4 is used for stereo data)
240 add r12,r17 ; this makes it play forward at double speed
241 adc r13,r22 ; until desired delay is reached
242 rjmp switchsample_000003
243
244 indexdown_000003:
245
246 ldi r17,$02 ; decrement delay register (2 is used for stereo data)
247 sub r12,r17 ; this makes is play backwards until desired delay is reached
248 sbc r13,r22 ; r22 is cleared above
249
250 switchsample_000003: ; check state of rotary switch
251
252 dec r15 ; countdown switch counter
253 brne done_000003 ; finish off if not ready yet
254 lds r16,pinj ; get switch data
255 andi r16,$78 ; mask off rotary switch
256 lsr r16 ; adjust switch position to program memory location
257 lsr r16
258 ldi r17,$02
259 add r16,r17
260 cp r16,r31 ; check if location has changed
261 breq done_000003 ; finish off if no change
262 clr r30 ; reset jump register to new function if changed
263 mov r31,r16
264
265 done_000003:
266
267 movw r29:r28,r25:r24 ; move write address to read destination register
268 sub r28,r12 ; remove delay time
269 sbc r29,r13
270 reti ; return to waiting
271
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.