Attachment 'delay_6s_mono.asm'
Download 1 ; program: delay-18b-pot-mono.asm
2 ; UID = 000033 - unique id to eliminate conflicts between variables
3 ; 18b address space (6s delay time)
4 ; mono data (left in only, output on left and right)
5 ; pot (MOD1) controlled delay time (6ms - 6s)
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 desired delay time fractional byte
20 ; r1
21 ; r2 left/right lsb out
22 ; r3 left/right msb out
23 ; r4
24 ; r5
25 ; r6 left lsb in
26 ; r7 left msb in
27 ; r8
28 ; r9
29 ; r10 adc accumulator lsb
30 ; r11 adc accumulator msb
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 null register
38 ; r19 adc accumulator fractional byte
39 ; r20 temporary swap register
40 ; r21 actual delay fractional byte
41 ; r22 write address third byte
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,$23 ; 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_000033: ; 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,$04 ; check if full memory space has been cleared
67 breq cleardone_000033 ; 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_000033 ; continue clearing
79
80 cleardone_000033: ; reset registers
81
82 clr r24 ; clear write register
83 clr r25
84 ldi r22,$00 ; setup write address high byte
85 clr r28 ; set read address to minimum delay
86 ldi r29,$ff
87 ldi r23,$07 ; setup read address high byte
88 clr r21 ; set actual delay time to minimum delay
89 ldi r16,$01
90 mov r12,r16
91 clr r13
92 clr r2 ; initialize data output registers
93 clr r3
94 reti ; finish with initialization and wait for next interrupt
95
96 ;program starts here every time but first
97 ;initiate data transfer to codec
98 sbi portb,portb0 ; toggle slave select pin
99 out spdr,r3 ; send out left channel msb
100 cbi portb,portb0
101
102 ;increment sram addresses
103 adiw r25:r24,$01 ; increment write address
104 adc r22,r18 ; increment write third byte
105 andi r22,$03 ; mask off unsed bits
106 adiw r29:r28,$01 ; increment read address
107 adc r23,r18 ; increment read third byte
108 andi r23,$03 ; mask off unsed bits
109 ori r23,$04 ; set we bit for reading
110
111 wait1_000033: ; check if byte has been sent
112
113 in r17,spsr
114 sbrs r17,spif
115 rjmp wait1_000033
116 in r7,spdr ; recieve in left channel msb
117 out spdr,r2 ; send out left channel lsb
118
119 wait2_000033: ; check if byte has been sent
120
121 in r17,spsr
122 sbrs r17,spif
123 rjmp wait2_000033
124 in r6,spdr ; recieve in left channel lsb
125 out spdr,r3 ; send out right channel msb
126
127 ;write left channel data to sram
128 out portd,r24 ; set address
129 sts porth,r25
130 out portg,r22 ; pull ce low,we low,and set high bits of address
131 ldi r17,$ff
132 out ddra,r17 ; set porta as output for data write
133 out ddrc,r17 ; set portc as output for data write
134 out porta,r6 ; set data
135 out portc,r7
136 sbi portg,portg2 ; pull we high to write
137 out ddra,r18 ; set porta as input for data lines
138 out ddrc,r18 ; set portc as input for data lines
139
140 wait3_000033: ; check if byte has been sent
141
142 in r17,spsr
143 sbrs r17,spif
144 rjmp wait3_000033
145 in r9,spdr ; recieve in right channel msb
146 out spdr,r2 ; send out right channel lsb
147
148 ;get left channel data from sram
149 out portg,r23 ; pull ce low,we high,oe low, and set high bits of address
150 out portd,r28 ; set address
151 sts porth,r29
152 nop ; wait microcontroller setup time of 2 cycles
153 nop
154 in r2,pina ; get data
155 in r3,pinc ; get data
156
157 wait4_000033: ; check if byte has been sent
158
159 in r17,spsr
160 sbrs r17,spif
161 rjmp wait4_000033
162 in r8,spdr ; recieve in left channel lsb
163
164 ; get delay settings
165 lds r17,adcsra ; get adc control register
166 sbrs r17,adif ; check if adc conversion is complete
167 rjmp shift_000033 ; skip adc sampling
168 lds r16,adcl ; get low byte adc value
169 lds r17,adch ; get high byte adc value
170 add r19,r16 ; accumulate adc samples
171 adc r10,r17
172 adc r11,r18 ; r18 is cleared above
173 ldi r17,$f7
174 sts adcsra,r17 ; clear interrupt flag
175 dec r14 ; countdown adc sample clock
176 brne shift_000033 ; get delay time if its been long enough
177 ldi r17,$01 ; check if adc value is less than $000100
178 cp r19,r18 ; r18 is cleared above
179 cpc r10,r17
180 cpc r11,r18
181 brsh deadband_000033 ; check if adc value changed enough to update delay
182 inc r10 ; set minimum delay to $000100 = 6ms
183 clr r19
184
185 deadband_000033: ; check for change in adc value
186
187 movw r17:r16,r11:r10 ; move adc sample to temporary register
188 mov r20,r19
189 sub r20,r0 ; find difference between adc sample and desired delay time
190 sbc r16,r26
191 sbc r17,r27
192 brsh check_000033 ; check for deadband if positive
193 com r20 ; invert if negative
194 com r16 ; using ones complement as it is faster, and only has 1 bit error
195 com r17
196
197 check_000033: ; check if difference is greater than deadband
198
199 cpi r16,$01 ; check if difference is less than 1 lsb
200 cpc r17,r18 ; r18 cleared above
201 brlo empty_000033 ; do nothing if less than 1 lsb
202 movw r27:r26,r11:r10 ; move adc sample to delay time if large enough change
203 andi r19,$fe ; make sure delay time is even
204 mov r0,r19
205
206 empty_000033: ; empty accumulation registers and finish off
207
208 clr r10 ; empty accumulation registers
209 clr r11
210 clr r19
211
212 shift_000033: ; check if delay time is correct
213
214 cp r0,r21 ; compare desired delay to actual delay
215 cpc r26,r12
216 cpc r27,r13
217 breq switchsample_000033 ; do nothing if the same
218 brlo indexdown_000033
219 ldi r17,$02 ; increment delay register
220 add r21,r17 ; this doubles playback speed until desired delay is reached
221 adc r12,r18 ; r18 is cleared above
222 adc r13,r18
223 ldi r17,$03
224 and r13,r17 ; mask off unused bits
225 rjmp switchsample_000033
226
227 indexdown_000033:
228
229 subi r21,$01 ; decrement delay register
230 sbc r12,r18 ; r18 is cleared above
231 sbc r13,r18 ; this plays backwards until desired delay is reached
232 ldi r17,$03
233 and r13,r17 ; mask off unused bits
234
235 switchsample_000033: ; check state of rotary switch
236
237 dec r15
238 brne done_000033
239 lds r16,pinj ; get switch data
240 andi r16,$78 ; mask off rotary switch
241 lsr r16 ; adjust switch position to program memory location
242 lsr r16
243 ldi r17,$02
244 add r16,r17
245 cp r16,r31 ; check if location has changed
246 breq done_000033 ; finish off if no change
247 clr r30 ; reset jump register to new function if it changed
248 mov r31,r16
249
250 done_000033:
251
252 movw r29:r28,r25:r24 ; move write address to read destination register
253 mov r23,r22 ; move write third byte to read third byte
254 sub r28,r21 ; subtract delay time
255 sbc r29,r12
256 sbc r23,r13
257 andi r23,$03 ; mask off unsed bits
258 ori r23,$04 ; set we bit for reading
259 reti
260
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.