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
Enter the first 6 digits of Pi.

location: AudioInt4Asm

Audioint4.asm

[Discussion of code elements, needed revision etc, can go here]

   1 .include "m3250Pdef.inc" ; standard definitions include file
   2 
   3 ; microdec v1.0 - /ss = pb0
   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        memory address/data bits/channels - function
  74 ; -----   -----------   --------------------------------------------
  75 ; $0200 = position 07 = 18b/16b/stereo - delay - pot controlled (3ms - 3s)
  76 ; $0400 = position 06 = 16b/16b/stereo - delay - pot controlled (0s - .7s)
  77 ; $0600 = position 05 = 16b/16b/mono - vco with vca
  78 ; $0800 = position 04 = 16b/16b/stereo - upsweep - pot controlled
  79 ; $0a00 = position 03 = 16b/16b/stereo - reverser
  80 ; $0c00 = position 02 = 16b/16b/stereo - up/down sweep
  81 ; $0e00 = position 01 = 16b/16b/stereo - delay - rotary encoder controlled
  82 ; $1000 = position 00 = 16b/16b/mono - reverb
  83 ; $1200 = position 15 = 16b/16b/mono - fullwave rectifier
  84 ; $1400 = position 14 = 16b/16b/mono - gated reverser
  85 ; $1600 = position 13 = 16b/16b/mono - envelope stripper as vca on rampwave
  86 ; $1800 = position 12 = 16b/16b/mono - ring modulator
  87 ; $1a00 = position 11 = 16b/16b/mono - sampler - pot controlled playback speed
  88 ; $1c00 = position 10 = 16b/16b/mono - 16 voice chorus
  89 ; $1e00 = position 09 = 16b/16b/mono - flanger
  90 ; $2000 = position 08 = 16b/16b/mono - sampler - rotary encoder controlled playback speed
  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,low(RAMEND)
 142 out SPH,r16
 143 ldi r16,high(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,interrupt disabled,ck/128(156khz@20mhz cpu)
 179 
 180 ;initialize sram address buffers
 181 ldi r25,$00 ; initialize sram write address registers
 182 ldi r24,$00
 183 ldi r29,$00 ; initialize sram read address registers
 184 ldi r28,$80
 185 ldi r23,$04 ; initialize high byte read address register (/we bit set)
 186 ldi r22,$00 ; initialize high byte write address register (/we bit cleared)
 187 
 188 ;setup switch lines
 189 ldi r16,$7c
 190 sts portj,r16 ; turn on pullups for rotary switch and pushbutton
 191 
 192 ;codec initialization routines
 193 ;check wm8731 datasheet for other settings
 194 ;
 195 ;setup codec - power and clock registers
 196 ldi r17,$34 ; send address
 197 rcall twisend
 198 ldi r17,$0c ; power down command register
 199 rcall clock_data
 200 ldi r17,$02 ; adc on,line in on,adc on,osc on,power on,clock out,mic off
 201 rcall clock_data
 202 
 203 ;setup codec - digital interface
 204 ldi r17,$34 ; send address
 205 rcall twisend
 206 ldi r17,$0e ; digital interface command register
 207 rcall clock_data
 208 ldi r17,$03 ; dsp mode,16bit,slave mode,bclk invert disabled,lrswap disabled,data on first edge
 209 rcall clock_data
 210 
 211 ;setup codec - left analog input
 212 ldi r17,$34 ; send address
 213 rcall twisend
 214 ldi r17,$00 ; left analog interface command register
 215 rcall clock_data
 216 ldi r17,$17 ; mute off, +0db gain, lr load off
 217 rcall clock_data
 218 
 219 ;setup codec - right analog input
 220 ldi r17,$34 ; send address
 221 rcall twisend
 222 ldi r17,$02 ; right analog interface command register
 223 rcall clock_data
 224 ldi r17,$17 ; mute off, +0db gain, lr load off
 225 rcall clock_data
 226 
 227 ;setup codec - left headphone output
 228 ldi r17,$34 ; send address
 229 rcall twisend
 230 ldi r17,$04 ; left headphone otput command register
 231 rcall clock_data
 232 ldi r17,$79 ; zero-cross disable, +0db gain, lr load off
 233 rcall clock_data
 234 
 235 ;setup codec - right headphone output
 236 ldi r17,$34 ; send address
 237 rcall twisend
 238 ldi r17,$06 ; right headphone output command register
 239 rcall clock_data
 240 ldi r17,$79 ; zero-cross disable, +0db gain, lr load off
 241 rcall clock_data
 242 
 243 ;setup codec - digital audio path
 244 ldi r17,$34 ; send address
 245 rcall twisend
 246 ldi r17,$0a ; digital audio path command register
 247 rcall clock_data
 248 ldi r17,$00 ; highpass filter enabled,de-emphasis disabled,mute disabled,dc offset storage disabled
 249 rcall clock_data
 250 
 251 ;setup codec - analog audio path
 252 ldi r17,$34 ; send address
 253 rcall twisend
 254 ldi r17,$08 ; analog audio path command register
 255 rcall clock_data
 256 ldi r17,$12 ; disable mic boost,mute mic,line in to adc,disable bypass,select dac,disable sidetone
 257 rcall clock_data
 258 
 259 ;setup codec - sampling control
 260 ldi r17,$34 ; send address
 261 rcall twisend
 262 ldi r17,$10 ; sampling control command register
 263 rcall clock_data
 264 ldi r17,$a0 ; normal mode,256fs,clk/2 disable,clk/2 out enable
 265 rcall clock_data
 266 
 267 ;setup codec - activate codec
 268 ldi r17,$34 ; send address
 269 rcall twisend
 270 ldi r17,$12 ; active command register
 271 rcall clock_data
 272 ldi r17,$01 ; active
 273 rcall clock_data
 274 
 275 ;setup timer0 for interrupt on dataclock
 276 ldi r17,$07
 277 out tccr0a,r17 ; set timer0 to external clock source, normal mode
 278 ldi r17,$00
 279 out tcnt0,r17 ; clear counter
 280 ldi r17,$80
 281 out ocr0a,r17 ; set counter top to 128
 282 ldi r17,$03
 283 sts timsk0,r17 ; set timer to interrupt on compare match and overflow
 284 
 285 sei ; turn on interrupts
 286 
 287 repeat: ; idle while outside of interrupt
 288 
 289 nop
 290 nop
 291 nop
 292 nop
 293 nop
 294 nop
 295 rjmp repeat ; continue to idle
 296 
 297 twisend: ; send data over twi (r17=data)
 298 ; this is being bit banged as the USI peripheral essentially needs to be
 299 ; bit banged anyways.  the stop bit is not sent, as it doesn't seem to be
 300 ; neccesary.
 301 ;
 302 ;setup timer0 for twi operation
 303 ldi r16,$00
 304 out tcnt0,r16 ; clear counter
 305 ldi r16,$20
 306 out ocr0a,r16 ; set counter top to 32 (167kHz data clock frequency)
 307 ldi r16,$01
 308 out tccr0a,r16 ; set timer0 to internal clock (cpu/1 = 20MHz), normal mode
 309 ; make sure pullups are off
 310 cbi porte,porte4 ; clock
 311 cbi porte,porte5 ; data
 312 cbi ddre,dde4 ; pull clock high
 313 cbi ddre,dde5 ; pull data high
 314 
 315 ;initiate start condition
 316 ;
 317 wait_start1: ; wait one clock cycle
 318 
 319 sbis tifr0,ocf0a
 320 rjmp wait_start1
 321 ldi r16,$00
 322 out tcnt0,r16 ; clear counter
 323 sbi tifr0,ocf0a ; clear interrupt flag
 324 sbi ddre,dde5 ; pull data low
 325 
 326 wait_start2: ; wait one clock cycle
 327 
 328 sbis tifr0,ocf0a
 329 rjmp wait_start2
 330 sbi ddre,dde4 ; pull clock low
 331 ldi r16,$00
 332 out tcnt0,r16 ; clear counter
 333 sbi tifr0,ocf0a ; clear interrupt flag
 334 
 335 wait_start3: ; wait one clock cycle
 336 
 337 sbis tifr0,ocf0a
 338 rjmp wait_start3
 339 sbi tifr0,ocf0a ; clear interrupt flag
 340 
 341 clock_data: ; clock out data
 342 
 343 ldi r18,$08 ; setup data counter for 8 data bits
 344 ldi r16,$00 ; reinitialize counter as data sends start from here
 345 out tcnt0,r16 ; clear counter
 346 ldi r16,$20
 347 out ocr0a,r16 ; set counter top to 32 (167kHz data clock frequency)
 348 ldi r16,$01
 349 out tccr0a,r16 ; set timer0 to internal clock (cpu/1 = 20MHz), normal mode
 350 
 351 clock_data1: ; continue clocking bits
 352 
 353 lsl r17 ; move bit to be sent to carry register
 354 brcs setbit_data ; check if bit is set
 355 sbi ddre,dde5 ; clear data at output if not
 356 rjmp wait_data1 ; continue with clocking
 357 
 358 setbit_data: ; set data at output
 359 
 360 cbi ddre,dde5 ; output data if bit is set
 361 
 362 wait_data1: ; wait one clock cycle
 363 
 364 sbis tifr0,ocf0a
 365 rjmp wait_data1
 366 cbi ddre,dde4 ; pull clock high
 367 ldi r16,$00
 368 out tcnt0,r16 ; clear counter
 369 sbi tifr0,ocf0a ; clear interrupt flag
 370 
 371 wait_data2: ; wait one clock cycle
 372 
 373 sbis tifr0,ocf0a
 374 rjmp wait_data2
 375 sbi ddre,dde4 ; pull clock low
 376 ldi r16,$00
 377 out tcnt0,r16 ; clear counter
 378 sbi tifr0,ocf0a ; clear interrupt flag
 379 
 380 wait_data3: ; wait one clock cycle
 381 
 382 sbis tifr0,ocf0a
 383 rjmp wait_data3
 384 ldi r16,$00
 385 out tcnt0,r16 ; clear counter
 386 sbi tifr0,ocf0a ; clear interrupt flag
 387 dec r18 ; check if all bits have been clocked out
 388 brne clock_data1 ; continue if not done
 389 cbi ddre,dde5 ; release data line for ack
 390 
 391 ;check for ack from codec
 392 ;
 393 wait_ack1: ; check for ack
 394 
 395 sbic tifr0,ocf0a ; check if timer has expired
 396 rjmp start ; reset micro if no ack within timeout (1.3us)
 397 sbic pine,pine5 ; check for codec pulling the data line low
 398 rjmp wait_ack1
 399 
 400 wait_ack2: ; wait remainder of clock cycle
 401 
 402 sbis tifr0,ocf0a
 403 rjmp wait_ack2
 404 cbi ddre,dde4 ; pull clock high
 405 ldi r16,$00
 406 out tcnt0,r16 ; clear counter
 407 sbi tifr0,ocf0a ; clear interrupt flag
 408 
 409 wait_ack3: ; wait one clock cycle
 410 
 411 sbis tifr0,ocf0a
 412 rjmp wait_ack3
 413 sbi ddre,dde4 ; pull clock low
 414 ldi r16,$00
 415 out tcnt0,r16 ; clear counter
 416 sbi tifr0,ocf0a ; clear interrupt flag
 417 
 418 wait_ack4: ; wait one clock cycle
 419 
 420 sbis tifr0,ocf0a
 421 rjmp wait_ack4
 422 ldi r16,$00
 423 out tcnt0,r16 ; clear counter
 424 sbi tifr0,ocf0a ; clear interrupt flag
 425 ldi r16,$80
 426 out ocr0a,r16 ; set counter top to 128 for ack timeout (6.4us time out)
 427 
 428 wait_ack5: ; check for ack complete
 429 
 430 sbic tifr0,ocf0a ; check if timer has expired
 431 rjmp start ; reset micro if no ack within timeout (6.4us)
 432 sbis pine,pine5 ; check for codec releasing the data line
 433 rjmp wait_ack5
 434 ldi r16,$00
 435 out tccr0a,r16 ; turn counter0 off
 436 ret
 437 
 438 .org $0200 ; program space for position 7 on rotary encoder
 439 
 440 ;.include "flanger-16b-variable.asm"
 441 ;.include "delay-16b-midi.asm"
 442 .include "pitch_shifter-16b-variable-fading.asm"
 443 ;.include "delay-18b-pot.asm" ; place delay program here
 444 
 445 .org $0400 ; program space for switch position 6
 446 
 447 ;.include "delay-16b-pot.asm" ; place delay program here
 448 .include "pitch_shifter-16b-variable-ducking.asm"
 449 
 450 .org $0600 ; program space for switch position 5
 451 
 452 ;.include "pitch_shifter-16b-rotary.asm"
 453 .include "pll-16b.asm" ; place pll program here
 454 
 455 .org $0800 ; program space for switch position 4
 456 
 457 ;.include "pitch_shifter-16b-variable.asm"
 458 .include "upsweep-16b-pot.asm" ; place upsweep program here
 459 
 460 .org $0a00 ; program space for switch position 3
 461 
 462 .include "downsweep-16b.asm" ; place downsweep program here
 463 
 464 .org $0c00 ; program space for switch position 2
 465 
 466 .include "up_downsweep-16b.asm" ; place up_downsweep program here
 467 
 468 .org $0e00 ; program space for switch position 1
 469 
 470 .include "delay-16b-rotary.asm" ; place delay program here
 471 
 472 .org $1000 ; program space for switch position 0
 473 
 474 .include "reverb-16b.asm" ; place reverb program here
 475 
 476 .org $1200 ; program space for switch position 15
 477 
 478 .include "pseudo_convolver-16b.asm"
 479 ;.include "fullwave.asm" ; place fullwave rectifier program here
 480 
 481 .org $1400 ; program space for switch position 14
 482 
 483 .include "gated_reverser-16b.asm" ; place gated reverser program here
 484 
 485 .org $1600 ; program space for switch position 13
 486 
 487 .include "envelope_stripper.asm" ; place envelope stripper program here
 488 
 489 .org $1800 ; program space for switch position 12
 490 
 491 .include "ring_modulator.asm" ; place ring modulator program here
 492 
 493 .org $1a00 ; program space for switch position 11
 494 
 495 .include "sampler-pot.asm" ; place sampler program here
 496 
 497 .org $1c00 ; program space for switch position 10
 498 
 499 .include "chorus-16b.asm" ; place chorus program here
 500 
 501 .org $1e00 ; program space for switch position 9
 502 
 503 .include "flanger-16b.asm" ; place flanger program here
 504 
 505 .org $2000 ; program space for switch position 8
 506 
 507 .include "sampler-rotary.asm" ; place sampler program here
 508 
 509 .org $2200 ; program space for sinewave table
 510 ; 256 sample, 8b, half sine table, only positive values [$00 - $7f]
 511 ; should update to 16b table, as this sounds pretty bad
 512 .include "sinewave-8b-256s.asm"
 513 
 514 .org $2400 ; program space for sinewave lookup table
 515 ; 256 samples at 16b resolution, halfwave table, signed positive values
 516 ; only [$0000 - $7fff].
 517 .include "sinewave-16b-256s.asm"
 518 

MICrODEC

Microdec Software