welcome: please sign in

Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment
What is the opposite of 'day'?

Revision 3 as of 2010-08-13 05:33:29

location: MicrodecAsm

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