welcome: please sign in
location: Diff for "MicrodecAsm"
Differences between revisions 2 and 3
Revision 2 as of 2010-08-13 05:30:13
Size: 15029
Editor: guest
Comment:
Revision 3 as of 2010-08-13 05:33:29
Size: 15045
Editor: guest
Comment:
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 

MICrODEC

Microdec Software

MicrodecAsm (last edited 2010-08-21 01:47:08 by guest)