;**************************************************** ;EE 476 - Final Project .include "c:\windows\desktop\projects\8515def.inc" ;Uses the 8535 chip ;****************** ;Register Defs .def AnaLo =r4 ;ADC convert values .def past =r5 .def past2 =r6 .def temp =r16 ;temporary value register .def temp2 =r17 .def effect =r18 ;current effect .def ADCFlag =r19 ;Tells if the ADC is finished or not .def TXbusy =r20 ;transmit busy flag .def RXchar =r21 ;a received character .def parameterL=r22 ;low byte of input parameter .def parameterH=r23 ;high byte of input parameter ;EQUATES ;MACROS .macro outi ;out immediate macro ldi temp, @1 out @0, temp .endmacro ;timer schtuff .equ timskVal=0b01000000 ;sets Timer1 Compare A match .equ t1cAVal =0 ;no timer1 Output Stuff .equ t1cBVal =0b00001001 ;clear on match, prescale = 1 .equ t1oAVal =666 ;6kHz sampling rate ;.equ t1oAVal =1200 ;300Hz sampling rate ;.equ t1oAVal =2400 ;Really Slow!! ;UART schtuff .equ baud96 =25 ;9600 baud constant for 4Mhz crystal ;Effects .equ wire =0 ;no effects .equ inversion =1 ;inverting every other bit .equ swapping =2 ;reverse high order bits with low order .equ delay =3 ;delay is effect 1 .equ clipping =4 ;amplitude clipping .equ echo =5 ;echo effect .equ needsparameters =3 ;the lowest effect # that needs parameters ;port D bit definitions, outputs to ADC and input from it .equ ADCSCLK = 5 ;ADC serial clock output .equ ADCCS = 0 ;ADC chip select (active low) .equ ADCDIN = 2 ;ADC serial data .equ ADCDout = 3 ;ADC output .equ ADCSTRB = 4 ;ADC STROBE output to signal end of conversion ;other stuff .equ MaxDelay =15000 .equ Ack =0x55 ;Acknowledgement String ;******************* ;Data .dseg .org RAMEND+1 delayline: .byte 15000 ;the delay line ;******************* ;Code .cseg .org $0000 rjmp RESET ;reset entry vector reti ;IRQ0 reti ;IRQ1 reti ;Timer 1 Capture rjmp TIMER1A ;Timer 1 CompareA reti ;Timer 1 CompareB reti ;Timer 1 Overflow reti ;timer0 overflow reti ;SPI TX Complete rjmp RXDONE ;UART RX Complete reti ;UDR Empty reti ;rjmp TXDONE ;UART TX Complete reti ;Analog Compare ;**********RESET ISR RESET: ;RAM setup outi SPL, LOW(RAMEND) outi SPH, HIGH(RAMEND) outi MCUCR, 0b10000000 ;use external RAM ;Port setup outi DDRD, 0b000100100 ;set bits 2 & 5 to outputs and all outi portd, 0x00 outi DDRB, 0xFF ;make port B output outi PORTB, 0xFF ;Timer 1 Setup outi TIMSK, timskVal outi TCCR1A, t1cAVal outi TCCR1B, t1cBVal outi OCR1AH, HIGH(t1oAVal) outi OCR1AL, LOW(t1oAVal) ;setup UART -- enable TXempty & RXdone int, and RX, TX pins outi UCR, 0b10011000 outi UBRR, baud96 ;set baud rate to 9600 ;setup RAM Pointers ldi ZL, LOW(delayline) ldi ZH, HIGH(delayline) ;Initial Effect conditions ldi effect, wire ldi YL, LOW(delayline) ldi YH, HIGH(delayline) sei MAIN: tst ADCFlag ;Has the ADC given us an input yet? breq MAIN ;**************ADC Conversion READADC: cbi portD, ADCSCLK ;clear the clock line cbi portB, ADCCS ;chip select the ADC ldi temp, 0b10001110 ;the ADC command word ;unipolar (channel1) single ended conversion ;with internal clocking ;Change this for different functions of the ;ADC such as bipolar conversion or external ;clocking. ldi temp2,8 ;the bit counter ADC_SENDCOMMAND: rol temp ;shift out the 8-bit command .SET _skipcc = PC+2 brcc _skipcc sbi portD,ADCDin ;set the bit in Din .set _skipcs = PC+2 brcs _skipcs cbi portD, ADCDin ;clear the bit in Din sbi PortD, ADCSCLK ;SCLK high .SET _nextstep = PC+1 ;wait at least 200 nS rjmp _nextstep .SET _nextstep = PC+1 rjmp _nextstep cbi PortD, ADCSCLK ;SCLK low dec temp2 brne ADC_SENDCOMMAND _WAITLOOP: sbic portD, ADCSTRB ; wait until you receive a signal from strobe rjmp _WAITLOOP clr AnaLo ;refresh Main 3 ldi temp2, 10 ;shift in 8+2 bit result (2 leading 0's) ADC_RECEIVEDATA: clc ;first set the carry sbi PortD, ADCSCLK ;SCLK high .SET _nextstep = PC+1 ;wait at least 200 nS rjmp _nextstep .SET _nextstep = PC+1 rjmp _nextstep cbi PortD, ADCSCLK ;SCLK low sbis PinD, ADCDOUT ;if ADC data low is high, set carry sec ;inverted since low turns led on rol AnaLo ;shift carry into data buffer dec temp2 brne ADC_RECEIVEDATA;repeat until all bits read sbi PortB, ADCCS ;release ADC chip select clr ADCFlag ;+++++ st Z+, AnaLo ;save input value, increment pointer ldi temp, HIGH(delayline+MaxDelay) ;if reached end of delayline, go back to begining cpi ZL, LOW(delayline+MaxDelay) cpc ZH, temp brne _chooseEffects ldi ZL, LOW(delayline) ldi ZH, HIGH(delayline) ;--------------------Choose Effects---------------------- _chooseEffects: ld r0, Y+ ;load input value, increment value _selector: cpi effect, wire breq _output cpi effect, inversion breq _inversion cpi effect, swapping breq _swap cpi effect, delay breq _output cpi effect, clipping breq _clipping cpi effect, echo breq _echo ;-------------------------------------------------------- _output: ldi temp, 1 or r0, temp out PORTB, r0 ;out to LEDs ldi temp, HIGH(delayline+MaxDelay) ;if reached end of delayline, go back to begining cpi YL, LOW(delayline+MaxDelay) cpc YH, temp brne _dojump ldi YL, LOW(delayline) ldi YH, HIGH(delayline) rjmp _dojump _dojump: rjmp MAIN _inversion: sbrs YL, 0 com r0 ;inverts every other bit rjmp _output _swap: swap r0 rjmp _output _clipping: cp r0, parameterL brlt _lowclipping ;if below the low threshold, set value to threshold cp r0, parameterH ; brge _highclipping rjmp _output _lowclipping: mov r0, parameterL rjmp _output _highclipping: mov r0, parameterH rjmp _output _echo: mov XL, YL mov XH, YH ldi temp, 1 ldi temp2, 0 sub XL, temp sbc XH, temp2 mov temp, parameterL mov temp2, parameterH sub XL, temp sbc XH, temp2 ldi temp, high(delayLine) ;check to see if X<0... if so, wrap around cpi XL, low(delayLine) cpc XH, temp brge _processEcho ldi temp, low(MaxDelay) ;if X<0, then add MaxDelay for wrap around ldi temp2, high(MaxDelay) add XL, temp adc XH, temp2 _processEcho: ld past, X lsr past mov past2, past lsr past2 add past, past2 lsr past lsr r0 add r0, past ;this is the current sample plus 75% of a previous sample _echostage2: mov temp, parameterL mov temp2, parameterH sub XL, temp sbc XH, temp2 ldi temp, high(delayLine) ;check to see if X<0... if so, wrap around cpi XL, low(delayLine) cpc XH, temp brge _processEcho2 ldi temp, low(MaxDelay) ;if X<0, then add MaxDelay for wrap around ldi temp2, high(MaxDelay) add XL, temp adc XH, temp2 _processEcho2: ld past, X lsr past lsr past add r0, past ;this is the current sample plus 75% of a previous sample + 50% of a previous sample rjmp _output ;****************Timer 1 A Compare Match TIMER1A: push temp ser ADCFlag ;outi ADCSR, 0b11001001 ;Enable & Start ADC for one run at 2div prescale pop temp reti ;****************ADC Complete ;ADCDONE: ; ser ADCFlag ;sets the ADC done flag ; reti ;****************UART guys ; TX done -- buffer is empty TXDONE: push temp in temp, SREG ;save processor status push temp pop temp out SREG, temp ;restore proc status pop temp reti ;back to pgm ; UART read a character RXDONE: push temp in temp, SREG ;save processor status push temp in RXchar, UDR ;get the character ; out UDR, RXchar ;echo character - for Hyperterminal only ; subi RXChar, 0x30 ;convert to decimal -- NEEDS to be for HYPERTERM ;Calculate effects mov effect, RXchar mov YL, ZL ;setup initial conditions for Y to current Z value mov YH, ZH cpi effect, needsparameters ;check to see if effect needs parameters brlt InitEffects ;if no, skip parameter check. ;-------------------------Send/Receive Parameters-------------------- ldi temp, Ack ;acknowledgement string mov RXChar, temp out UDR, RXChar ;send acknowledgement CharSent: sbis USR, TXC ;check to see if transmit is complete rjmp CharSent cbi USR, TXC ;clear the transmit complete bit ParamLRead: sbis USR, RXC ;have we received the data yet? rjmp ParamLRead cbi USR, RXC ;clear the receive complete bit in parameterL, UDR ;get the character ; subi parameterL, '0' out PORTB, parameterL ldi temp, Ack ;acknowledgement string mov RXChar, temp out UDR, RXChar ;send acknowledgement NextCharSent: sbis USR, TXC ;check to see if transmit is complete rjmp NextCharSent cbi USR, TXC ;clear the transmit complete bit ParamHRead: sbis USR, RXC ;have we received the data yet? rjmp ParamHRead cbi USR, RXC ;clear the receive complete bit in parameterH, UDR ;get the character ; subi parameterH, '0' out PORTB, parameterH ;-------------------------End of Send/Receive Parameters-------------------- InitEffects: ;wire? cpi effect, wire brne _inversionsetup rjmp _endcase _inversionsetup: cpi effect, inversion brne _delay rjmp _endcase _delay:;delay? cpi effect, delay brne _amplitudeclipping sub YL, parameterL ;subtract the delay offset sbc YH, parameterH ldi temp, high(delayLine) ;check to see if Y<0... if so, wrap around cpi YL, low(delayLine) cpc YH, temp brge _endcase ldi temp, low(MaxDelay) ;if Y<0, then add MaxDelay for wrap around ldi temp2, high(MaxDelay) add YL, temp adc YH, temp2 rjmp _endcase _amplitudeclipping: cpi effect, clipping brne _echoEffect rjmp _endcase _echoEffect: cpi effect, echo brne _nexteffect rjmp _endcase _nexteffect: _endcase: pop temp out SREG, temp ;restore proc status pop temp reti ;back to program