welcome: please sign in
location: attachment:delay_700ms_stereo.asm of Delay700msStereo

Attachment 'delay_700ms_stereo.asm'

Download

   1 ; program: delay-16b-pot.asm
   2 ; UID = 000003 - unique id to eliminate conflicts between variables
   3 ; 16b address space (.7s delay time)
   4 ; stereo data
   5 ; pot (MOD1) controlled delay time (3ms - 700ms)
   6 
   7 ; program overview
   8 ;
   9 ; data is read in from memory and written out the codec at the same time
  10 ; new data is written to the memory from the codec.  ADC0 (MOD1) is read
  11 ; and averaged over 256 samples to reduce jitter.  this value is subtracted
  12 ; from the write address to create the desired read address.  if the actual
  13 ; read address doesnt match the desired read address, it is either
  14 ; incremented or decremented by one sample each sample period until it
  15 ; matches.  this reduces noise during delay time transitions.
  16 
  17 ; register usage - may be redefined in other sections
  18 ;
  19 ; r0  
  20 ; r1  
  21 ; r2  left lsb out
  22 ; r3  left msb out
  23 ; r4  right lsb out
  24 ; r5  right msb out
  25 ; r6  left lsb in
  26 ; r7  left msb in
  27 ; r8  right lsb in
  28 ; r9  right msb in
  29 ; r10 adc accumulator fractional byte
  30 ; r11 adc accumulator lsb
  31 ; r12 actual delay lsb
  32 ; r13 actual delay msb
  33 ; r14 adc sample counter
  34 ; r15 switch sample counter
  35 ; r16 temporary swap register
  36 ; r17 temporary swap register
  37 ; r18 
  38 ; r19 adc accumulator msb
  39 ; r20 
  40 ; r21 
  41 ; r22 null register
  42 ; r23 read address third byte
  43 ; r24 write address lsb
  44 ; r25 write address msb
  45 ; r26 desired delay lsb
  46 ; r27 desired delay msb
  47 ; r28 read address lsb
  48 ; r29 read address msb
  49 ; r30 jump location for interrupt lsb
  50 ; r31 jump location for interrupt msb
  51 ; t   
  52 
  53 ;program starts here first time
  54 ldi r30,$25 ; set jump location to program start
  55 clr r24 ; clear write register
  56 clr r25
  57 ldi r22,$00 ; setup write address high byte
  58 clr r18 ; setup r18 as null register for carry addition and ddr setting
  59 ldi r17,$ff ; setup r17 for ddr setting
  60 
  61 clear_000003: ; clear delay buffer
  62 ; eliminates static when first switching to the delay setting
  63 
  64 adiw r25:r24,$01 ; increment write register
  65 adc r22,r18 ; increment write third byte
  66 cpi r22,$01 ; check if 16b memory space has been cleared
  67 breq cleardone_000003 ; continue until end of buffer reached
  68 out portd,r24 ; set address
  69 sts porth,r25
  70 out portg,r22 ; pull ce low,we low,and set high bits of address
  71 out ddra,r17 ; set porta as output for data write
  72 out ddrc,r17 ; set portc as output for data write
  73 out porta,r18 ; set data
  74 out portc,r18 ; r18 is cleared above
  75 sbi portg,portg2 ; pull we high to write
  76 out ddra,r18 ; set porta as input for data lines
  77 out ddrc,r18 ; set portc as input for data lines
  78 rjmp clear_000003 ; continue clearing
  79 
  80 cleardone_000003: ; reset registers
  81 
  82 clr r24 ; clear write register
  83 clr r25
  84 ldi r22,$00 ; setup null register
  85 clr r28 ; set read address to minimum delay
  86 ldi r29,$ff
  87 ldi r23,$04 ; setup read address high byte
  88 clr r21 ; set actual delay time to minimum delay
  89 ldi r16,$01
  90 mov r13,r16
  91 clr r12
  92 clr r2 ; initialize data output registers
  93 clr r3
  94 clr r4
  95 clr r5
  96 reti ; finish with initialization and wait for next interrupt
  97 
  98 ;program starts here every time but first
  99 ;initiate data transfer to codec
 100 sbi portb,portb0 ; toggle slave select pin
 101 out spdr,r3 ; send out left channel msb
 102 cbi portb,portb0
 103 
 104 ;increment sram address
 105 adiw r25:r24,$01 ; increment write address
 106 adiw r29:r28,$01 ; increment read address
 107 
 108 wait1_000003: ; check if byte has been sent
 109 
 110 in r17,spsr
 111 sbrs r17,spif
 112 rjmp wait1_000003
 113 in r7,spdr ; recieve in left channel msb
 114 out spdr,r2 ; send out left channel lsb
 115 
 116 ;get left channel data from sram
 117 out portd,r28 ; set address
 118 sts porth,r29
 119 nop ; wait input latch time of 2 clock cycles
 120 nop ; wait input latch time of 2 clock cycles
 121 in r2,pina ; get data
 122 in r3,pinc ; get data
 123 adiw r29:r28,$01 ; increment read address
 124 
 125 wait2_000003: ; check if byte has been sent
 126 
 127 in r17,spsr
 128 sbrs r17,spif
 129 rjmp wait2_000003
 130 in r6,spdr ; recieve in left channel lsb
 131 out spdr,r5 ; send out right channel msb
 132 
 133 ;write left channel data to sram
 134 out portd,r24 ; set address
 135 sts porth,r25
 136 out portg,r22 ; pull ce low,we low,and set high bits of address
 137 ldi r17,$ff
 138 out ddra,r17 ; set porta as output for data write
 139 out ddrc,r17 ; set portc as output for data write
 140 out porta,r6 ; set data
 141 out portc,r7
 142 sbi portg,portg2 ; pull we high to write
 143 out ddra,r22 ; set porta as input for data lines
 144 out ddrc,r22 ; set portc as input for data lines
 145 
 146 wait3_000003: ; check if byte has been sent
 147 
 148 in r17,spsr
 149 sbrs r17,spif
 150 rjmp wait3_000003
 151 in r9,spdr ; recieve in right channel msb
 152 out spdr,r4 ; send out right channel lsb
 153 
 154 ;get right channel data from sram
 155 out portd,r28 ; set address
 156 sts porth,r29
 157 nop ; wait input latch time of 2 clock cycles
 158 nop ; wait input latch time of 2 clock cycles
 159 in r4,pina ; get data
 160 in r5,pinc ; get data
 161 adiw r25:r24,$01 ; increment write address
 162 
 163 wait4_000003: ; check if byte has been sent
 164 
 165 in r17,spsr
 166 sbrs r17,spif
 167 rjmp wait4_000003
 168 in r8,spdr ; recieve in left channel lsb
 169 
 170 ;write right channel data to sram
 171 out portd,r24 ; set address
 172 sts porth,r25
 173 out portg,r22 ; pull ce low,we low,and set high bits of address
 174 ldi r17,$ff
 175 out ddra,r17 ; set porta as output for data write
 176 out ddrc,r17 ; set portc as output for data write
 177 out porta,r8 ; set data
 178 out portc,r9
 179 sbi portg,portg2 ; pull we high to write
 180 out ddra,r22 ; set porta as input for data lines
 181 out ddrc,r22 ; set portc as input for data lines
 182 
 183 ;get delay settings
 184 lds r17,adcsra ; get adc control register
 185 sbrs r17,adif ; check if adc conversion is complete
 186 rjmp shift_000003 ; skip adc sampling
 187 lds r16,adcl ; get low byte adc value
 188 lds r17,adch ; get high byte adc value
 189 add r10,r16 ; accumulate adc samples
 190 adc r11,r17
 191 adc r19,r22 ; r22 is cleared above
 192 ldi r17,$f7
 193 sts adcsra,r17 ; clear interrupt flag
 194 dec r14 ; countdown adc sample clock
 195 brne shift_000003 ; get delay time if its been long enough
 196 lsr r19 ; divide adc sample by 4
 197 ror r11 ; makes adc value a 16b number
 198 ror r10
 199 lsr r19
 200 ror r11
 201 ror r10
 202 ldi r16,$01 ; check if delay is below minimum
 203 cp r10,r22 ; r22 is cleared above
 204 cpc r11,r16
 205 brsh deadband_000003 ; check if adc value changed enough to update delay
 206 clr r10 ; set minimum delay to $0100 = 3ms
 207 mov r11,r16
 208 
 209 deadband_000003: ; set the low value of the delay
 210 
 211 movw r17:r16,r11:r10 ; move adc sample to temporary register
 212 sbc r16,r26 ; find difference between adc sample and desired delay time
 213 sbc r17,r27
 214 brsh check_000003 ; check for deadband if positive
 215 neg r16 ; invert if negative
 216 adc r17,r22 ; r22 is cleared above
 217 neg r17 ; converts ones complement to twos complement
 218 
 219 check_000003: ; check if difference is greater than deadband
 220 
 221 cpi r16,$40 ; check if difference is less than 1 lsb of adc
 222 cpc r17,r22 ; r22 cleared above
 223 brlo empty_000003 ; do nothing if less than 1 lsb
 224 movw r27:r26,r11:r10 ; move adc sample to delay time if large enough change
 225 andi r26,$fc ; make sure delay time is a multiple of 4
 226 
 227 empty_000003: ; empty accumulation registers and finish off
 228 
 229 clr r10 ; empty accumulation registers
 230 clr r11
 231 clr r19
 232 
 233 shift_000003: ; check if delay time is correct
 234 
 235 cp r26,r12 ; compare desired delay to actual delay
 236 cpc r27,r13
 237 breq switchsample_000003 ; do nothing if the same
 238 brlo indexdown_000003
 239 ldi r17,$04 ; increment delay register (4 is used for stereo data)
 240 add r12,r17 ; this makes it play forward at double speed
 241 adc r13,r22 ; until desired delay is reached
 242 rjmp switchsample_000003
 243 
 244 indexdown_000003:
 245 
 246 ldi r17,$02 ; decrement delay register (2 is used for stereo data)
 247 sub r12,r17 ; this makes is play backwards until desired delay is reached
 248 sbc r13,r22 ; r22 is cleared above
 249 
 250 switchsample_000003: ; check state of rotary switch
 251 
 252 dec r15 ; countdown switch counter
 253 brne done_000003 ; finish off if not ready yet
 254 lds r16,pinj ; get switch data
 255 andi r16,$78 ; mask off rotary switch
 256 lsr r16 ; adjust switch position to program memory location
 257 lsr r16
 258 ldi r17,$02
 259 add r16,r17
 260 cp r16,r31 ; check if location has changed
 261 breq done_000003 ; finish off if no change
 262 clr r30 ; reset jump register to new function if changed
 263 mov r31,r16
 264 
 265 done_000003:
 266 
 267 movw r29:r28,r25:r24 ; move write address to read destination register
 268 sub r28,r12 ; remove delay time
 269 sbc r29,r13
 270 reti ; return to waiting
 271 

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.