;*************************************************************** ; ECE331 Lab 4 Starter Program (KEH, August 2004) ; BLINKY.ASM - Demonstrates simultaneous operation of a non-interrupt driven ; main program that flashes an LED (on PT7) on and off at an approximate 1-second rate ; and also a precisely timed 500 Hz square wave (on PT6) generating program using Timer Channel 6 ; as an output compare register. ; XDEF BLINKY ABSENTRY BLINKY INCLUDE 'mc9s12c32.inc' ORG $3800 storeLoc: DS.B 4 toneLoc: DS.B 4 ORG $4000 Combo: DC.B %00001111,%00001111,%00001111,%00001111 LUT: DC.B %00111111,%00000110,%01011011,%01001111,%01100110,%01101101,%01111101,%00000111,%01111111,%01100111 BLINKY: lds #$3f00 jsr PLL_init movb #%10101110,DDRT ;Make PT1,2,3,5,7 digital outputs. movb #%01111111,ATDDIEN ;Disable ATD conversion on PAD0-6 movb #%01110000,DDRAD ;Set PAD0-PAD3 as digital inputs and PAD7 as an analog input movb #%00000000,PERAD ;Disable internal pull-ups bset ATDCTL2,%10000000 ;Power up ATD Unit movb #%00001000,ATDCTL3 ;Select single conversion per sequence movb #%00000111,ATDCTL4 ;Select 10 bit conversion, 2-clock sample time, 1/16 prescale movb #%01111111,RTICTL ;Set interrupt period to be every 43.7 ms. movb #%00111000,DDRM ;Set PTM3-5 as outputs movb #$5C,SPICR1 ;Power up SPI interface, and set it up movb #$27,SPIBR ;Set up SPI baud rate bset CRGINT,%10000000 ;Initialize RTI interrupts movb #%00000000,PTM ; movb #5,TSCR2 ;Set prescaler bits to 5 so TCNT increments every ;32/24MHz = 1.333 microseconds. movb #$80,TSCR1 ;Enable Timer TCNT to begin counting movb #%01010001,TIE ;Locally Enable TC6 and TC4 interrupts movb #%01000000,TIOS ;Make TC6 an Output Compare register and TC4 and Input Compare register movb #$10,TCTL1 ;Make TC6 pin toggle when the scheduled output compare occurs movb #2,TCTL3 ;Enable falling edge sensitivity for PT4, PT0 movb #2,TCTL4 ; ldd TCNTHi ;Load TCNT into register D addd #750 ;Add 750 TCNT increments to it. ;Note 750*1.33us = 1 ms. std TC6Hi ;Schedule next output compare interrupt to occur in 1 ms movb #%01010001,TFLG1;Make sure TC6 and TC4 interrupt flags are cleared cli ;globally enable interrupts blinkagain: bclr PTT,%10000000 ;Turn off LED on PT7 bsr onesecdelay bset PTT,%10000000 ;Turn ON LED on PT7 bsr onesecdelay bra blinkagain ;*********Here ends the main program "BLINKY" onesecdelay: ;Software timing loop delay routine -- ;Delays approx 1 second,depending upon how pshx ;much time is taken away to process interrupts. pshy ldx #46 outerloop: ldy #$ffff innerloop: dey bne innerloop dex bne outerloop puly pulx rts TOC6ISR: ldd TCNTHi addd #750 ;Schedule another interrupt in 1 ms from now std TC6Hi movb #$40,TFLG1 ;Relax the TC6 interrupt flag rti TOC4ISR: movb #%00010000,TFLG1 ;Relax the TC4 interrupt flag ldx #storeLoc ldy #Combo movb 2,X,3,X ;Rotate stored data movb 1,X,2,X movb X,1,X ldaa PTAD ;Load newest value anda #%00001111 ;Mask out other bits staa X ;Store it to memory cmpa Y ;Compare list of values bne notCorrect ; ldaa 1,X ; cmpa 1,Y ; bne notCorrect ; ldaa 2,X ; cmpa 2,Y ; bne notCorrect ; ldaa 3,X ; cmpa 3,Y ; bne notCorrect ; ldaa PTT ;Turn on the LED if correct combo entered oraa #%00100000 ; staa PTT ; rti ; notCorrect: bclr PTT,%00100000 ;Shut off LED rti TOC0ISR: movb #%00000001,TFLG1 ;Relax the TC4 interrupt flag ldx #toneLoc ; movw X,2,X ;Rotate Data around ldd TC0Hi ;Read input capture reg and std X ;determine whether the frequency is alright subd 2,X ; cpd #1750 ; bhi tooLow ; cpd #1680 ; blo tooHigh ; bclr PTT,%00001110 ;Turn the freq good light on bset PTT,%00000100 rti tooHigh: bclr PTT,%00001110 ;Turn the freq too high light on bset PTT,%00001000 rti tooLow: bclr PTT,%00001110 ;Turn the freq too low light on bset PTT,%00000010 rti ATD: bset CRGFLG,%10000000 ;Relax interrupt flag movb #%10000111,ATDCTL5 ;Start ATD conversion process Wait: brclr ATDSTAT0,#%10000000,Wait ;Wait for the flag to be set ldd ATDDR0 ;Load converted data into accumulator A ldy #50 ;Convert to a value in the range of 0-50 emul ; addd #25 ; ldx #1024 ; idiv tfr x,d ldx #10 idiv tfr d,y ldaa LUT,y ldab LUT,x bclr PTM,%00001000 ;Lower PTM3 ;psha ;ldaa SPISR ;pula ldx SPISR ;Dummy read STAB SPIDR ;Write first byte Wait2: ldab SPISR andb #$20 beq Wait2 ;brclr SPISR,#%10000000,Wait2 ;Check to see if flag set ; not needed ldx SPIDR ;Dummy read STAA SPIDR ;Write second byte Wait3: ldab SPISR andb #$20 beq Wait3 ;brclr SPISR,#%10000000,Wait3 ;Check to see if flag set bset PTM,%00001000 ;Raise PTM3 rti ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;Subroutine Name: PLL_init ;;Purpose: Initialize clock generator and PLL to increase CPU clock speed by factor of 6 ;;Author: Dr. Hoover ;;Creation Date: Unknown ;;Revision Number: Unknown ;;Input Data Required: None. ;;Output Data: None ;;Registers Affected: None. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PLL_init:bclr CLKSEL,$80 ;Disconnect PLL from system if connected. bset PLLCTL,$40 ;Turn on the PLL hardware block. movb #2,SYNR ;Set PLL multiplier movb #1,REFDV ;Set PLL divider ;From Section 3.1.1 of CRG Block Guide ;PLLCLK = OSCCLK*(SYNR+!)/(REFDV+1) ; = 16 MHz * (2+1)/(1+1) = 24MHz nop ;NOP delays put here to allow time for nop ;CRGFLG flag register to become valid. wt_PLL_Lock: brclr CRGFLG, 8, wt_PLL_Lock ;Wait here for PLL to “Lock in” bset CLKSEL,$80 ;Connect PLL back into system. rts ;************************************************************** ;* Initialize Reset Vector and TC4 and TC6 Interrupt Vector * ;************************************************************** ORG $FFFE fdb BLINKY ;Make reset vector point to entry point of BLINKY program ORG $FFE2 fdb TOC6ISR ;Make TC6 interrupt vector point to TC6 interrupt rtn ORG $FFE6 fdb TOC4ISR ;Make TC4 interrupt vector point to TC4 interrupt rtn ORG $FFEE fdb TOC0ISR ;Make TC0 interrupt vector point to TC0 interrupt rtn ORG $FFF0 fdb ATD ;Make RTI interrupt vector point to ATD interrupt rtn