;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; 3 x VCO na AT90s1200 3VCO-VOI.ASM 020916 ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; ; Finterrupt = Fsamp = 12MHz/64 = 187,5 kHz ; (planowane: 14MHz/56 = 250 kHz) ; ; --> odbior danych PWM ; ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; PB0..PB7 lokalna szyna danych ; PD0 wyjscie diagnostyczne ; PD1 wyjscie do OE\ HC574 ; PD2 wejscie INT\ = Fsamp ; PD3 wyjscie do MUXEN\ ; PD4 wyjscie do MUXA ; PD5 wyjscie do MUXB ; PD6 wyjscie do MUXC ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; C O N S T A N T S ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ;port D: к--------- PD6 = MUXC ; Гк-------- PD5 = MUXB ; ГГк------- PD4 = MUXA ; ГГГк------ PD3 = MUXEN\ ; ГГГГк----- PD2 = INT0\ ; ГГГГГк---- PD1 = OE\ HC574 ; ГГГГГГк--- PD0 = diagnostyka PD_DISABLE EQU 00001110b PD_OE574_0 EQU 00001100b PD_CHAN0 EQU 00000110b PD_CHAN1 EQU 00010110b PD_CHAN2 EQU 00100110b PD_CHAN3 EQU 00110111b PD_CHAN4 EQU 01000111b PD_CHAN5 EQU 01010111b PD_CHAN6 EQU 01100111b PD_CHAN7 EQU 01110111b ;rozkazy procesora glownego: CMD_DATA EQU 0x80 ; 1 0 0 0 0 d2 d1 d0 ;potem nastepuje bajt danych: 0 d9 d8 d7 d6 d5 d4 d3 CMD_VCO1 EQU 0x90 ; 1 0 0 1 0 d12 d11 d10 ;potem nastepuje bajt danych: 0 d19 d18 d17 d16 d15 d14 d13 CMD_VCO2 EQU 0xA0 ; 1 0 1 0 0 d12 d11 d10 ;potem nastepuje bajt danych: 0 d19 d18 d17 d16 d15 d14 d13 CMD_VCO3 EQU 0xB0 ; 1 0 1 1 0 d12 d11 d10 ;potem nastepuje bajt danych: 0 d19 d18 d17 d16 d15 d14 d13 CMD_PWM1 EQU 0xC0 ; 1 1 0 0 0 0 0 d0 ;potem nastepuje bajt danych: 0 d7 d6 d5 d4 d3 d2 d1 CMD_PWM2 EQU 0xC8 ; 1 1 0 0 1 0 0 d0 ;potem nastepuje bajt danych: 0 d7 d6 d5 d4 d3 d2 d1 CMD_PWM3 EQU 0xD0 ; 1 1 0 1 0 0 0 d0 ;potem nastepuje bajt danych: 0 d7 d6 d5 d4 d3 d2 d1 CMD_VCF EQU 0xD8 ; 1 1 0 1 1 0 0 d0 ;potem nastepuje bajt danych: 0 d7 d6 d5 d4 d3 d2 d1 CMD_VCA EQU 0xE0 ; 1 1 1 0 0 0 0 d0 ;potem nastepuje bajt danych: 0 d7 d6 d5 d4 d3 d2 d1 ;adresy I/O w AT90S1200: ACSR EQU 0x08 PIND EQU 0x10 DDRD EQU 0x11 PORTD EQU 0x12 PINB EQU 0x16 DDRB EQU 0x17 PORTB EQU 0x18 EECR EQU 0x1C EEDR EQU 0x1D EEAR EQU 0x1E WDTCR EQU 0x21 TCNT0 EQU 0x32 TCCR0 EQU 0x33 MCUCR EQU 0x35 TIFR EQU 0x38 TIMSK EQU 0x39 GIMSK EQU 0x3B SREG EQU 0x3F ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; V A R I A B L E S ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл PHASE1_L EQU R0 PHASE1_M EQU R1 PHASE1_H EQU R2 PHASE2_L EQU R3 PHASE2_M EQU R4 PHASE2_H EQU R5 PHASE3_L EQU R6 PHASE3_M EQU R7 PHASE3_H EQU R8 PHASEDELTA1_L EQU R9 PHASEDELTA1_M EQU R10 PHASEDELTA1_H EQU R11 PHASEDELTA2_L EQU R12 PHASEDELTA2_M EQU R13 PHASEDELTA2_H EQU R14 PHASEDELTA3_L EQU R15 PHASEDELTA3_M EQU R16 PHASEDELTA3_H EQU R17 MUXDISABLE EQU R18 RIN0 EQU R19 ;\ SREGBUF EQU R20 ;/ uzywane w INT0 INPUTHC574 EQU R21 DACDATA EQU R22 DACCHAN EQU R23 HOST_CMD EQU R24 ;rozkaz od procesora glownego HOST_DATA1 EQU R25 ;dane od procesora glownego HOST_DATA2 EQU R26 ;dane od procesora glownego PWM1VALUE EQU R27 ;wartosc PWM1 PWM2VALUE EQU R28 ;wartosc PWM2 PWM3VALUE EQU R29 ;wartosc PWM3 ; EQU R30 ;uzywany w programie glownym ; EQU R31 ;uzywany w programie glownym VCFVALUE EQU EEDR ;wartosc VCF (EEDR jako rejestr R/W) VCAVALUE EQU TCNT0 ;wartosc VCA (TCNT0 jako rejestr R/W) ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; V E C T O R T A B L E ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ORG 0 rjmp RESET ;0x000 RESET rjmp INT_EXT0 ;0x001 INT0 reti ;0x002 TIMER0 OVF reti ;0x003 ANA_COMP ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; I N T E R R U P T S U B R O U T I N E S ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ;----------------------------------------------------------------------------- ; Timer0 overflow ;----------------------------------------------------------------------------- INT_T0OVF: reti ;----------------------------------------------------------------------------- ; Interrupt 0 ;----------------------------------------------------------------------------- ;Uses: RIN0,SREGBUF ;----------------------------------------------------------------------------- INT_EXT0: in SREGBUF,SREG ;odczytanie portu HC574 (dane z procesora glownego): out PORTD,MUXDISABLE ;MUX = off ldi RIN0,00000000b ;\ out DDRB,RIN0 ;/ PB = iiiiiiii ldi RIN0,PD_OE574_0 out PORTD,RIN0 ;OE\ = 0 nop nop nop nop nop nop in INPUTHC574,PINB ;odczyt HC574 out PORTD,MUXDISABLE ;OE\ = 1, MUX = off ldi RIN0,11111111b ;\ out DDRB,RIN0 ;/ PB = oooooooo ;wyslanie do DAC0, zwiekszenie fazy VCO1: ldi RIN0,PD_CHAN0 ;channel 0 out PORTB,PHASE1_H ;SAW1 --> DAC add PHASE1_L,PHASEDELTA1_L adc PHASE1_M,PHASEDELTA1_M adc PHASE1_H,PHASEDELTA1_H out PORTD,RIN0 ;MUX = channel 0 ;wyslanie do DAC1, zwiekszenie fazy VCO2: ldi RIN0,PD_CHAN1 ;channel 1 out PORTD,MUXDISABLE ;MUX = off out PORTB,PHASE2_H ;SAW2 --> DAC add PHASE2_L,PHASEDELTA2_L adc PHASE2_M,PHASEDELTA2_M adc PHASE2_H,PHASEDELTA2_H out PORTD,RIN0 ;MUX = channel 1 ;wyslanie do DAC2, zwiekszenie fazy VCO3: ldi RIN0,PD_CHAN2 ;channel 2 out PORTD,MUXDISABLE ;MUX = off out PORTB,PHASE3_H ;SAW 3 --> DAC add PHASE3_L,PHASEDELTA3_L adc PHASE3_M,PHASEDELTA3_M adc PHASE3_H,PHASEDELTA3_H out PORTD,RIN0 ;MUX = channel 2 nop nop ;wyslanie do DAC3..DAC7: out PORTD,MUXDISABLE ;MUX = off out PORTB,DACDATA ;DATA out nop nop nop out SREG,SREGBUF out PORTD,DACCHAN ;MUX = channel 3..7 reti ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; M A I N L E V E L S U B R O U T I N E S ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ;----------------------------------------------------------------------------- ;In: - ;Out: - ;Used: - ;----------------------------------------------------------------------------- ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; M A I N P R O G R A M ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл RESET: cli ;disable interrupts ;inicjuj zmienne: clr PHASE1_L clr PHASE1_M clr PHASE1_H clr PHASE2_L clr PHASE2_M clr PHASE2_H clr PHASE3_L clr PHASE3_M clr PHASE3_H ;wstepne ustawienie czestotliwosci VCO1..VCO3: ;Nvco = (2^24/Fsamp) * Fvco ldi R31,0 ldi R30,0x5B mov PHASEDELTA1_L,R31 mov PHASEDELTA1_M,R30 mov PHASEDELTA1_H,R31 ldi R30,0x5A mov PHASEDELTA2_L,R31 mov PHASEDELTA2_M,R30 mov PHASEDELTA2_H,R31 ldi R30,0x5C mov PHASEDELTA3_L,R31 mov PHASEDELTA3_M,R30 mov PHASEDELTA3_H,R31 ; ldi MUXDISABLE,PD_DISABLE ;MUXEN\ = 1, OE\ = 1 clr INPUTHC574 clr HOST_CMD ldi PWM1VALUE,128 ldi PWM2VALUE,64 ldi PWM3VALUE,32 ldi R31,255 out VCFVALUE,R31 out VCAVALUE,R31 ;inicjuj port D (control): mov R31,MUXDISABLE ;\ out PORTD,R31 ;/ PD = x0001p10 ldi R31,01111011b ;\ out DDRD,R31 ;/ PD = xooooioo ;inicjuj port B (data): ldi R31,00000000b ;\ out PORTB,R31 ;/ PB = 00000000 ldi R31,11111111b ;\ out DDRB,R31 ;/ PB = oooooooo ;inicjuj Timer 0: ldi R31,00000000b ;\ out TCCR0,R31 ;/ stop ;uruchom przerwania: ldi R31,00000010b ;\ out MCUCR,R31 ;/ INT0: falling edge ldi R31,01000000b ;\ out GIMSK,R31 ;/ INT0 interrupt enable ldi R31,00000000b ;\ out TIMSK,R31 ;/ Timer0 interrupt disable sei ;Global Interrupt Enable ;petla glowna: MAINLOOP: ;obsluga rozkazow i danych z procesora glownego: mov R31,INPUTHC574 tst R31 brpl MLP_INDATA ;skok gdy 0xxxxxxx (dane) MLP_INCOMMAND: mov HOST_CMD,R31 ;zapisz rozkaz gdy 1xxxxxxx rjmp MLP_INEXIT MLP_INDATA: mov R30,HOST_CMD ;R30 = x x x x x d2 d1 d0 ;lub x x x x x d12 d11 d10 ;lub x x x x x x x d0 andi HOST_CMD,11111000b cpi HOST_CMD,CMD_DATA brne MLP_IN_NOTDAT ;CMD_DATA: ;R30 = x x x x x d2 d1 d0 ;R31 = 0 d9 d8 d7 d6 d5 d4 d3 lsl R31 ;R31 = d9 d8 d7 d6 d5 d4 d3 0 lsl R31 ;\ HOST_DATA2 = x x x x x x x d9 rol HOST_DATA2 ;/ R31 = d8 d7 d6 d5 d4 d3 0 0 lsl R31 ;\ HOST_DATA2 = x x x x x x d9 d8 rol HOST_DATA2 ;/ R31 = d7 d6 d5 d4 d3 0 0 0 sbrc R30,2 ;\ ori R31,00000100b ;/ R31 = d7 d6 d5 d4 d3 d2 0 0 sbrc R30,1 ;\ ori R31,00000010b ;/ R31 = d7 d6 d5 d4 d3 d2 d1 0 sbrc R30,0 ;\ ori R31,00000001b ;/ R31 = d7 d6 d5 d4 d3 d2 d1 d0 mov HOST_DATA1,R31 ;HOST_DATA1 = d7 d6 d5 d4 d3 d2 d1 d0 ;HOST_DATA2 = x x x x x x d9 d8 rjmp MLP_INEXIT_D MLP_IN_NOTDAT: cpi HOST_CMD,CMD_VCO1 breq MLP_IN_VCOx cpi HOST_CMD,CMD_VCO2 breq MLP_IN_VCOx cpi HOST_CMD,CMD_VCO3 brne MLP_IN_NOTVCO MLP_IN_VCOx: ;CMD_VCO1, CMD_VCO2, CMD_VCO3: ;HOST_DATA1 = d7 d6 d5 d4 d3 d2 d1 d0 ;HOST_DATA2 = x x x x x x d9 d8 ;R30 = x x x x x d12 d11 d10 ;R31 = 0 d19 d18 d17 d16 d15 d14 d13 lsl R30 lsl R30 ;R30 = x x x d12 d11 d10 0 0 andi HOST_DATA2,00000011b ;HOST_DATA2 = 0 0 0 0 0 0 d9 d8 or R30,HOST_DATA2 ;R30 = x x x d12 d11 d10 d9 d8 lsl R30 ;R30 = x x d12 d11 d10 d9 d8 0 lsl R30 ;R30 = x d12 d11 d10 d9 d8 0 0 lsl R30 ;R30 = d12 d11 d10 d9 d8 0 0 0 lsr R31 ;\ R30 = d13 d12 d11 d10 d9 d8 0 0 ror R30 ;/ R31 = 0 0 d19 d18 d17 d16 d15 d14 lsr R31 ;\ R30 = d14 d13 d12 d11 d10 d9 d8 0 ror R30 ;/ R31 = 0 0 0 d19 d18 d17 d16 d15 lsr R31 ;\ R30 = d15 d14 d13 d12 d11 d10 d9 d8 ror R30 ;/ R31 = 0 0 0 0 d19 d18 d17 d16 ;HOST_DATA1 = d7 d6 d5 d4 d3 d2 d1 d0 ;R30 = d15 d14 d13 d12 d11 d10 d9 d8 ;R31 = 0 0 0 0 d19 d18 d17 d16 cpi HOST_CMD,CMD_VCO1 brne MLP_IN_NOTV1 mov PHASEDELTA1_L,HOST_DATA1 mov PHASEDELTA1_M,R30 mov PHASEDELTA1_H,R31 rjmp MLP_INEXIT_D MLP_IN_NOTV1: cpi HOST_CMD,CMD_VCO2 brne MLP_IN_NOTV2 mov PHASEDELTA2_L,HOST_DATA1 mov PHASEDELTA2_M,R30 mov PHASEDELTA2_H,R31 rjmp MLP_INEXIT_D MLP_IN_NOTV2: mov PHASEDELTA3_L,HOST_DATA1 mov PHASEDELTA3_M,R30 mov PHASEDELTA3_H,R31 rjmp MLP_INEXIT_D MLP_IN_NOTVCO: cpi HOST_CMD,CMD_PWM1 brne MLP_IN_NOTPWM1 ;CMD_PWM1: ;R30 = x x x x x x x d0 ;R31 = 0 d7 d6 d5 d4 d3 d2 d1 lsr R30 ;\ rol R31 ;/ R31 = d7 d6 d5 d4 d3 d2 d1 d0 mov PWM1VALUE,R31 rjmp MLP_INEXIT_D MLP_IN_NOTPWM1: cpi HOST_CMD,CMD_PWM2 brne MLP_IN_NOTPWM2 ;CMD_PWM2: ;R30 = x x x x x x x d0 ;R31 = 0 d7 d6 d5 d4 d3 d2 d1 lsr R30 ;\ rol R31 ;/ R31 = d7 d6 d5 d4 d3 d2 d1 d0 mov PWM2VALUE,R31 rjmp MLP_INEXIT_D MLP_IN_NOTPWM2: cpi HOST_CMD,CMD_PWM3 brne MLP_IN_NOTPWM3 ;CMD_PWM3: ;R30 = x x x x x x x d0 ;R31 = 0 d7 d6 d5 d4 d3 d2 d1 lsr R30 ;\ rol R31 ;/ R31 = d7 d6 d5 d4 d3 d2 d1 d0 mov PWM3VALUE,R31 rjmp MLP_INEXIT_D MLP_IN_NOTPWM3: cpi HOST_CMD,CMD_VCF brne MLP_IN_NOTVCF ;CMD_VCF: ;R30 = x x x x x x x d0 ;R31 = dane = 0 d7 d6 d5 d4 d3 d2 d1: lsr R30 ;\ rol R31 ;/ R31 = d7 d6 d5 d4 d3 d2 d1 d0 out VCFVALUE,R31 rjmp MLP_INEXIT_D MLP_IN_NOTVCF: cpi HOST_CMD,CMD_VCA brne MLP_IN_NOTVCA ;CMD_VCA: ;R30 = x x x x x x x d0 ;R31 = dane = 0 d7 d6 d5 d4 d3 d2 d1: lsr R30 ;\ rol R31 ;/ R31 = d7 d6 d5 d4 d3 d2 d1 d0 out VCAVALUE,R31 rjmp MLP_INEXIT_D MLP_IN_NOTVCA: MLP_INEXIT_D: clr HOST_CMD MLP_INEXIT: ;wyslanie do DAC3..7: mov R31,DACCHAN mov DACCHAN,MUXDISABLE ;temporary disable DAC3..7 cpi R31,PD_CHAN7 breq MLP_CHANNEL3 cpi R31,PD_CHAN3 breq MLP_CHANNEL4 cpi R31,PD_CHAN4 breq MLP_CHANNEL5 cpi R31,PD_CHAN5 breq MLP_CHANNEL6 MLP_CHANNEL7: in DACDATA,VCAVALUE ldi DACCHAN,PD_CHAN7 ;channel 7 (VCA) rjmp MLP_CHEXIT MLP_CHANNEL6: in DACDATA,VCFVALUE ldi DACCHAN,PD_CHAN6 ;channel 6 (VCF) rjmp MLP_CHEXIT MLP_CHANNEL5: mov DACDATA,PWM3VALUE ldi DACCHAN,PD_CHAN5 ;channel 5 (PWM3) rjmp MLP_CHEXIT MLP_CHANNEL4: mov DACDATA,PWM2VALUE ldi DACCHAN,PD_CHAN4 ;channel 4 (PWM2) rjmp MLP_CHEXIT MLP_CHANNEL3: mov DACDATA,PWM1VALUE ldi DACCHAN,PD_CHAN3 ;channel 3 (PWM1) MLP_CHEXIT: ;czekaj az DAC3..7 zostanie zapisany: MLP_WAIT: in R31,PORTD cp R31,DACCHAN brne MLP_WAIT ;kontynuuj: rjmp MAINLOOP ;ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл END