welcome: please sign in
location: attachment:delay_ping_pong.asm of DelayPingPong

Attachment 'delay_ping_pong.asm'

Download

   1 ; program: ping_pong-18b-pot.asm
   2 ; UID = 000030 - unique id to eliminate conflicts between variables
   3 ; 18b address space (3s delay time)
   4 ; stereo data - left and right swap to create ping-pong effect
   5 ; pot (MOD1) controlled delay time (3ms - 3s)
   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.  the left
  16 ; channel input is recorded to the right channel output buffer (and vice
  17 ; versa), so the sound bounces back and forth between the two channels.
  18 
  19 ; register usage - may be redefined in other sections
  20 ;
  21 ; r0  deisred delay time fractional byte
  22 ; r1  
  23 ; r2  left lsb out
  24 ; r3  left msb out
  25 ; r4  right lsb out
  26 ; r5  right msb out
  27 ; r6  left lsb in
  28 ; r7  left msb in
  29 ; r8  right lsb in
  30 ; r9  right msb in
  31 ; r10 adc accumulator lsb
  32 ; r11 adc accumulator msb
  33 ; r12 actual delay lsb
  34 ; r13 actual delay msb
  35 ; r14 adc sample counter
  36 ; r15 switch sample counter
  37 ; r16 temporary swap register
  38 ; r17 temporary swap register
  39 ; r18 null register
  40 ; r19 adc accumulator fractional byte
  41 ; r20 temporary swap register
  42 ; r21 actual delay fractional byte
  43 ; r22 write address third byte
  44 ; r23 read address third byte
  45 ; r24 write address lsb
  46 ; r25 write address msb
  47 ; r26 desired delay lsb
  48 ; r27 desired delay msb
  49 ; r28 read address lsb
  50 ; r29 read address msb
  51 ; r30 jump location for interrupt lsb
  52 ; r31 jump location for interrupt msb
  53 ; t   
  54 
  55 ;program starts here first time
  56 ldi r30,$25 ; set jump location to program start
  57 clr r24 ; clear write register
  58 clr r25
  59 ldi r22,$00 ; setup write address high byte
  60 clr r18 ; setup r18 as null register for carry addition and ddr setting
  61 ldi r17,$ff ; setup r17 for ddr setting
  62 
  63 clear_000030: ; clear delay buffer
  64 ; eliminates static when first switching to the delay setting
  65 
  66 adiw r25:r24,$01 ; increment write register
  67 adc r22,r18 ; increment write third byte
  68 cpi r22,$04 ; check if full memory space has been cleared
  69 breq cleardone_000030 ; continue until end of buffer reached
  70 out portd,r24 ; set address
  71 sts porth,r25
  72 out portg,r22 ; pull ce low,we low,and set high bits of address
  73 out ddra,r17 ; set porta as output for data write
  74 out ddrc,r17 ; set portc as output for data write
  75 out porta,r18 ; set data
  76 out portc,r18 ; r18 is cleared above
  77 sbi portg,portg2 ; pull we high to write
  78 out ddra,r18 ; set porta as input for data lines
  79 out ddrc,r18 ; set portc as input for data lines
  80 rjmp clear_000030 ; continue clearing
  81 
  82 cleardone_000030: ; reset registers
  83 
  84 clr r24 ; clear write register
  85 clr r25
  86 ldi r22,$00 ; setup write address high byte
  87 clr r28 ; set read address to minimum delay
  88 ldi r29,$ff
  89 ldi r23,$07 ; setup read address high byte
  90 clr r21 ; set actual delay time to minimum delay
  91 ldi r16,$01
  92 mov r12,r16
  93 clr r13
  94 clr r2 ; initialize data output registers
  95 clr r3
  96 clr r4
  97 clr r5
  98 reti ; finish with initialization and wait for next interrupt
  99 
 100 ; program starts here every time but first
 101 ; initiate data transfer to codec
 102 sbi portb,portb0 ; toggle slave select pin
 103 out spdr,r3 ; send out left channel msb
 104 cbi portb,portb0
 105 
 106 ;increment sram addresses
 107 adiw r25:r24,$01 ; increment write address
 108 adc r22,r18 ; increment write third byte
 109 andi r22,$03 ; mask off unsed bits
 110 adiw r29:r28,$01 ; increment read address
 111 adc r23,r18 ; increment read third byte
 112 andi r23,$03 ; mask off unsed bits
 113 ori r23,$04 ; set we bit for reading
 114 
 115 wait1_000030: ; check if byte has been sent
 116 
 117 in r17,spsr
 118 sbrs r17,spif
 119 rjmp wait1_000030
 120 in r7,spdr ; recieve in left channel msb
 121 out spdr,r2 ; send out left channel lsb
 122 
 123 ;get left channel data from sram
 124 out portg,r23 ; pull ce low, we high, and set high bits of register
 125 out portd,r28 ; set address
 126 sts porth,r29
 127 adiw r29:r28,$01 ; increment read address
 128 adc r23,r18 ; placed here to use setup time efficiently
 129 andi r23,$03 ; mask off unsed bits
 130 ori r23,$04 ; set we bit for reading
 131 in r2,pina ; get data
 132 in r3,pinc ; get data
 133 
 134 wait2_000030: ; check if byte has been sent
 135 
 136 in r17,spsr
 137 sbrs r17,spif
 138 rjmp wait2_000030
 139 in r6,spdr ; recieve in left channel lsb
 140 out spdr,r5 ; send out right channel msb
 141 
 142 ;write left channel data to sram
 143 out portd,r24 ; set address
 144 sts porth,r25
 145 out portg,r22 ; pull ce low,we low,and set high bits of address
 146 ldi r17,$ff
 147 out ddra,r17 ; set porta as output for data write
 148 out ddrc,r17 ; set portc as output for data write
 149 out porta,r6 ; set data
 150 out portc,r7
 151 sbi portg,portg2 ; pull we high to write
 152 out ddra,r18 ; set porta as input for data lines
 153 out ddrc,r18 ; set portc as input for data lines
 154 
 155 wait3_000030: ; check if byte has been sent
 156 
 157 in r17,spsr
 158 sbrs r17,spif
 159 rjmp wait3_000030
 160 in r9,spdr ; recieve in right channel msb
 161 out spdr,r4 ; send out right channel lsb
 162 
 163 ;get right channel data from sram
 164 out portg,r23 ; pull ce low,we high,oe low, and set high bits of address
 165 out portd,r28 ; set address
 166 sts porth,r29
 167 adiw r25:r24,$01 ; increment write address
 168 adc r22,r18 ; placed here for efficient use of setup time
 169 andi r22,$03 ; mask off unsed bits
 170 in r4,pina ; get data
 171 in r5,pinc ; get data
 172 
 173 wait4_000030: ; check if byte has been sent
 174 
 175 in r17,spsr
 176 sbrs r17,spif
 177 rjmp wait4_000030
 178 in r8,spdr ; recieve in left channel lsb
 179 
 180 ;write right channel data to sram
 181 out portd,r24 ; set address
 182 sts porth,r25
 183 out portg,r22 ; pull ce low,we low,and set high bits of address
 184 ldi r17,$ff
 185 out ddra,r17 ; set porta as output for data write
 186 out ddrc,r17 ; set portc as output for data write
 187 out porta,r8 ; set data
 188 out portc,r9
 189 sbi portg,portg2 ; pull we high to write
 190 out ddra,r18 ; set porta as input for data lines
 191 out ddrc,r18 ; set portc as input for data lines
 192 
 193 ; get delay settings
 194 lds r17,adcsra ; get adc control register
 195 sbrs r17,adif ; check if adc conversion is complete
 196 rjmp shift_000030 ; skip adc sampling
 197 lds r16,adcl ; get low byte adc value
 198 lds r17,adch ; get high byte adc value
 199 add r19,r16 ; accumulate adc samples
 200 adc r10,r17
 201 adc r11,r18 ; r18 is cleared above
 202 ldi r17,$f7
 203 sts adcsra,r17 ; clear interrupt flag
 204 dec r14 ; countdown adc sample clock
 205 brne shift_000030 ; get delay time if its been long enough
 206 ldi r17,$01 ; check if adc value is less than $000100
 207 cp r19,r18 ; r18 is cleared above
 208 cpc r10,r17
 209 cpc r11,r18
 210 brsh deadband_000030 ; check if adc value changed enough to update delay
 211 inc r10 ; set minimum delay to $000100 = 3ms
 212 clr r19
 213 
 214 deadband_000030: ; check for change in adc value
 215 
 216 movw r17:r16,r11:r10 ; move adc sample to temporary register
 217 mov r20,r19
 218 sub r20,r0 ; find difference between adc sample and desired delay time
 219 sbc r16,r26
 220 sbc r17,r27
 221 brsh check_000030 ; check for deadband if positive
 222 com r20 ; invert if negative
 223 com r16 ; using ones complement as it is faster, and only has 1 bit error
 224 com r17
 225 
 226 check_000030: ; check if difference is greater than deadband
 227 
 228 cpi r16,$01 ; check if difference is less than 1 lsb
 229 cpc r17,r18 ; r18 cleared above
 230 brlo empty_000030 ; do nothing if less than 1 lsb
 231 movw r27:r26,r11:r10 ; move adc sample to delay time if large enough change
 232 andi r19,$fc ; make sure delay time is a multiple of 4
 233 mov r0,r19
 234 
 235 empty_000030: ; empty accumulation registers and finish off
 236 
 237 clr r10 ; empty accumulation registers
 238 clr r11
 239 clr r19
 240 
 241 shift_000030: ; check if delay time is correct
 242 
 243 cp r0,r21 ; compare desired delay to actual delay
 244 cpc r26,r12
 245 cpc r27,r13
 246 breq switchsample_000030 ; do nothing if the same
 247 brlo indexdown_000030
 248 ldi r17,$04 ; increment delay register
 249 add r21,r17
 250 adc r12,r18 ; r18 is cleared above
 251 adc r13,r18
 252 ldi r17,$03
 253 and r13,r17 ; mask off unused bits
 254 rjmp switchsample_000030
 255 
 256 indexdown_000030:
 257 
 258 subi r21,$02 ; decrement delay register
 259 sbc r12,r18 ; r18 is cleared above
 260 sbc r13,r18
 261 ldi r17,$03
 262 and r13,r17 ; mask off unused bits
 263 
 264 switchsample_000030: ; check state of rotary switch
 265 
 266 dec r15
 267 brne done_000030
 268 lds r16,pinj ; get switch data
 269 andi r16,$78 ; mask off rotary switch
 270 lsr r16 ; adjust switch position to program memory location
 271 lsr r16
 272 ldi r17,$02
 273 add r16,r17 ; move to jump register
 274 cp r16,r31 ; check if location has changed
 275 breq done_000030 ; finish off if no change
 276 clr r30 ; reset jump register to intial state
 277 mov r31,r16
 278 
 279 done_000030:
 280 
 281 movw r29:r28,r25:r24 ; move write address to read destination register
 282 mov r23,r22 ; move write third byte to read third byte
 283 sub r28,r21 ; subtract delay time
 284 sbc r29,r12
 285 sbc r23,r13
 286 andi r23,$03 ; mask off unsed bits
 287 ori r23,$04 ; set we bit for reading
 288 movw r17:r16,r3:r2 ; swap left and right channels
 289 movw r3:r2,r5:r4
 290 movw r5:r4,r17:r16
 291 reti
 292 

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.