;***************************************************************** ;*LCD and I/O Board Test Program * ;*St.Denis, Aug. 2005 * ;*This program can test the LCD and speaker on * ;*the "HC12C32 to I/O" board used in the ELT2050 class * ;***************************************************************** ; export symbols XDEF Entry ; export 'Entry' symbol ABSENTRY Entry ; for absolute assembly: mark this as application entry point ; include derivative specific macros INCLUDE 'mc9s12c32.inc' ROMStart EQU $C000 ; absolute address to place code/constant data LED_RIGHT_Bit EQU %00000001 ;devices attached to bits on PortT LED_LEFT_Bit EQU %00000010 Beeper_Bit EQU %00000100 LCD_Bits EQU %11110000 ;these deal with the LCD routines E_Bit EQU %000100 ; possible future changes RW_Bit EQU %000010 RS_Bit EQU %000001 SevSegBits EQU %11110111 ;PT3 is not attached to 7 seg display SevSegLatchEn EQU %00100000 ;enable bits on PortM Right_Digit_Bit EQU %00010000 Left_Digit_Bit EQU %00001000 ; variable/data section ORG $3800 ;RAMStart Beeper_Ctrl: ds.w 1 ;a counting semaphore which is set by the ;main program for the # of beep cycles. ;the RTI_ISR geenrates the squareware at the speaker. FlashLED_Ctrl: ds.w 1 ;a counter used to control the Seven segment ;test routine flash rate FlashTimeConstant EQU 1000 ;this value is loaded into FlashLED_Ctrl SevSegPattern: ds.b 1 ;stores a bit pattern used to drive the seven ;segment LEDs. This pattern is inverted ;periodically. ; code section ORG ROMStart Entry: CLI ;enable interrupts for Serial monitor ;***************************************************** ;Start up code to set memory mapping to match serial ; monitor (RAM @ $3800-$3FFF, reg's @ $0000 ; (EEPROM not available on 'C32 series) MOVB #$00,INITRG ;set registers at $0000 MOVB #$39,INITRM ;set ram to end at $3fff ;MOVB #$09,INITEE ;set eeprom to end at $0fff ;***************************************************** ;Start up code to turn on PLL and set bus speed to ; 24Mhz (matching serial monitor mode) bclr CLKSEL,mCLKSEL_PLLSEL ;disengage PLL to system bset PLLCTL,mPLLCTL_PLLON ;turn on PLL movb #2,SYNR ;set PLL multiplier movb #0,REFDV ;set PLL divider nop nop brclr CRGFLG,mCRGFLG_LOCK,*+0 ;while PLL not locked bset CLKSEL,mCLKSEL_PLLSEL ;engage PLL to system ;***************************************************** ;If you are doing 'absolute assembly' and want system ; work in 'RUN' mode, you must load the stack pointer. ; This is generally not necessary when using C. LDS #$4000 ;or wherever the end of RAM is. ;***************************************************** ;Motorola (Freescale) recommends initiallizing all the ; unused ports. A good, safe strategy is to activate ; all the pull up resistors on all the ports. In this ; way all pins will be at a known state and aren't ; likely to oscillate. MOVB #$93,PUCR MOVB #$ff,PERT ;Enable pull devices in PortT MOVB #$00,PPST ;Select pull ups for Port T MOVB #$ff,PERP ;Enable pull devices in PortP MOVB #$00,PPSP ;Select pull ups for Port P MOVB #$00,PERM ;Disable pull devices in PortM MOVB #$00,PPSM ;Select pull ups for Port M MOVB #$0f,PERS ;Enable pull devices in PortS MOVB #$00,PPSS ;Select pull ups for Port S MOVB #$C0,PERJ ;Enable pull devices in PortJ MOVB #$00,PPSJ ;Select pull ups for Port J MOVB #$FF,PERAD ;Enable pull devices in PortAD MOVB #$00,PPSAD ;Select pull ups for Port AD BCLR PTT,7 ;set up LEDs and speaker on PortT BSET DDRT,7 BSET ATDDIEN,#$C0 MOVB #%00010011,RTICTL ;RTI interval =4*1024/8Mhz = 512microsec BSET CRGINT,mCRGINT_RTIE ;enable local interrupt MOVW #200,Beeper_Ctrl ;short beep MOVB #$80, ATDCTL2 ;turns on A/D convertor MOVB #$A0, ATDCTL5 ;continuous scanning, channel 0, right justified LDX #5000 ;set up the parameters for the flashing LEDs STX FlashLED_Ctrl LDAA #$FF STAA SevSegPattern ANDA #SevSegBits LDAB PTT ANDB #(SevSegBits ^$FF) ABA STAA PTT BSET PTM, SevSegLatchEn BCLR PTM, Right_Digit_Bit + Left_Digit_Bit BSET DDRM, SevSegLatchEn + Right_Digit_Bit + Left_Digit_Bit BCLR PTM, SevSegLatchEn JSR Init_LCD ;do this once, then use LCD_CMD or LCD_Out Main_Loop: LDAB #'A' Main_Loop_2: JSR LCD_Out INCB CMPB #'Z' BNE Main_Loop_2 Wait4Key: BRCLR PORTAD0,#%10000000, Sound BRCLR PORTAD0,#%01000000, Letters JSR FlashSevSegs JSR DELAY_1ms BRA Wait4Key Sound: MOVW #1000,Beeper_Ctrl BRA Wait4Key Letters: LDAB #'z' JSR LCD_Out JSR DELAY_10ms Letter_Loop: BRCLR PORTAD0,#%01000000, Letter_Loop JSR DELAY_10ms BRA Wait4Key ;************************************************************** ;* LCD I/O Routines * ;* St.Denis, Feb. 2005 * ;* * ;* These routines can be used to initialize, send commands, * ;* and send data (ASCII codes) to a standard HD44780 based * ;* LCD module. It is assumed that the 4 bit interface is * ;* used (upper data lines wired to PT7-PT4, E=PM2, RS=PM1, * ;* and R/W= PM0). * ;* * ;* Init_LCD -- Initializes using the standard sequence of * ;* commands to force the LCD into a known state, then * ;* commands it to use the 4 bit interface, use 2 lines, * ;* flashing cursor, and clears the display. * ;* LCD_CMD -- The byte in the B register is sent as a * ;* command (RS = low) to the LCD. The byte is broken * ;* into nibbles and each is sent separately by * ;* LCD_Upp_CMD. * ;* LCD_Out -- The byte(ASCII code)in B is sent to the LCD * ;* as data (RS = high) and causes a character to be * ;* displayed. The byte is broken into nibbles and each * ;* is sent separately by LCD_Upp_Data. * ;* * ;* These routines can form the lowest layer of a character I/O* ;* package. These could be improved by using the BUSY flag * ;* if desired. * ;************************************************************** LCD_Out: PSHB PSHB ;pass data (ASCII) in reg. B JSR LCD_Upp_Data PULB ;now deal with the lower nibble LSLB ;shift it into upper half LSLB LSLB LSLB JSR LCD_Upp_Data PULB RTS LCD_Upp_Data: PSHA ;this deals with the upper nibble of a character BCLR PTM, #RW_Bit ;it's data BSET PTM, #E_Bit+RS_Bit JSR DELAY_10us ;needs to be at least 1/2 uS SEI ANDB #LCD_Bits LDAA PTT ANDA #(LCD_Bits ^$FF) ;complement of the mask ABA STAA PTT CLI BCLR PTM,E_Bit JSR Delay_100us ;most take ~40uS PULA RTS LCD_CMD: PSHB PSHB JSR LCD_Upp_CMD PULB ;now deal with the lower nibble LSLB ;shift it into upper half LSLB LSLB LSLB JSR LCD_Upp_CMD PULB RTS LCD_Upp_CMD: PSHA ;this deals with the upper nibble of a command BCLR PTM, #RS_Bit+RW_Bit ;it's a command, not data BSET PTM, #E_Bit JSR DELAY_10us ;needs to be at least 1/2 uS SEI ANDB #LCD_Bits LDAA PTT ANDA #(LCD_Bits ^$FF) ;complement of the mask ABA STAA PTT CLI BCLR PTM,E_Bit JSR Delay_100us ;most take ~40uS PULA RTS Init_LCD: BCLR PTT, #LCD_Bits ;activate the lines to the LCD BSET DDRT, #LCD_Bits ;only using 4 bit interface BCLR PTM, RS_Bit + RW_Bit BSET PTM, E_Bit BSET DDRM, E_Bit + RS_Bit + RW_Bit JSR Delay_10ms ;needed for power on delay JSR Delay_10ms LDAB #$30 ;send 3 times JSR LCD_Upp_CMD ;controller thinks its in 8 bit mode ; only send upper half of control bytes JSR Delay_10ms ;needs to be at least 4.1 msec LDAB #$30 JSR LCD_Upp_CMD JSR Delay_10ms LDAB #$30 JSR LCD_Upp_CMD JSR Delay_10ms LDAB #$20 JSR LCD_Upp_CMD JSR Delay_10ms LDAB #$28 ;finally in 4 bit mode, send bytes in halves JSR LCD_CMD ;this sets 2 line display, 5x8 matrix LDAB #$06 ;Entry mode: increment cursor position counter, shift off JSR LCD_CMD LDAB #$0F ;turn display back on, cursor on & blinking JSR LCD_CMD LDAB #$01 ;Clear screen JSR LCD_CMD JSR Delay_10ms ;needs at least 2 msec extra RTS ;************************************************************** ;* Software Delay Routines * ;************************************************************** DELAY_10us: PSHA LDAA #$20 ; load accumulator with 10 uS delay?? D10US_LOOP: DECA ; BNE D10US_LOOP ; PULA RTS DELAY_100us: Delay_100us: PSHA LDAA #$C8 ; load accumulator with 100 uS delay?? D100US_LOOP: DECA ; BNE D100US_LOOP ; PULA RTS DELAY_1ms: Delay_1ms: PSHB LDAB #10 D1ms_Loop: JSR DELAY_100us DECB BNE D1ms_Loop PULB RTS DELAY_10ms: Delay_10ms: PSHD LDD #10 JSR Delay_Dms PULD RTS DELAY_DMS: DELAY_Dms: Delay_Dms: PSHD DDms_Loop: JSR DELAY_1ms SUBD #1 BNE DDms_Loop PULD RTS ;************************************************************** ;* Seven Segment LED Display Test Routine * ;************************************************************** FlashSevSegs: LDX FlashLED_Ctrl ;decrement a timer to zero & BEQ TogglePattern ;switch the pattern displayed DEX STX FlashLED_Ctrl Jmp F7S_Done TogglePattern: LDX ATDDR0 ;LDX #FlashTimeConstant STX FlashLED_Ctrl LDAA SevSegPattern COMA STAA SevSegPattern ANDA #SevSegBits ;this sequence attempts to LDAB PTT ;protect PT3 from changing ANDB #(SevSegBits ^$FF) ABA STAA PTT BSET PTM,%00111000 ;enable '573 latch BCLR PTM,%00100000 ;store at '573 latch and turn ;on both digit drivers. F7S_Done: RTS ;************************************************************** ;* Interrupt Service Routines * ;************************************************************** RTI_ISR: LDX Beeper_Ctrl BEQ RTI_ISR_Done DEX STX Beeper_Ctrl LDAA PTT ;toggle the speaker EORA #Beeper_Bit STAA PTT RTI_ISR_Done: LDAA CRGFLG ;reset the RTI flag ANDA #mCRGFLG_RTIF STAA CRGFLG RTI ;************************************************************** ;* Interrupt Vectors * ;************************************************************** ORG $FFF0 ;a few common vectors dc.w RTI_ISR ; dc.w IRQ_ISR ; dc.w XIRQ_ISR ; dc.w SWI_ISR ORG $FFFE fdb Entry ; Reset