welcome: please sign in
location: attachment:updown_sweep.asm of UpDownSweep

Attachment 'updown_sweep.asm'

Download

   1 ; program: up_downsweep-18b-pot.asm
   2 ; UID = 000035 - unique id to eliminate conflicts between variables
   3 ; 18b address space (3s sample time)
   4 ; stereo data
   5 ; pot (MOD1) controlled buffer size (3ms - 1.5s)
   6 
   7 ; program overview
   8 ;
   9 ; data is read in from memory and written out to the codec at the same time
  10 ; new data is written to the memory from the codec.  the write address
  11 ; increments until it reaches the top of the buffer and then starts at
  12 ; zero.  the read address increases at twice the rate until it reaches the
  13 ; write address, and then decreases until it reaches the write address.
  14 ; it continues this back and forth sample playback.  ADC0 (MOD1) is read
  15 ; and averaged over 256 samples to reduce jitter.  this value is subtracted
  16 ; from the write address to create the desired read address.  if the actual
  17 ; read address doesnt match the desired read address, it is either
  18 ; incremented or decremented by one sample each sample period until it
  19 ; matches.  this reduces noise during delay time transitions.
  20 
  21 ; register usage - may be redefined in other sections
  22 ;
  23 ; r0  desired buffer size fractional byte
  24 ; r1  
  25 ; r2  left lsb out
  26 ; r3  left msb out
  27 ; r4  right lsb out
  28 ; r5  right msb out
  29 ; r6  left lsb in
  30 ; r7  left msb in
  31 ; r8  right lsb in
  32 ; r9  right msb in
  33 ; r10 adc accumulation lsb
  34 ; r11 adc accumulation msb
  35 ; r12 read address offset lsb
  36 ; r13 read address offset msb
  37 ; r14 adc/switch sample counter
  38 ; r15 
  39 ; r16 temporary swap register
  40 ; r17 temporary swap register
  41 ; r18 null register
  42 ; r19 adc accumulation fractional byte
  43 ; r20 temporary swap regiser
  44 ; r21 read address offset high byte
  45 ; r22 write address high byte
  46 ; r23 read address high byte
  47 ; r24 write address lsb
  48 ; r25 write address msb
  49 ; r26 desired buffer size lsb
  50 ; r27 desired buffer size msb
  51 ; r28 read address lsb
  52 ; r29 read address msb
  53 ; r30 jump location for interrupt lsb
  54 ; r31 jump location for interrupt msb
  55 ; t   forward/reverse indicator
  56 
  57 ; program starts here first time
  58 ; initialze z pointer for correct jump
  59 ; this assumes a less than 256 word jump
  60 ldi r30,$29 ; set jump location to program start
  61 clr r24 ; clear write register
  62 clr r25
  63 ldi r22,$00 ; setup write address high byte
  64 clr r18 ; setup r18 as null register for carry addition and ddr setting
  65 ldi r17,$ff ; setup r17 for ddr setting
  66 
  67 clear_000035: ; clear delay buffer
  68 ; eliminates static when first switching to the delay setting
  69 
  70 adiw r25:r24,$01 ; increment write register
  71 adc r22,r18 ; increment write third byte
  72 cpi r22,$04 ; check if full memory space has been cleared
  73 breq cleardone_000035 ; continue until end of buffer reached
  74 out portd,r24 ; set address
  75 sts porth,r25
  76 out portg,r22 ; pull ce low,we low,and set high bits of address
  77 out ddra,r17 ; set porta as output for data write
  78 out ddrc,r17 ; set portc as output for data write
  79 out porta,r18 ; set data
  80 out portc,r18 ; r18 is cleared above
  81 sbi portg,portg2 ; pull we high to write
  82 out ddra,r18 ; set porta as input for data lines
  83 out ddrc,r18 ; set portc as input for data lines
  84 rjmp clear_000035 ; continue clearing
  85 
  86 cleardone_000035: ; reset registers
  87 
  88 ldi r24,$00 ; initialize write register
  89 ldi r25,$00
  90 ldi r22,$00 ; setup write address high byte
  91 ldi r28,$00 ; set read address to minimum delay
  92 ldi r29,$fe
  93 ldi r23,$07 ; setup read address high byte
  94 clr r0 ; set buffer size to minimum
  95 ldi r26,$01
  96 clr r27
  97 clr r12 ; set read address offset to minimum buffer size
  98 ldi r16,$01
  99 mov r13,r16
 100 clr r21
 101 clr r2 ; initialize data output registers
 102 clr r3
 103 clr r4
 104 clr r5
 105 clt ; clear t register to start with forward play
 106 reti ; finish with initialization and wait for next interrupt
 107 
 108 ; program starts here all but first time
 109 ; this is the point the z-pointer is incremented to
 110 ; initiate data transfer to codec
 111 sbi portb,portb0 ; toggle slave select pin
 112 out spdr,r3 ; send out left channel msb
 113 cbi portb,portb0
 114 
 115 wait1_000035: ; check if byte has been sent
 116 
 117 in r17,spsr
 118 sbrs r17,spif
 119 rjmp wait1_000035
 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 for efficient use of setup time
 129 andi r23,$03 ; mask off unsed bits
 130 ori r23,$04 ; set we/ bit in high byte register
 131 in r2,pina ; get data
 132 in r3,pinc ; get data
 133 
 134 wait2_000035: ; check if byte has been sent
 135 
 136 in r17,spsr
 137 sbrs r17,spif
 138 rjmp wait2_000035
 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_000035: ; check if byte has been sent
 156 
 157 in r17,spsr
 158 sbrs r17,spif
 159 rjmp wait3_000035
 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, and set high bits of register
 165 out portd,r28 ; set address
 166 sts porth,r29
 167 adiw r25:r24,$01 ; increment write address
 168 adc r22,r18 ; placed here to use setup time efficiently
 169 andi r22,$03 ; mask off unsed bits
 170 in r4,pina ; get data
 171 in r5,pinc ; get data
 172 
 173 wait4_000035: ; check if byte has been sent
 174 
 175 in r17,spsr
 176 sbrs r17,spif
 177 rjmp wait4_000035
 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 ;increment write address to next sample position
 194 adiw r25:r24,$01 ; increment write address
 195 adc r22,r18 ; increment write third byte
 196 andi r22,$03 ; mask off unsed bits
 197 movw r29:r28,r25:r24 ; move write address to read address
 198 mov r23,r22
 199 
 200 ;calculate read offset
 201 brtc increment_000035 ; move read address forward if in foward mode
 202 ldi r16,$04 ; else move read address backwards by 2
 203 add r12,r16 ; this requires incrementing the read offset by 4
 204 adc r13,r18 ; r18 is cleared above
 205 adc r21,r18
 206 cp r12,r0 ; check if at bottom of buffer
 207 cpc r13,r26
 208 cpc r21,r27
 209 brlo readadd_000035 ; load read address if not at bottom of buffer
 210 clt ; else clear t register to indicate forward motion after next sample
 211 ; decrement offset by 2 - this halts playback for one sample
 212 ; to reduce spikes at transitions
 213 
 214 increment_000035: ; move read address forward by 4
 215 ; moving read address forward requires reducing the read offset by 2
 216 ldi r16,$02 ; subtract 2 from read offset
 217 sub r12,r16
 218 sbc r13,r18 ; r18 is cleared above
 219 sbc r21,r18
 220 brne readadd_000035 ; load read address if not at top of buffer
 221 ldi r16,$04 ; set to playback last played sample
 222 mov r12,r16 ; reduces spikes at transitions
 223 set ; else set t register to start reversing on next sample
 224 
 225 readadd_000035: ; add in read offset
 226 
 227 sub r28,r12 ; subtract offset from read address
 228 sbc r29,r13
 229 sbc r23,r21
 230 andi r23,$03 ; mask off unused bits
 231 ori r23,$04 ; set we/ bit for reading
 232 
 233 adcsample_000035: ; get buffer size from adc
 234 
 235 lds r17,adcsra ; get adc control register
 236 sbrs r17,adif ; check if adc conversion is complete
 237 rjmp done_000035 ; skip adc sampling if not
 238 lds r16,adcl ; get low byte adc value
 239 lds r17,adch ; get high byte adc value
 240 add r19,r16 ; accumulate adc samples
 241 adc r10,r17
 242 adc r11,r18 ; r18 is cleared above
 243 ldi r17,$f7
 244 sts adcsra,r17 ; clear interrupt flag
 245 dec r14 ; countdown adc sample clock
 246 brne done_000035 ; dont get buffer size till its been long enough
 247 lsr r11 ; divide adc sample by 2
 248 ror r10 ; as the max buffer size is only $020000
 249 ror r19 ; as the buffer is read backwards half of the time
 250 ldi r17,$01 ; check if adc value is less than $000100
 251 cp r10,r17
 252 cpc r11,r18 ; r18 cleared above
 253 brsh deadband_000035 ; check if adc value changed enough to update delay
 254 mov r10,r17 ; set minimum delay to $000100 = 3ms
 255 clr r19
 256 
 257 deadband_000035: ; check for change in adc value
 258 
 259 movw r17:r16,r11:r10 ; move adc sample to temporary register
 260 mov r20,r19
 261 sub r20,r0 ; find difference between adc sample and desired buffer size
 262 sbc r16,r26
 263 sbc r17,r27
 264 brsh check_000035 ; check for deadband if positive
 265 com r20 ; invert if negative
 266 com r16 ; using ones complement as it is faster, and only has 1 bit error
 267 com r17
 268 
 269 check_000035: ; check if difference is greater than deadband
 270 
 271 cpi r20,$80 ; check if difference is less than 1 lsb
 272 cpc r16,r18 ; r18 cleared above
 273 cpc r17,r18
 274 brlo empty_000035 ; do nothing if less than 1 lsb
 275 movw r27:r26,r11:r10 ; move adc sample to delay time if large enough change
 276 andi r19,$fc ; make sure buffer size is a multiple of 4
 277 mov r0,r19
 278 
 279 empty_000035: ; empty accumulation registers and finish off
 280 
 281 clr r10 ; empty accumulation registers
 282 clr r11
 283 clr r19
 284 
 285 switchsample_000035: ; check if at same function
 286 
 287 lds r16,pinj ; get switch data
 288 andi r16,$78 ; mask off rotary switch
 289 lsr r16 ; adjust switch position to program memory location
 290 lsr r16
 291 ldi r17,$02
 292 add r16,r17 ; move to jump register
 293 cpse r16,r31 ; check if location has changed
 294 clr r30 ; reset jump register to intial state
 295 mov r31,r16
 296 
 297 done_000035:
 298 
 299 reti ; return to waiting
 300 

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.