← Revision 2 as of 2010-08-13 05:30:13
15029
Comment:
|
← Revision 3 as of 2010-08-13 05:33:29 →
15045
|
Deletions are marked like this. | Additions are marked like this. |
Line 183: | Line 183: |
sts adcsra,r16 ; enable adc,start conversion,free running mode,interrupt disabled,ck/128(156khz@20mhz cpu) |
sts adcsra,r16 ; enable adc,start conversion,free running mode, ; interrupt disabled,ck/128(156khz@20mhz cpu) |
Line 213: | Line 214: |
ldi r17,$03 ; dsp mode,16bit,slave mode,bclk invert disabled,lrswap disabled,data on first edge |
ldi r17,$03 ; dsp mode,16bit,slave mode,bclk invert disabled, ; lrswap disabled,data on first edge |
Line 253: | Line 255: |
ldi r17,$00 ; highpass filter enabled,de-emphasis disabled,mute disabled,dc offset storage disabled |
ldi r17,$00 ; highpass filter enabled,de-emphasis disabled, ; mute disabled,dc offset storage disabled |
Line 261: | Line 264: |
ldi r17,$12 ; disable mic boost,mute mic,line in to adc,disable bypass,select dac,disable sidetone |
ldi r17,$12 ; disable mic boost,mute mic,line in to adc, ; disable bypass,select dac,disable sidetone |
microdec1.asm
[Discussion of code elements, needed revision etc, can go here]
1 .include "m3250Pdef.inc" ; standard definitions include file
2
3 ;microdec v1.0
4
5 ;fuse settings
6 ;
7 ; start up time set to 258CK + 65ms
8 ; set to 20MHz by external crystal
9 ; BOD set at 4.3V
10 ; RSTDISBL not set
11 ; OCDEN not set
12 ; JTAG enabled
13 ; SPI enabled
14 ; EESAVE not set
15 ; CKOUT not set
16 ; CKDIV8 not set
17 ; WDT not set
18
19 ;hardware connections
20 ;
21 ; portA0:7 = D0 - D7 for sram
22 ; portB0:4 = SPI to codec and ISP
23 ; portB5:6 = NC (XP3)
24 ; portB7 = OE for sram
25 ; portC0:7 = D8 - D15 for sram
26 ; portD0:7 = A0 - A7 for sram
27 ; portE0:1 = USART (CEREAL)
28 ; portE2:3 = NC (XP1)
29 ; portE4:5 = I2C to codec with external pullups (could be any pins as USI is pointless)
30 ; portE6:7 = NC (XP2)
31 ; portF0 = ADC0 for potentiometer input (MOD1)
32 ; portF1:3 = NC (ADC1:3)
33 ; portF4:7 = JTAG
34 ; portG0:1 = A16 - A17 for sram
35 ; portG2 = WE for sram
36 ; portG3 = CE for sram
37 ; portG4 = CLKin from codec to T0 for interrupt timing
38 ; portG5 = RESET to JTAG/ISP
39 ; portH0:7 = A8 - A15 for sram
40 ; portJ0:1 = rotary encoder (b0,b1) with external pullups
41 ; portJ2 = rotary encoder pushbutton
42 ; portJ3:6 = rotary switch (b0 - b3)
43 ; AREF = externally connected to AVcc = +5V
44 ; XTAL1:2 = 20MHz crystal
45 ; VCC = DVcc = +5V
46 ; AVCC = AVcc = +5V
47
48 ;program structure overview
49 ;
50 ; Data is transferred to the codec via SPI, using the codec's DSP mode.
51 ; The codec's master clock is divided by two within the codec, and then
52 ; sent to the microcontroller where it is divided by 128 with T0. This
53 ; causes an interrupt at 44.1kHz for data transfers to the codec. In
54 ; order to eliminate audio glitches, this transfer must happen at the
55 ; same time, every time. For this reason, all code is run within this
56 ; interrupt, and no other interrupts are used. This way there can never
57 ; be a delay in the transfer of data. The exact piece of code that is
58 ; run is determined by the rotary switch, which must be checked within
59 ; the interrupt periodically to determine which code should be currently
60 ; running. The program executes the correct code by jumping to the
61 ; program space defined by the rotary switch setting (ijmp command).
62 ; This jump location has to be loaded into r31:r30 before returning from
63 ; the interrupt, or the program may crash. Because of the timing
64 ; limitations, only 20MHz/44.1kHz = 453 clock cycles can occur per
65 ; interrupt, of which approximatley 60 are taken up with SPI communication
66 ; and interrupt handling. A buffered data method could be used if
67 ; the program does not perform the same operations each sample period,
68 ; but the current method is used because of its simplicity. If you want
69 ; to change a function, merely swap out the code at that .org location.
70
71 ;current programs and their memory locations
72 ;
73 ; code switch function
74 ; ----- ----------- --------------------------------------------
75 ; $0200 = position 07 = pitch_shifter-16b-tonal-fading.asm
76 ; $0400 = position 06 = up_downsweep-18b-pot.asm
77 ; $0600 = position 05 = reverser-18b-gated-delay.asm
78 ; $0800 = position 04 = reverser-16b-pot-fading.asm
79 ; $0a00 = position 03 = reverser-16b-pot-crossfade.asm
80 ; $0c00 = position 02 = ping_pong-18b.asm
81 ; $0e00 = position 01 = delay-18b-pot-mono.asm
82 ; $1000 = position 00 = delay-16b-pot.asm
83 ; $1200 = position 15 = reverb-16b.asm
84 ; $1400 = position 14 = tremolo-stereo.asm
85 ; $1600 = position 13 = chorus-16b-sine.asm
86 ; $1800 = position 12 = flanger-16b-sine.asm
87 ; $1a00 = position 11 = stereo_flanger-16b.asm
88 ; $1c00 = position 10 = vco.asm
89 ; $1e00 = position 09 = fullwave-delay-lowpass.asm
90 ; $2000 = position 08 = sampler-18b-pot.asm
91
92 ;interrupt vectors
93 ;
94 .org 0 ; reset interrupt
95 rjmp start ; initialize microcontroller registers
96 .org OC0addr ; T0 compare interrupt - set to $80
97 ijmp ; send data to codec every 128 cycles of codec clock
98 .org OVF0addr ; T0 overflow interrupt
99 ijmp ; send data to codec every 128 cycles of codec clock
100
101 ;register usage - may be redefined in other sections
102 ; for conistency between programs, these registers(*) are normally used
103 ; as shown
104 ;
105 ; r0 multiply result lsb(*)
106 ; r1 multiply result msb(*)
107 ; r2 left data out lsb(*)
108 ; r3 left data out msb(*)
109 ; r4 right data out lsb(*)
110 ; r5 right data out msb(*)
111 ; r6 left data in lsb(*)
112 ; r7 left data in msb(*)
113 ; r8 right data in lsb(*)
114 ; r9 right data in msb(*)
115 ; r10
116 ; r11
117 ; r12
118 ; r13
119 ; r14
120 ; r15
121 ; r16 temporary swap register(*)
122 ; r17 temporary swap register(*)
123 ; r18 twi (i2c) counter register
124 ; r19
125 ; r20
126 ; r21
127 ; r22 write address third byte(*)
128 ; r23 read address third byte(*)
129 ; r24 write address lsb(*)
130 ; r25 write address msb(*)
131 ; r26
132 ; r27
133 ; r28 read address lsb(*)
134 ; r29 read address msb(*)
135 ; r30 jump location for interrupts lsb(*)
136 ; r31 jump location for interrupts msb(*)
137
138 start: ; configure microcontroller registers
139
140 ;set stack pointer to top of SRAM
141 ldi r16,high(RAMEND)
142 out SPH,r16
143 ldi r16,low(RAMEND)
144 out SPL,r16
145
146 ;setup sram io lines
147 ldi r16,$ff
148 out ddrd,r16 ; set portd as output for address lines
149 sts ddrh,r16 ; set porth as output for address lines
150 out porta,r16 ; turn on pullups on porta for data lines
151 out portc,r16 ; turn on pullups on portc for data lines
152 ldi r16,$00
153 out ddra,r16 ; set porta as input for data lines
154 out ddrc,r16 ; set portc as input for data lines
155 ldi r16,$0f
156 out ddrg,r16 ; set portg sram control pins to output
157 sbi ddrb,ddb7 ; set oe control pin to output
158 cbi portb,portb7 ; set oe to low - defined again in the spi setup
159
160 ;setup spi for codec data io
161 ldi r16,$87
162 out ddrb,r16 ; set ss,sck,mosi as output,and pb7 as output for oe on sram
163 ldi r16,$50 ; set spi to master,mode 0
164 out spcr,r16
165 ldi r16,$01 ; set spi to 2x (10MHz)
166 out spsr,r16
167
168 ;initialize ijmp address for reset vectors
169 ldi r30,$00
170 ldi r31,$02
171
172 ;setup adc
173 ldi r16,$01
174 sts didr0,r16 ; turn off input stage for pf0(adc0)
175 ldi r16,$00
176 sts admux,r16 ; set adc to sample adc0,external vcc ref,10b result
177 ldi r16,$e7
178 sts adcsra,r16 ; enable adc,start conversion,free running mode,
179 ; interrupt disabled,ck/128(156khz@20mhz cpu)
180
181 ;initialize sram address buffers
182 ldi r25,$00 ; initialize sram write address registers
183 ldi r24,$00
184 ldi r29,$00 ; initialize sram read address registers
185 ldi r28,$80
186 ldi r23,$04 ; initialize high byte read address register (/we bit set)
187 ldi r22,$00 ; initialize high byte write address register (/we bit cleared)
188
189 ;setup switch lines
190 ldi r16,$7c
191 sts portj,r16 ; turn on pullups for rotary switch and pushbutton
192
193 ;codec initialization routines
194 ;check wm8731 datasheet for other settings
195 ;
196 ;setup codec - power and clock registers
197 ldi r17,$34 ; send address
198 rcall twisend
199 ldi r17,$0c ; power down command register
200 rcall clock_data
201 ldi r17,$02 ; adc on,line in on,adc on,osc on,power on,clock out,mic off
202 rcall clock_data
203
204 ;setup codec - digital interface
205 ldi r17,$34 ; send address
206 rcall twisend
207 ldi r17,$0e ; digital interface command register
208 rcall clock_data
209 ldi r17,$03 ; dsp mode,16bit,slave mode,bclk invert disabled,
210 ; lrswap disabled,data on first edge
211 rcall clock_data
212
213 ;setup codec - left analog input
214 ldi r17,$34 ; send address
215 rcall twisend
216 ldi r17,$00 ; left analog interface command register
217 rcall clock_data
218 ldi r17,$17 ; mute off, +0db gain, lr load off
219 rcall clock_data
220
221 ;setup codec - right analog input
222 ldi r17,$34 ; send address
223 rcall twisend
224 ldi r17,$02 ; right analog interface command register
225 rcall clock_data
226 ldi r17,$17 ; mute off, +0db gain, lr load off
227 rcall clock_data
228
229 ;setup codec - left headphone output
230 ldi r17,$34 ; send address
231 rcall twisend
232 ldi r17,$04 ; left headphone otput command register
233 rcall clock_data
234 ldi r17,$79 ; zero-cross disable, +0db gain, lr load off
235 rcall clock_data
236
237 ;setup codec - right headphone output
238 ldi r17,$34 ; send address
239 rcall twisend
240 ldi r17,$06 ; right headphone output command register
241 rcall clock_data
242 ldi r17,$79 ; zero-cross disable, +0db gain, lr load off
243 rcall clock_data
244
245 ;setup codec - digital audio path
246 ldi r17,$34 ; send address
247 rcall twisend
248 ldi r17,$0a ; digital audio path command register
249 rcall clock_data
250 ldi r17,$00 ; highpass filter enabled,de-emphasis disabled,
251 ; mute disabled,dc offset storage disabled
252 rcall clock_data
253
254 ;setup codec - analog audio path
255 ldi r17,$34 ; send address
256 rcall twisend
257 ldi r17,$08 ; analog audio path command register
258 rcall clock_data
259 ldi r17,$12 ; disable mic boost,mute mic,line in to adc,
260 ; disable bypass,select dac,disable sidetone
261 rcall clock_data
262
263 ;setup codec - sampling control
264 ldi r17,$34 ; send address
265 rcall twisend
266 ldi r17,$10 ; sampling control command register
267 rcall clock_data
268 ldi r17,$a0 ; normal mode,256fs,clk/2 disable,clk/2 out enable
269 rcall clock_data
270
271 ;setup codec - activate codec
272 ldi r17,$34 ; send address
273 rcall twisend
274 ldi r17,$12 ; active command register
275 rcall clock_data
276 ldi r17,$01 ; active
277 rcall clock_data
278
279 ;setup timer0 for interrupt on dataclock
280 ldi r17,$07
281 out tccr0a,r17 ; set timer0 to external clock source, normal mode
282 ldi r17,$00
283 out tcnt0,r17 ; clear counter
284 ldi r17,$80
285 out ocr0a,r17 ; set counter top to 128
286 ldi r17,$03
287 sts timsk0,r17 ; set timer to interrupt on compare match and overflow
288
289 sei ; turn on interrupts
290
291 repeat: ; idle while outside of interrupt
292
293 nop
294 nop
295 nop
296 nop
297 nop
298 nop
299 rjmp repeat ; continue to idle
300
301 twisend: ; send data over twi (r17=data)
302 ; this is being bit banged as the USI peripheral essentially needs to be
303 ; bit banged anyways. the stop bit is not sent, as it doesn't seem to be
304 ; neccesary.
305 ;
306 ;setup timer0 for twi operation
307 ldi r16,$00
308 out tcnt0,r16 ; clear counter
309 ldi r16,$20
310 out ocr0a,r16 ; set counter top to 32 (167kHz data clock frequency)
311 ldi r16,$01
312 out tccr0a,r16 ; set timer0 to internal clock (cpu/1 = 20MHz), normal mode
313 ; make sure pullups are off
314 cbi porte,porte4 ; clock
315 cbi porte,porte5 ; data
316 cbi ddre,dde4 ; pull clock high
317 cbi ddre,dde5 ; pull data high
318
319 ;initiate start condition
320 ;
321 wait_start1: ; wait one clock cycle
322
323 sbis tifr0,ocf0a
324 rjmp wait_start1
325 ldi r16,$00
326 out tcnt0,r16 ; clear counter
327 sbi tifr0,ocf0a ; clear interrupt flag
328 sbi ddre,dde5 ; pull data low
329
330 wait_start2: ; wait one clock cycle
331
332 sbis tifr0,ocf0a
333 rjmp wait_start2
334 sbi ddre,dde4 ; pull clock low
335 ldi r16,$00
336 out tcnt0,r16 ; clear counter
337 sbi tifr0,ocf0a ; clear interrupt flag
338
339 wait_start3: ; wait one clock cycle
340
341 sbis tifr0,ocf0a
342 rjmp wait_start3
343 sbi tifr0,ocf0a ; clear interrupt flag
344
345 clock_data: ; clock out data
346
347 ldi r18,$08 ; setup data counter for 8 data bits
348 ldi r16,$00 ; reinitialize counter as data sends start from here
349 out tcnt0,r16 ; clear counter
350 ldi r16,$20
351 out ocr0a,r16 ; set counter top to 32 (167kHz data clock frequency)
352 ldi r16,$01
353 out tccr0a,r16 ; set timer0 to internal clock (cpu/1 = 20MHz), normal mode
354
355 clock_data1: ; continue clocking bits
356
357 lsl r17 ; move bit to be sent to carry register
358 brcs setbit_data ; check if bit is set
359 sbi ddre,dde5 ; clear data at output if not
360 rjmp wait_data1 ; continue with clocking
361
362 setbit_data: ; set data at output
363
364 cbi ddre,dde5 ; output data if bit is set
365
366 wait_data1: ; wait one clock cycle
367
368 sbis tifr0,ocf0a
369 rjmp wait_data1
370 cbi ddre,dde4 ; pull clock high
371 ldi r16,$00
372 out tcnt0,r16 ; clear counter
373 sbi tifr0,ocf0a ; clear interrupt flag
374
375 wait_data2: ; wait one clock cycle
376
377 sbis tifr0,ocf0a
378 rjmp wait_data2
379 sbi ddre,dde4 ; pull clock low
380 ldi r16,$00
381 out tcnt0,r16 ; clear counter
382 sbi tifr0,ocf0a ; clear interrupt flag
383
384 wait_data3: ; wait one clock cycle
385
386 sbis tifr0,ocf0a
387 rjmp wait_data3
388 ldi r16,$00
389 out tcnt0,r16 ; clear counter
390 sbi tifr0,ocf0a ; clear interrupt flag
391 dec r18 ; check if all bits have been clocked out
392 brne clock_data1 ; continue if not done
393 cbi ddre,dde5 ; release data line for ack
394
395 ;check for ack from codec
396 ;
397 wait_ack1: ; check for ack
398
399 sbic tifr0,ocf0a ; check if timer has expired
400 rjmp start ; reset micro if no ack within timeout (1.3us)
401 sbic pine,pine5 ; check for codec pulling the data line low
402 rjmp wait_ack1
403
404 wait_ack2: ; wait remainder of clock cycle
405
406 sbis tifr0,ocf0a
407 rjmp wait_ack2
408 cbi ddre,dde4 ; pull clock high
409 ldi r16,$00
410 out tcnt0,r16 ; clear counter
411 sbi tifr0,ocf0a ; clear interrupt flag
412
413 wait_ack3: ; wait one clock cycle
414
415 sbis tifr0,ocf0a
416 rjmp wait_ack3
417 sbi ddre,dde4 ; pull clock low
418 ldi r16,$00
419 out tcnt0,r16 ; clear counter
420 sbi tifr0,ocf0a ; clear interrupt flag
421
422 wait_ack4: ; wait one clock cycle
423
424 sbis tifr0,ocf0a
425 rjmp wait_ack4
426 ldi r16,$00
427 out tcnt0,r16 ; clear counter
428 sbi tifr0,ocf0a ; clear interrupt flag
429 ldi r16,$80
430 out ocr0a,r16 ; set counter top to 128 for ack timeout (6.4us time out)
431
432 wait_ack5: ; check for ack complete
433
434 sbic tifr0,ocf0a ; check if timer has expired
435 rjmp start ; reset micro if no ack within timeout (6.4us)
436 sbis pine,pine5 ; check for codec releasing the data line
437 rjmp wait_ack5
438 ldi r16,$00
439 out tccr0a,r16 ; turn counter0 off
440 ret
441
442 .org $0200 ; program space for switch position 7
443
444 .include "pitch_shifter-16b-tonal-fading.asm"
445
446
447 .org $0400 ; program space for switch position 6
448
449 .include "up_downsweep-18b-pot.asm"
450
451
452 .org $0600 ; program space for switch position 5
453
454 .include "reverser-18b-gated-delay.asm"
455
456
457 .org $0800 ; program space for switch position 4
458
459 .include "reverser-16b-pot-fading.asm"
460
461
462 .org $0a00 ; program space for switch position 3
463
464 .include "reverser-16b-pot-crossfade.asm"
465
466
467 .org $0c00 ; program space for switch position 2
468
469 .include "ping_pong-18b.asm"
470
471
472 .org $0e00 ; program space for switch position 1
473
474 .include "delay-18b-pot-mono.asm"
475
476
477 .org $1000 ; program space for switch position 0
478
479 .include "delay-16b-pot.asm"
480
481
482 .org $1200 ; program space for switch position 15
483
484 .include "reverb-16b.asm"
485
486
487 .org $1400 ; program space for switch position 14
488
489 .include "tremolo-stereo.asm"
490
491
492 .org $1600 ; program space for switch position 13
493
494 .include "chorus-16b-sine.asm"
495
496
497 .org $1800 ; program space for switch position 12
498
499 .include "flanger-16b-sine.asm"
500
501
502 .org $1a00 ; program space for switch position 11
503
504 .include "stereo_flanger-16b.asm"
505
506
507 .org $1c00 ; program space for switch position 10
508
509 .include "vco.asm"
510
511
512 .org $1e00 ; program space for switch position 9
513
514 .include "fullwave-delay-lowpass.asm"
515
516
517 .org $2000 ; program space for switch position 8
518
519 .include "sampler-18b-pot.asm"
520
521
522 .org $2400 ; program space for sinewave lookup table
523 ; 512 samples at 16b resolution, halfwave table, signed positive values
524 ; only [$0000 - $7fff].
525 .include "sinewave-16b-512s.asm"
526
527 .org $2600 ; program space for tone lookup table
528 ; tone lookup table for pitch shifter program - up and down one octave
529 ; includes each half step in 12 tone system
530 .include "tone_chart-16b.asm"
531