#include    "msp430x41x.h" ;  MSP430x41x Standard Definitions
;*******************************************************************************
;  MSP-FET430P410 Demo - LCD, displays numbers on 3 multiplex rate LCD
;
;  Description "FET410_3muxLCD": This program displays a 4 digit BCD value 
;  stored in register R14 on a 3 mux rate LCD then waits in low power mode 3.  
;  To use the program enter a 4 digit BCD (characters 0-9) number in R14 and 
;  press enter.  Reset the program then press run.  The value in R14 will be 
;  displayed on the LCD.  If the user does not have the LCD connected the 
;  functioning of the software can still be followed by single stepping and 
;  watching the register values, the LCDTEMP value in RAM, and the LCD memory
;  locations change as the software is executed.
;   ACLK = LFXT1 = 32768, MCLK = SMCLK = TACLK = DCO = 32xACLK = 1.048576MHz 
;   //*An external watch crystal is required on XIN/XOUT for ACLK*//	  
;  
;                                 Connections MSP430 -> LCD
;                                 -------------------------
;
;                                T.I.               Varitronix         
;                           MSP430x41x MCU     4.5 digit, 3 mux LCD
;                                              # VIM-503-DP-FC-S-LV
;                           ---------------       --------------
;                          |          COM2 |-----|15 COM3       |
;                          |          COM1 |-----|14 COM2       | 
;                          |          COM0 |-----|13 COM1       |
;                          |          SEG0 |-----|10            |
;                          |          SEG1 |-----|12            |
;                          |          SEG2 |-----|11            |
;                          |          SEG3 |-----|7             |  
;                          |          SEG4 |-----|9             |
;                          |          SEG5 |-----|8             |
;                          |          SEG6 |-----|4             |
;                          |          SEG7 |-----|6             |
;                          |          SEG8 |-----|5             | 
;                          |          SEG9 |-----|1             |
;                          |          SEG10|-----|3             |
;               	   |          SEG11|-----|2             |
;                	   |               |      --------------
;                	   |               | 
;                           ---------------  
;
;                   NOTE: Pin R03 on the MSP430 must be connected to GND
;
; B. Merritt
; Texas Instruments Inc.
; January 2002
;
;--------CPU register used------------------------------------------------------
;;;;;;;       R13, R14, R15                    ;used as temporary registers, can
                                               ;be reused 

;--------RAM words used for variables-------------------------------------------
LCDTEMP       equ    0200h                     ;temporary storage in LCD routine

;-------------------------------------------------------------------------------
              ORG    0E000h                    ;program reset
;-------------------------------------------------------------------------------
RESET         mov    #300h,SP                  ;itialize stackpointer          
              call   #Setup                    ;configure MSP430 for application

Mainloop      call   #OutLCD                   ;call routine to display lower 
                                               ;2 BCD digits entered into R14
              swpb   R14                       ;swap bytes in R14 
              call   #OutLCD                   ;call routine to display upper
                                               ;2 BCD digits just moved to lower
                                               ;byte of R14
              bis    #LPM3,SR                  ;Set SR bits to wait in LPM3

;-------------------------------------------------------------------------------
;             Display 2 digits on 3 mux rate LCD. CPU Registers R15, R14 and R13
;             used temporarily
;-------------------------------------------------------------------------------
OutLCD        mov    R14,R13                   ;copy R14 to R13, so R14 saved
              and    #000Fh,R13                ;blank upper 12 bits, only low 
                                               ;nibble now in R13
              add    R13,R13                   ;double R13 since is word data
			                       ;where addresses = 2 bytes apart 
              mov    LCD_Tab(R13),LCDTEMP      ;16 bit segment info into temp                                    
                                               ;LCDTEMP = 0000 0bch 0agd 0yfe
              mov.b  LCDTEMP,0(R15)            ;segments 'dga_ef' of low digit
                                               ;to LCD memory
              swpb   LCDTEMP                   ;swap bytes in temp
              bis.b  LCDTEMP,1(R15)            ;segments 'bch' of low digit
                                               ;to LCD memory
              
              mov.b  R14,R13                   ;copy lower byte of BCD value in
                                               ;R14 to R13
              rra.b  R13                       ;right shift R13 4 times to 
              rra.b  R13                       ;move high nibble to lower 4 bits
              rra.b  R13                       ;
              rra.b  R13                       ;
              and    #000Fh,R13                ;blank upper 4 bits, only 
                                               ;high nibble of BCD now in R13
              add    R13,R13                   ;double R13 since is word data
                                               ;where addresses = 2 bytes apart
              mov    LCD_Tab(R13),LCDTEMP      ;16bit segment info into temp
                                               ;LCDTEMP = 0000 0bch 0agd 0yfe
              rla    LCDTEMP                   ;LCDTEMP = 0000 bch0 agd0 yfe0
              rla    LCDTEMP                   ;LCDTEMP = 000b ch0a gd0y fe00
              rla    LCDTEMP                   ;LCDTEMP = 00bc h0ag d0yf e000
              rla    LCDTEMP                   ;LCDTEMP = 0bch 0agd 0yfe 0000
              bis.b  LCDTEMP,1(R15)            ;segments 'yfe' of high digit
              swpb   LCDTEMP                   ;LCDTEMP = 0yfe 0000 0bch 0agd 
              mov.b  LCDTEMP,2(R15)            ;segments 'bchagd' of high digit
              add    #3,R15                    ;increase R15 (LCD mem pointer) 
                                               ;by 3 since 1.5 bytes per digit
              ret

;-------------------------------------------------------------------------------
Setup         ;Configure modules and control registers 
;-------------------------------------------------------------------------------
StopWDT       mov    #WDTPW+WDTHOLD,&WDTCTL    ;stop Watchdog Timer
SetupFLL2     bis.b  #XCAP18PF,&FLL_CTL0       ;set load capacitance for xtal
              mov    #10000,R15
FLL_Wait      dec    R15                       ;delay for FLL to lock
              jnz    FLL_Wait		 
SetupLCD      mov.b  #035h,&LCDCTL             ;3mux LCD, segs 16-23 = outputs
              bis.b  #0FCh,&P5SEL              ;set Rxx and COM pins for LCD
SetupBT       mov.b  #00h+BTFRFQ1,&BTCTL       ;set fLCD = ACLK / 128
SetupPorts    mov.b  #0FFh,&P1DIR              ;set port to outputs
              mov.b  #0FFh,&P2DIR              ;set port to outputs
              mov.b  #0FFh,&P3DIR              ;set port to outputs
              mov.b  #0FFh,&P4DIR              ;set port to outputs
              mov.b  #0FFh,&P6DIR              ;set port to outputs

ClearLCD      mov    #15,R15                   ;15 LCD memory bytes to clear
Clear1        mov.b  #0,LCDM1(R15)             ;write zeros in LCD RAM locations
                                               ;so clear display
              dec    R15                       ;all LCD mem clear?
              jc     Clear1                    ;more LCD mem to clear, use JC
                                               ;to get memory location 0
              mov.b  #LCDM1,R15;               ;R15 points to first LCD location
              ret
              		 
;-------------------------------------------------------------------------------
;             Define characters for VIM-503 4.5 digit 3 mux LCD
;-------------------------------------------------------------------------------
f             equ    0001h
e             equ    0002h
h             equ    0004h
a             equ    0010h
g             equ    0020h
d             equ    0040h 
b             equ    0100h                     
c             equ    0200h
y             equ    0400h

              EVEN                             ;align words on even boundry
LCD_Tab       DW     a+b+c+d+e+f               ;displays "0"
              DW     b+c                       ;displays "1"
              DW     a+b+d+e+g	               ;displays "2"
              DW     a+b+c+d+g                 ;displays "3"
              DW     b+c+f+g                   ;displays "4"
              DW     a+c+d+f+g                 ;displays "5"
              DW     a+c+d+e+f+g               ;displays "6"
              DW     a+b+c                     ;displays "7"
              DW     a+b+c+d+e+f+g             ;displays "8"
              DW     a+b+c+d+f+g               ;displays "9"
              DW     g                         ;displays "-"

;-------------------------------------------------------------------------------
;             41x Interrupt vectors
;-------------------------------------------------------------------------------
              ORG    0FFFEh                    ;MSP430 RESET Vector
              DW     RESET                     
              END     



