#include    "msp430x44x.h" ;  MSP430x44x Standard Definitions
;*******************************************************************************
;  MSP-FET430P440 Demo - LCD, displays numbers on static LCD
;
;  Description "FET440_staticLCD": This program displays a 3.5 digit number
;  stored in register R14 on a static LCD, then waits in low power mode 3. The
;  leading digit must be '1', nothing else will display.  To use the program
;  enter a 4 digit BCD (characters 0-9) number in R14 and press enter.  Reset 
;  and run the program.  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 values in the LCD memory locations as the 
;  software is executed.
;
;  NOTE: The code is written such that single digits can be passed to the 
;        display routine.  The routine to shift bytes, that is currently in the
;        mainloop, could be moved to the display routine if the passing of 
;        multiple digits is preferred
;  
;  
;                                 Connections MSP430 -> LCD
;                                 -------------------------
;
;                                T.I.               Varitronix  
;                           MSP430x4xx MCU     3.5 digit, static LCD
;                                                 # VI-302-DP-S
;                           ---------------       --------------
;                          |          COM0 |-----|1,40 COM      |
;                          |          SEG0 |-----|21            |
;                          |          SEG1 |-----|20            |
;                          |          SEG2 |-----|19            |
;                          |          SEG3 |-----|18            |  
;                          |          SEG4 |-----|17            |
;                          |          SEG5 |-----|22            |
;                          |          SEG6 |-----|23            |
;                          |          SEG7 |-----|38 (low batt) |
;                          |          SEG8 |-----|25            | 
;                          |          SEG9 |-----|24            |
;                          |          SEG10|-----|15            |
;                          |          SEG11|-----|14            |
;                          |          SEG12|-----|13            | 
;                          |          SEG13|-----|26            |
;                          |          SEG14|-----|27            |
;                          |          SEG15|-----|28 (L)  COLON |
;                          |          SEG16|-----|30            | 
;                          |          SEG17|-----|29            |
;                          |          SEG18|-----|11            |
;                          |          SEG19|-----|10            |
;                       ---|R03       SEG20|-----|9             | 
;                      |   |          SEG21|-----|31            |
;                      |   |          SEG22|-----|32            |
;                     \|/  |          SEG23|-----|3 (B-C) =     |
;                     GND  |               |     | .5 digit ="1"|
;                           ---------------       --------------  
;
;                 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      mov.b  R14,R13                   ;copy R14 to R13, so R14 saved
              call   #ToLCD                    ;call to display 1st digit
              mov.b  R14,R13                   ;recopy R14 to R13, so R14 saved
              rra.b  R13                       ;right shift R13 4 times to 
              rra.b  R13                       ;move 2nd nibble to lower 4 bits
              rra.b  R13                       ;
              rra.b  R13                       ;
              call   #ToLCD                    ;call to display 2nd digit
              swpb   R14                       ;swap bytes in R14    
              mov.b  R14,R13                   ;copy R14 to R13, so R14 saved
              call   #ToLCD                    ;call to display 3rd digit
              mov.b  R14,R13                   ;recopy R14 to R13
              rra.b  R13                       ;right shift R13 4 times to 
              rra.b  R13                       ;move 2nd nibble to lower 4 bits
              rra.b  R13                       ;
              rra.b  R13                       ;
              call   #ToLCD                    ;call to display 4th digit if = 1
              bis    #LPM3,SR                  ;Set SR bits to wait in LPM3

;-------------------------------------------------------------------------------
;             Display 1 digit on static LCD. CPU Registers R15, R14 and R13
;             used temporarily
;-------------------------------------------------------------------------------
ToLCD         cmp    #09Dh,R15                 ;pointer incremented for 4th
                                               ;digit = 1/2 digit position?
              jeq    Halfdigit                 ;yes, jump to test/set leading 1       
              and    #000Fh,R13                ;blank upper 12 bits
              add    R13,R13                   ;double R13 since is word data
                                               ;where addresses = 2 bytes apart 
              add    R13,R13                   ;double R13 again since 2 words
                                               ;per digit in static mode
ContinueLCD   mov    LCD_Tab(R13),LCDTEMP      ;low word into temp memory
              mov.b  LCDTEMP,0(R15)            ;low byte of low word to LCD
              swpb   LCDTEMP                   ;swap bytes in temp memory
              bis.b  LCDTEMP,1(R15)            ;high byte of low word to LCD
              incd   R13                       ;double increment to high word of
                                               ;digit
              mov    LCD_Tab(R13),LCDTEMP      ;high word into temp memory                                    
              mov.b  LCDTEMP,2(R15)            ;low byte of high word to LCD
              swpb   LCDTEMP                   ;swap bytes in temp memory
              bis.b  LCDTEMP,3(R15)            ;high byte of high word to LCD
              add    #4,R15                    ;increase R15 (LCD mem pointer) 
                                               ;by 4 since 4 bytes per digit
EndLCD        ret                              ;return from call

;-------------------------------------------------------------------------------
;             Test if 1 is to be displayed in 1/2 digit position and display it
;             If leading zero then nothing is displayed
;-------------------------------------------------------------------------------
Halfdigit     cmp.b  #1,R13                    ;digit to display = 1?
              jne    EndHalf                   ;no, jump to not display digit
              bis.b  #10h,-1(R15)              ;yes, set h bit in 12th byte(0-11)
                                               ; = 1/2 digit (leading 1) bit
EndHalf       mov.b  #LCDM1,R15                ;set pointer to start of LCD mem.
              jmp    EndLCD                    ;return from routine

;-------------------------------------------------------------------------------
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  #065h,&LCDCTL             ;static LCD, segments = 0 - 23
SetupBT       mov.b  #00h+BTFRFQ1+BTFRFQ0,&BTCTL ;set fLCD = ACLK / 256
SetupPorts    mov.b  #0FFh,&P1DIR              ;set port to outputs
SetupPx       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,&P5DIR              ;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 VI-302 3.5 digit static LCD
;-------------------------------------------------------------------------------
a             equ    0001h
b             equ    0010h
c             equ    0100h
d             equ    1000h
e             equ    0001h
f             equ    0010h 
g             equ    0100h                     
h             equ    1000h                     ;decimal point or special
                                               ;character

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

;-------------------------------------------------------------------------------
;             4xx Interrupt vectors
;-------------------------------------------------------------------------------
              ORG    0FFFEh                    ;MSP430 RESET Vector
              DW     RESET                     
              END     

