#include  <msp430x42x0.h>      
;------------------------------------------------------------------------------
            ORG     0A000h                  ; program start for MSP430F4260
;------------------------------------------------------------------------------
RESET       mov.w   #300h, SP               ; initialize stack pointer
            mov.w   #WDTPW+WDTHOLD, &WDTCTL ; stop WDT
            bis.b   #XCAP14PF, &FLL_CTL0    ; set load capacitance for xtal
            mov.b   #LCDON + LCDSTATIC + LCDFREQ_128, &LCDACTL ; static, ACLK/128
            mov.b   #0x0F, &LCDAPCTL0       ; configure s0-s13 for LCD
 
            clr.b   &P6OUT                  ; configure all ports for output
            mov.b   #0xFF, &P6DIR
            clr.b   &P5OUT
            mov.b   #0x1C, &P5DIR
            mov.b   #0x10, &P1OUT           ; preset CS=0 and CLK=1
            mov.b   #0xBF, &P1DIR           ; enable input at P1:6
 
            mov.b   #7, R15                 ; 7 LCD memory bytes to clear
            clr.b   LCDMEM-1(R15)           ; clear display
            dec.b   R15      
            jnz     $ - 6              

            mov.b   #0x27, &BTCTL           ; basic timer1 setup ACLK/2^(16)
            clr.b   &BTCNT1                 ; clear counters
            clr.b   &BTCNT2
            bis.b   #BTIE, &IE2             ; enable timer interrupt

            clr.w   R6                      ; old temperature
loop        bis.b   #BIT5, &P1OUT           ; set CS=1 to start conversion

            mov.b   #0x24, &BTCTL           ; sleep for 0.256 sec to complete
            bis.w   #LPM3 | GIE, SR         ; temp. conversion
            mov.b   #0x27, &BTCTL           ; set next timer event in 2sec

            bic.b   #BIT5, &P1OUT           ; set CS=0 and terminate conversion
            bic.b   #BIT4, &P1OUT           ; set CLK=0 and prepare for output

            clr.w   R5
            mov.b   #10, R15                ; setup input bits counter
get_bit     bis.b   #BIT4, &P1OUT           ; CLK = 1
            bit.b   #BIT6, &P1IN            ; C = input bit
            rlc     R5                      ; rotate it into R5
            bic.b   #BIT4, &P1OUT           ; CLK = 0
            dec.b   R15
            jnz     get_bit

            bis.b   #BIT4, &P1OUT           ; set CLK = 1

            bit.w   #BIT9, R5               ; temp < 0 ?
            jz      add1                    ; NO - treate is as positive
            bis.w   #0xFC00, R5             ; sign extend negative temp
            dec.w   R5                      ; rounding off negative temp
            jmp     $+4
add1        inc.w   R5                      ; rounding off non-negative temp
            rra.w   R5                      ; compute integer part in R5
            
            cmp.w   R5, R6                  ; do not process temp if it is
            jeq     sleep                   ; the same as earlier            
            mov.w   R5, R6                   ; update old temp value

            call    #bin2BCD8               ; compute BCD in R4
            call    #display                ; display temp

sleep       bis.w   #LPM3 | GIE, SR         ; enter the LPM3 mode (sleep)
            jmp     loop

            
;;;;;;;;;;;;;;;;;;;;;;;;;PROCEDURES::::::::::::::::::::
bt1_ISR     bic.w   #LPM3, 0(SP)            ; return from sleep (ISR)
            reti

bin2BCD8    mov.w   R5, R15                 ; copy input number
            bit.w   #BITF, R15         
            jz      check_up
            inv.w   R15                     ; negate number if it is negative
            inc.w   R15
            cmp.w   #9, R15                 ; display "-_" if the temp below
            jl      check_up                ; -9C
            mov.b   #0xBB, R4
            ret
            
check_up    cmp     #100, R15               ; exit if the number exceeds 99
            jl      process
            mov.b   #0xAA, R4
            ret

process     clr.w   R4                      ; prepare the result
            mov.b   #8, R14                 ; loop cnt = # of bits

b2b_loop    rla.b   R15                     ; use the decimal addition
            dadd.b  R4, R4                  ; operation to convert the byte
            dec.b   R14                     ; into BCD
            jnz     b2b_loop                ; we assume byte value <= 99
            bit.w   #BITF, R5
            jz      $ + 6
            bis     #0xB0, R4               ; add the minus sign
            ret

display     mov.b   R4, R14                 ; display a value in R4 on LCD
            mov.b   R4, R15
            and.b   #0x0F, R14              ; extract right digit in R14
            rla.b   R14
            rla.b   R14                     
            add.w   #right_digit, R14       ; R14 = address in right table
            clrc
            rrc.b   R15
            rra.b   R15                     
            and.b   #0xFC, R15
            add.w   #left_digit, R15        ; R15 = address in left table
 
            mov.b   @R15+, &LCDM2           ; write table data to LCD
            mov.b   @R15+, &LCDM3
            mov.b   @R15+, &LCDM4
            mov.b   @R15,  &LCDM5
            mov.b   @R14+, &LCDM1
            add.b   @R14+, &LCDM2
            mov.b   @R14+, &LCDM6
            mov.b   @R14,  &LCDM7
            ret

right_digit DW      0x0111                  ; digit 0 (LCDM1 part)
            DW      0x1110                  ; digit 0 (LCDM6 part)
            DW      0x0100                  ; digit 1 (LCDM1 part)
            DW      0x0010                  ; digit 1 (LCDM6 part)
            DW      0x0011                  ; digit 2 (LCDM1 part)
            DW      0x0111                  ; digit 2 (LCDM6 part)
            DW      0x0110                  ; digit 3 (LCDM1 part)
            DW      0x0111                  ; digit 3 (LCDM6 part)
            DW      0x0100                  ; digit 4 (LCDM1 part)
            DW      0x1011                  ; digit 4 (LCDM6 part)
            DW      0x0110                  ; digit 5 (LCDM1 part)
            DW      0x1101                  ; digit 5 (LCDM6 part)
            DW      0x0111                  ; digit 6 (LCDM1 part)
            DW      0x1101                  ; digit 6 (LCDM6 part)
            DW      0x0100                  ; digit 7 (LCDM1 part)
            DW      0x0110                  ; digit 7 (LCDM6 part)
            DW      0x0111                  ; digit 8 (LCDM1 part)
            DW      0x1111                  ; digit 8 (LCDM6 part)
            DW      0x0110                  ; digit 9 (LCDM1 part)
            DW      0x1111                  ; digit 9 (LCDM6 part)
            DW      0                       ; the overline symbol
            DW      0x0100                  
            DW      0x0010                  ; the underline symbol
            DW      0
            
left_digit  ;DW      0x1110                  ; digit 0 (LCDM2 part)
            ;DW      0x1110                  ; digit 0 (LCDM4 part)
            DW      0                       ; do not display leading 0
            DW      0
            DW      0x0010                  ; digit 1 (LCDM2 part)
            DW      0x1000                  ; digit 1 (LCDM4 part)
            DW      0x1100                  ; digit 2 (LCDM2 part)
            DW      0x1101                  ; digit 2 (LCDM4 part)
            DW      0x0110                  ; digit 3 (LCDM2 part)
            DW      0x1101                  ; digit 3 (LCDM4 part)
            DW      0x0010                  ; digit 4 (LCDM2 part)
            DW      0x1011                  ; digit 4 (LCDM4 part)
            DW      0x0110                  ; digit 5 (LCDM2 part)
            DW      0x0111                  ; digit 5 (LCDM4 part)
            DW      0x1110                  ; digit 6 (LCDM2 part)
            DW      0x0111                  ; digit 6 (LCDM4 part)
            DW      0x0010                  ; digit 7 (LCDM2 part)
            DW      0x1100                  ; digit 7 (LCDM4 part)
            DW      0x1110                  ; digit 8 (LCDM2 part)
            DW      0x1111                  ; digit 8 (LCDM4 part)
            DW      0x0110                  ; digit 9 (LCDM2 part)
            DW      0x1111                  ; digit 9 (LCDM4 part)
            DW      0                       ; the overline symbol
            DW      0x0100                  
            DW      0                       ; the - symbol
            DW      0x0001
            
;------------------------------------------------------------------------------
;           Interrupt Vectors
;------------------------------------------------------------------------------
            ORG     0x0FFE0                 ; basic timer 1 vector
            DW      bt1_ISR

            ORG     0x0FFFE                 ; RESET Vector
            DW      RESET                   ;
            END