welcome: please sign in
location: Diff for "MicrodecAsm"
Differences between revisions 1 and 2
Revision 1 as of 2010-08-13 05:26:42
Size: 28
Editor: guest
Comment:
Revision 2 as of 2010-08-13 05:30:13
Size: 15029
Editor: guest
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
Describe MicrodecAsm here. microdec1.asm

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

{{{#!highlight nasm
.include "m3250Pdef.inc" ; standard definitions include file

;microdec v1.0

;fuse settings
;
; start up time set to 258CK + 65ms
; set to 20MHz by external crystal
; BOD set at 4.3V
; RSTDISBL not set
; OCDEN not set
; JTAG enabled
; SPI enabled
; EESAVE not set
; CKOUT not set
; CKDIV8 not set
; WDT not set

;hardware connections
;
; portA0:7 = D0 - D7 for sram
; portB0:4 = SPI to codec and ISP
; portB5:6 = NC (XP3)
; portB7 = OE for sram
; portC0:7 = D8 - D15 for sram
; portD0:7 = A0 - A7 for sram
; portE0:1 = USART (CEREAL)
; portE2:3 = NC (XP1)
; portE4:5 = I2C to codec with external pullups (could be any pins as USI is pointless)
; portE6:7 = NC (XP2)
; portF0 = ADC0 for potentiometer input (MOD1)
; portF1:3 = NC (ADC1:3)
; portF4:7 = JTAG
; portG0:1 = A16 - A17 for sram
; portG2 = WE for sram
; portG3 = CE for sram
; portG4 = CLKin from codec to T0 for interrupt timing
; portG5 = RESET to JTAG/ISP
; portH0:7 = A8 - A15 for sram
; portJ0:1 = rotary encoder (b0,b1) with external pullups
; portJ2 = rotary encoder pushbutton
; portJ3:6 = rotary switch (b0 - b3)
; AREF = externally connected to AVcc = +5V
; XTAL1:2 = 20MHz crystal
; VCC = DVcc = +5V
; AVCC = AVcc = +5V

;program structure overview
;
; Data is transferred to the codec via SPI, using the codec's DSP mode.
; The codec's master clock is divided by two within the codec, and then
; sent to the microcontroller where it is divided by 128 with T0. This
; causes an interrupt at 44.1kHz for data transfers to the codec. In
; order to eliminate audio glitches, this transfer must happen at the
; same time, every time. For this reason, all code is run within this
; interrupt, and no other interrupts are used. This way there can never
; be a delay in the transfer of data. The exact piece of code that is
; run is determined by the rotary switch, which must be checked within
; the interrupt periodically to determine which code should be currently
; running. The program executes the correct code by jumping to the
; program space defined by the rotary switch setting (ijmp command).
; This jump location has to be loaded into r31:r30 before returning from
; the interrupt, or the program may crash. Because of the timing
; limitations, only 20MHz/44.1kHz = 453 clock cycles can occur per
; interrupt, of which approximatley 60 are taken up with SPI communication
; and interrupt handling. A buffered data method could be used if
; the program does not perform the same operations each sample period,
; but the current method is used because of its simplicity. If you want
; to change a function, merely swap out the code at that .org location.

;current programs and their memory locations
;
; code switch function
; ----- ----------- --------------------------------------------
; $0200 = position 07 = pitch_shifter-16b-tonal-fading.asm
; $0400 = position 06 = up_downsweep-18b-pot.asm
; $0600 = position 05 = reverser-18b-gated-delay.asm
; $0800 = position 04 = reverser-16b-pot-fading.asm
; $0a00 = position 03 = reverser-16b-pot-crossfade.asm
; $0c00 = position 02 = ping_pong-18b.asm
; $0e00 = position 01 = delay-18b-pot-mono.asm
; $1000 = position 00 = delay-16b-pot.asm
; $1200 = position 15 = reverb-16b.asm
; $1400 = position 14 = tremolo-stereo.asm
; $1600 = position 13 = chorus-16b-sine.asm
; $1800 = position 12 = flanger-16b-sine.asm
; $1a00 = position 11 = stereo_flanger-16b.asm
; $1c00 = position 10 = vco.asm
; $1e00 = position 09 = fullwave-delay-lowpass.asm
; $2000 = position 08 = sampler-18b-pot.asm

;interrupt vectors
;
.org 0 ; reset interrupt
rjmp start ; initialize microcontroller registers
.org OC0addr ; T0 compare interrupt - set to $80
ijmp ; send data to codec every 128 cycles of codec clock
.org OVF0addr ; T0 overflow interrupt
ijmp ; send data to codec every 128 cycles of codec clock

;register usage - may be redefined in other sections
; for conistency between programs, these registers(*) are normally used
; as shown
;
; r0 multiply result lsb(*)
; r1 multiply result msb(*)
; r2 left data out lsb(*)
; r3 left data out msb(*)
; r4 right data out lsb(*)
; r5 right data out msb(*)
; r6 left data in lsb(*)
; r7 left data in msb(*)
; r8 right data in lsb(*)
; r9 right data in msb(*)
; r10
; r11
; r12
; r13
; r14
; r15
; r16 temporary swap register(*)
; r17 temporary swap register(*)
; r18 twi (i2c) counter register
; r19
; r20
; r21
; r22 write address third byte(*)
; r23 read address third byte(*)
; r24 write address lsb(*)
; r25 write address msb(*)
; r26
; r27
; r28 read address lsb(*)
; r29 read address msb(*)
; r30 jump location for interrupts lsb(*)
; r31 jump location for interrupts msb(*)

start: ; configure microcontroller registers

;set stack pointer to top of SRAM
ldi r16,high(RAMEND)
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16

;setup sram io lines
ldi r16,$ff
out ddrd,r16 ; set portd as output for address lines
sts ddrh,r16 ; set porth as output for address lines
out porta,r16 ; turn on pullups on porta for data lines
out portc,r16 ; turn on pullups on portc for data lines
ldi r16,$00
out ddra,r16 ; set porta as input for data lines
out ddrc,r16 ; set portc as input for data lines
ldi r16,$0f
out ddrg,r16 ; set portg sram control pins to output
sbi ddrb,ddb7 ; set oe control pin to output
cbi portb,portb7 ; set oe to low - defined again in the spi setup

;setup spi for codec data io
ldi r16,$87
out ddrb,r16 ; set ss,sck,mosi as output,and pb7 as output for oe on sram
ldi r16,$50 ; set spi to master,mode 0
out spcr,r16
ldi r16,$01 ; set spi to 2x (10MHz)
out spsr,r16

;initialize ijmp address for reset vectors
ldi r30,$00
ldi r31,$02

;setup adc
ldi r16,$01
sts didr0,r16 ; turn off input stage for pf0(adc0)
ldi r16,$00
sts admux,r16 ; set adc to sample adc0,external vcc ref,10b result
ldi r16,$e7
sts adcsra,r16 ; enable adc,start conversion,free running mode,interrupt disabled,ck/128(156khz@20mhz cpu)

;initialize sram address buffers
ldi r25,$00 ; initialize sram write address registers
ldi r24,$00
ldi r29,$00 ; initialize sram read address registers
ldi r28,$80
ldi r23,$04 ; initialize high byte read address register (/we bit set)
ldi r22,$00 ; initialize high byte write address register (/we bit cleared)

;setup switch lines
ldi r16,$7c
sts portj,r16 ; turn on pullups for rotary switch and pushbutton

;codec initialization routines
;check wm8731 datasheet for other settings
;
;setup codec - power and clock registers
ldi r17,$34 ; send address
rcall twisend
ldi r17,$0c ; power down command register
rcall clock_data
ldi r17,$02 ; adc on,line in on,adc on,osc on,power on,clock out,mic off
rcall clock_data

;setup codec - digital interface
ldi r17,$34 ; send address
rcall twisend
ldi r17,$0e ; digital interface command register
rcall clock_data
ldi r17,$03 ; dsp mode,16bit,slave mode,bclk invert disabled,lrswap disabled,data on first edge
rcall clock_data

;setup codec - left analog input
ldi r17,$34 ; send address
rcall twisend
ldi r17,$00 ; left analog interface command register
rcall clock_data
ldi r17,$17 ; mute off, +0db gain, lr load off
rcall clock_data

;setup codec - right analog input
ldi r17,$34 ; send address
rcall twisend
ldi r17,$02 ; right analog interface command register
rcall clock_data
ldi r17,$17 ; mute off, +0db gain, lr load off
rcall clock_data

;setup codec - left headphone output
ldi r17,$34 ; send address
rcall twisend
ldi r17,$04 ; left headphone otput command register
rcall clock_data
ldi r17,$79 ; zero-cross disable, +0db gain, lr load off
rcall clock_data

;setup codec - right headphone output
ldi r17,$34 ; send address
rcall twisend
ldi r17,$06 ; right headphone output command register
rcall clock_data
ldi r17,$79 ; zero-cross disable, +0db gain, lr load off
rcall clock_data

;setup codec - digital audio path
ldi r17,$34 ; send address
rcall twisend
ldi r17,$0a ; digital audio path command register
rcall clock_data
ldi r17,$00 ; highpass filter enabled,de-emphasis disabled,mute disabled,dc offset storage disabled
rcall clock_data

;setup codec - analog audio path
ldi r17,$34 ; send address
rcall twisend
ldi r17,$08 ; analog audio path command register
rcall clock_data
ldi r17,$12 ; disable mic boost,mute mic,line in to adc,disable bypass,select dac,disable sidetone
rcall clock_data

;setup codec - sampling control
ldi r17,$34 ; send address
rcall twisend
ldi r17,$10 ; sampling control command register
rcall clock_data
ldi r17,$a0 ; normal mode,256fs,clk/2 disable,clk/2 out enable
rcall clock_data

;setup codec - activate codec
ldi r17,$34 ; send address
rcall twisend
ldi r17,$12 ; active command register
rcall clock_data
ldi r17,$01 ; active
rcall clock_data

;setup timer0 for interrupt on dataclock
ldi r17,$07
out tccr0a,r17 ; set timer0 to external clock source, normal mode
ldi r17,$00
out tcnt0,r17 ; clear counter
ldi r17,$80
out ocr0a,r17 ; set counter top to 128
ldi r17,$03
sts timsk0,r17 ; set timer to interrupt on compare match and overflow

sei ; turn on interrupts

repeat: ; idle while outside of interrupt

nop
nop
nop
nop
nop
nop
rjmp repeat ; continue to idle

twisend: ; send data over twi (r17=data)
; this is being bit banged as the USI peripheral essentially needs to be
; bit banged anyways. the stop bit is not sent, as it doesn't seem to be
; neccesary.
;
;setup timer0 for twi operation
ldi r16,$00
out tcnt0,r16 ; clear counter
ldi r16,$20
out ocr0a,r16 ; set counter top to 32 (167kHz data clock frequency)
ldi r16,$01
out tccr0a,r16 ; set timer0 to internal clock (cpu/1 = 20MHz), normal mode
; make sure pullups are off
cbi porte,porte4 ; clock
cbi porte,porte5 ; data
cbi ddre,dde4 ; pull clock high
cbi ddre,dde5 ; pull data high

;initiate start condition
;
wait_start1: ; wait one clock cycle

sbis tifr0,ocf0a
rjmp wait_start1
ldi r16,$00
out tcnt0,r16 ; clear counter
sbi tifr0,ocf0a ; clear interrupt flag
sbi ddre,dde5 ; pull data low

wait_start2: ; wait one clock cycle

sbis tifr0,ocf0a
rjmp wait_start2
sbi ddre,dde4 ; pull clock low
ldi r16,$00
out tcnt0,r16 ; clear counter
sbi tifr0,ocf0a ; clear interrupt flag

wait_start3: ; wait one clock cycle

sbis tifr0,ocf0a
rjmp wait_start3
sbi tifr0,ocf0a ; clear interrupt flag

clock_data: ; clock out data

ldi r18,$08 ; setup data counter for 8 data bits
ldi r16,$00 ; reinitialize counter as data sends start from here
out tcnt0,r16 ; clear counter
ldi r16,$20
out ocr0a,r16 ; set counter top to 32 (167kHz data clock frequency)
ldi r16,$01
out tccr0a,r16 ; set timer0 to internal clock (cpu/1 = 20MHz), normal mode

clock_data1: ; continue clocking bits

lsl r17 ; move bit to be sent to carry register
brcs setbit_data ; check if bit is set
sbi ddre,dde5 ; clear data at output if not
rjmp wait_data1 ; continue with clocking

setbit_data: ; set data at output

cbi ddre,dde5 ; output data if bit is set

wait_data1: ; wait one clock cycle

sbis tifr0,ocf0a
rjmp wait_data1
cbi ddre,dde4 ; pull clock high
ldi r16,$00
out tcnt0,r16 ; clear counter
sbi tifr0,ocf0a ; clear interrupt flag

wait_data2: ; wait one clock cycle

sbis tifr0,ocf0a
rjmp wait_data2
sbi ddre,dde4 ; pull clock low
ldi r16,$00
out tcnt0,r16 ; clear counter
sbi tifr0,ocf0a ; clear interrupt flag

wait_data3: ; wait one clock cycle

sbis tifr0,ocf0a
rjmp wait_data3
ldi r16,$00
out tcnt0,r16 ; clear counter
sbi tifr0,ocf0a ; clear interrupt flag
dec r18 ; check if all bits have been clocked out
brne clock_data1 ; continue if not done
cbi ddre,dde5 ; release data line for ack

;check for ack from codec
;
wait_ack1: ; check for ack

sbic tifr0,ocf0a ; check if timer has expired
rjmp start ; reset micro if no ack within timeout (1.3us)
sbic pine,pine5 ; check for codec pulling the data line low
rjmp wait_ack1

wait_ack2: ; wait remainder of clock cycle

sbis tifr0,ocf0a
rjmp wait_ack2
cbi ddre,dde4 ; pull clock high
ldi r16,$00
out tcnt0,r16 ; clear counter
sbi tifr0,ocf0a ; clear interrupt flag

wait_ack3: ; wait one clock cycle

sbis tifr0,ocf0a
rjmp wait_ack3
sbi ddre,dde4 ; pull clock low
ldi r16,$00
out tcnt0,r16 ; clear counter
sbi tifr0,ocf0a ; clear interrupt flag

wait_ack4: ; wait one clock cycle

sbis tifr0,ocf0a
rjmp wait_ack4
ldi r16,$00
out tcnt0,r16 ; clear counter
sbi tifr0,ocf0a ; clear interrupt flag
ldi r16,$80
out ocr0a,r16 ; set counter top to 128 for ack timeout (6.4us time out)

wait_ack5: ; check for ack complete

sbic tifr0,ocf0a ; check if timer has expired
rjmp start ; reset micro if no ack within timeout (6.4us)
sbis pine,pine5 ; check for codec releasing the data line
rjmp wait_ack5
ldi r16,$00
out tccr0a,r16 ; turn counter0 off
ret

.org $0200 ; program space for switch position 7

.include "pitch_shifter-16b-tonal-fading.asm"


.org $0400 ; program space for switch position 6

.include "up_downsweep-18b-pot.asm"


.org $0600 ; program space for switch position 5

.include "reverser-18b-gated-delay.asm"


.org $0800 ; program space for switch position 4

.include "reverser-16b-pot-fading.asm"


.org $0a00 ; program space for switch position 3

.include "reverser-16b-pot-crossfade.asm"


.org $0c00 ; program space for switch position 2

.include "ping_pong-18b.asm"


.org $0e00 ; program space for switch position 1

.include "delay-18b-pot-mono.asm"


.org $1000 ; program space for switch position 0

.include "delay-16b-pot.asm"


.org $1200 ; program space for switch position 15

.include "reverb-16b.asm"


.org $1400 ; program space for switch position 14

.include "tremolo-stereo.asm"


.org $1600 ; program space for switch position 13

.include "chorus-16b-sine.asm"


.org $1800 ; program space for switch position 12

.include "flanger-16b-sine.asm"


.org $1a00 ; program space for switch position 11

.include "stereo_flanger-16b.asm"


.org $1c00 ; program space for switch position 10

.include "vco.asm"


.org $1e00 ; program space for switch position 9

.include "fullwave-delay-lowpass.asm"


.org $2000 ; program space for switch position 8

.include "sampler-18b-pot.asm"


.org $2400 ; program space for sinewave lookup table
; 512 samples at 16b resolution, halfwave table, signed positive values
; only [$0000 - $7fff].
.include "sinewave-16b-512s.asm"

.org $2600 ; program space for tone lookup table
; tone lookup table for pitch shifter program - up and down one octave
; includes each half step in 12 tone system
.include "tone_chart-16b.asm"
}}}
[[MICrODEC]]

[[MicrodecSoftware|Microdec Software]]

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,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 switch position 7
 439 
 440 .include "pitch_shifter-16b-tonal-fading.asm"
 441 
 442 
 443 .org $0400 ; program space for switch position 6
 444 
 445 .include "up_downsweep-18b-pot.asm"
 446 
 447 
 448 .org $0600 ; program space for switch position 5
 449 
 450 .include "reverser-18b-gated-delay.asm"
 451 
 452 
 453 .org $0800 ; program space for switch position 4
 454 
 455 .include "reverser-16b-pot-fading.asm"
 456 
 457 
 458 .org $0a00 ; program space for switch position 3
 459 
 460 .include "reverser-16b-pot-crossfade.asm"
 461 
 462 
 463 .org $0c00 ; program space for switch position 2
 464 
 465 .include "ping_pong-18b.asm"
 466 
 467 
 468 .org $0e00 ; program space for switch position 1
 469 
 470 .include "delay-18b-pot-mono.asm"
 471 
 472 
 473 .org $1000 ; program space for switch position 0
 474 
 475 .include "delay-16b-pot.asm"
 476 
 477 
 478 .org $1200 ; program space for switch position 15
 479 
 480 .include "reverb-16b.asm"
 481 
 482 
 483 .org $1400 ; program space for switch position 14
 484 
 485 .include "tremolo-stereo.asm"
 486 
 487 
 488 .org $1600 ; program space for switch position 13
 489 
 490 .include "chorus-16b-sine.asm"
 491 
 492 
 493 .org $1800 ; program space for switch position 12
 494 
 495 .include "flanger-16b-sine.asm"
 496 
 497 
 498 .org $1a00 ; program space for switch position 11
 499 
 500 .include "stereo_flanger-16b.asm"
 501 
 502 
 503 .org $1c00 ; program space for switch position 10
 504 
 505 .include "vco.asm"
 506 
 507 
 508 .org $1e00 ; program space for switch position 9
 509 
 510 .include "fullwave-delay-lowpass.asm"
 511 
 512 
 513 .org $2000 ; program space for switch position 8
 514 
 515 .include "sampler-18b-pot.asm"
 516 
 517 
 518 .org $2400 ; program space for sinewave lookup table
 519 ; 512 samples at 16b resolution, halfwave table, signed positive values
 520 ; only [$0000 - $7fff].
 521 .include "sinewave-16b-512s.asm"
 522 
 523 .org $2600 ; program space for tone lookup table
 524 ; tone lookup table for pitch shifter program - up and down one octave
 525 ; includes each half step in 12 tone system
 526 .include "tone_chart-16b.asm"
 527 

MICrODEC

Microdec Software

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