; communication with temp sensor by using DMA

#include "msp430.h"                     ; the actual CPU model is set in
                                        ; the project options in IAR
pressTsch       EQU   0x3F+1            ; threscholds for button press and
releaseTsch     EQU   0xC0              ;  release (for the shift register)
CD      EQU     BIT0                    ; LCD interface on Port J: comm/data
RST     EQU     BIT1                    ; LCD reset
CS      EQU     BIT2                    ; LCD enable

Power   EQU     BIT0                    ; DC/DC enable output pin
Period  EQU     BIT0                    ; event bits and
Up      EQU     BIT1                    ;  buttons interface at Port 1
Mode    EQU     BIT2                    
Down    EQU     BIT3 
Switch  EQU     BIT4
Pause   EQU     BIT5
Record  EQU     BIT7
OnOff   EQU     BIT2                    ; On/Off button at Port 2.2

        RSEG    CSTACK                  ; pre-declaration of segment
        RSEG    DATA16_N                ; data segment
digits: DS      8                       ; pointers to 4 digit bitmaps        
i2cb:   DS      3                       ; I2C data buffer
cnt:    DS      1                       ; I2C sent bytes counter
width:  DS      2                       ; bitmap width
height: DS      1                       ; bitmap height
x:      DS      1                       ; screen coordinates (0 - 101)
y:      DS      1                       ; screen row number (0 - 7, 7=top)
zero:   DS      1                       ; display filling pattern (0)
recCnt: DS      2                       ; counter of records
step:   DS      2                       ; temp reading step 1/10/100/1000
state:  DS      1                       ; 0: measure temp, 1: record, 2: UART
switch: DS      1                       ; switch position
ta_p:   DS      2                       ; Timer_A period for 0.5 sec wakeup
ta_d:   DS      2                       ; Timer_A0 period for buttons debouncing
font:   DS      2                       ; pointer to display font
btState:DS      1                       ; buttons state reg: 1=up, 0=down
shiftM: DS      1                       ; shift registers for buttons debouncing
shiftD: DS      1
shiftU: DS      1
event:  DS      1                       ; event bits: Power, <, >, Mode, Switch
period: DS      1                       ; update period (1 sec, 15 sec, 60 sec)
periCnt:DS      1                       ; period counter
status: DS      1                       ; pause/recording
algn:   DS      1                       ; digits alignment: 0=right, 1=left

        RSEG    CODE                    ; code segment
reset:  mov     #SFE(CSTACK), SP        ; set up stack
        mov.w   #WDTPW+WDTHOLD, &WDTCTL ; stop watchdog timer
        bis.b   #REFTCOFF, &REFCTL0_L   ; disable temp sensor

        ; I/O ports setup
        mov.b   #0xCF, &P1OUT           ; init port  
        mov.b   #0xCE, &P1REN           ; enable pull-up resistors
        mov.b   #0x21, &P1DIR           ; output pins on P1
        mov.b   #BIT4, &P1SEL0          ; analog input A4 on P1.4          
        mov.b   #BIT6+BIT7+BIT4, &P1SEL1; activate special functions
        mov.b   #Up+Mode+Down, &P1IES   ; interrupt on high-to-low transition
        mov.b   #Up+Mode+Down, &P1IE    ; enable P1 button interrupts

        mov.b   #BIT2+BIT1, &P2OUT
        mov.b   #BIT2+BIT1, &P2REN      ; enable pull-up resistors at
        mov.b   #BIT0, &P2DIR           ; MISO/RX and On/Off pins
        bis.b   #OnOff, &P2IES          ; interrupt on high-to-low transition
        mov.b   #OnOff, &P2IE           ; enable On/Off button P2 interrupt

        mov.w   #0x0F, &PJDIR
        mov.w   #CS, &PJOUT
        bis.w   #BIT5+BIT4, &PJSEL0     ; enable Xtal oscillator pins
        clr.b   &P1IFG                  ; clear P1 interrupt flags
        clr.b   &P2IFG                  ; clear P2 interrupt flags
        
        ; clock setup
        mov.w   #16384, &ta_p           ; Timer_A0 period for mode 1
        mov.w   #327, &ta_d             ; 10 msec debouncing period        
        mov.b   #0xA5, &CSCTL0_H        ; unlock the clock interface 
        mov.b   #XT1DRIVE_1, &CSCTL4_L  ; crystal drive level
        clr.w   R5                     
wco1:   bic.b   #XT1OFFG, &CSCTL5_L     ; clear XT1 fault flag
        bic.b   #OFIFG, &SFRIFG1_L              
        bit.b   #OFIFG, &SFRIFG1_L	; test oscillator fault flag
        jz	wco2                    ; wait for crystal osc. to start
        inc.w   R5                      ; wait for at most 1 second for the
        jnz     wco1                    ; oscillator to start 
        mov.w   #4096, &ta_p            ; Timer_A0 period for 0.5 sec
        mov.w   #82, &ta_d              ; redefine debouncing period 10 msec
wco2:   clr.w   &CSCTL3                 ; set 8 MHz MCLK, SMCLK

        ; DMA_0 setup for LCD interface
        mov.w   #DMA0TSEL_15+DMA1TSEL_15, &DMACTL0  ; triggers for DMA_0,1                 
        mov.w   #UCA0TXBUF, &DMA0DAL    ; DMA_0 destination address        
        ; DMA_1 setup for UART write operation
        mov.w   #DMASRCINCR_3+DMASRCBYTE, &DMA1CTL
        mov.w   #i2cb, &DMA1SAL         ; DMA_1 source address
        mov.w   #UCA0TXBUF, &DMA1DAL    ; DMA_1 destination address
        mov.w   #5, &DMA1SZ             ; amount to transfer
        ; DMA_2 setup for I2C read operation
        mov.w   #DMA0TSEL_18, &DMACTL1  ; triggers for DMA_2
        mov.w   #DMADSTINCR_3+DMADSTBYTE, &DMA2CTL
        mov.w   #UCB0RXBUF, &DMA2SAL    ; DMA_2 source address
        mov.w   #i2cb, &DMA2DAL         ; DMA_2 destination address
        mov.w   #3, &DMA2SZ             ; amount to transfer

        ; SPI setup for eUSCI_A        
        bis.b   #UCSWRST, &UCA0CTL1     ; keep SPI module in reset  
        bis.w   #UCCKPL+UCMSB+UCMST+UCSYNC+UCSSEL_2, &UCA0CTLW0
        mov.b   #1, &UCA0BR0            ; clock division factor (1:1)
        call    #Init_LCD               ; init LCD driver

        ; UART setup for eUSCI_A
        mov.w   #0x4911, &UCA0MCTLW     ; setup for 9600 bod
        bis.w   #UCTXCPTIE, UCA0IE      ; enable transmit complete interrupt
        bit.b   #Mode, P1IN             ; UART transmission request ?
        jnz     $+6                     ; NO  - jump over the next instruction
        call    #Send_UART              ; YES - send recorded data via UART

        ; I2C setup for eUSCI_B
        bis.b   #UCSWRST, &UCB0CTL1     ; keep I2C module in reset
        bis.w   #UCMODE_3+UCMST+UCSYNC, &UCB0CTLW0 ; I2C master mode
        mov.w   #UCASTP_2, &UCB0CTLW1   ; automatic stop generation        
        mov.w   #128, &UCB0BRW          ; baudrate = 8MHz / 128
        mov.w   #0x5A, &UCB0I2CSA       ; slave address

        ; ADC setup
        bis.w   #ADC10ON, &ADC10CTL0    ; ADC on, 4 cycles for sampling
        bis.w   #ADC10SHP+ADC10DIV_1+ADC10SSEL_3, &ADC10CTL1  ; SMCLK/2     
        bis.w   #ADC10RES+ADC10SR, &ADC10CTL2   ; 10-bit binary unsigned
        bis.w   #ADC10INCH_4, &ADC10MCTL0  ; select channel A4, AVCC, AVSS
        mov.w   #ADC10HIIE+ADC10LOIE+ADC10INIE, &ADC10IE
        mov.w   #0x155, &ADC10LO        ; set ADC window threscholds
        mov.w   #0x2AA, &ADC10HI

        ; Timer_A0 setup for 0.5 sec periodic wakeups
        mov.w   #TASSEL_1+TACLR+TAIE, &TA0CTL ; ACLK, int. enable, clear
        mov.w   &ta_p, &TA0CCR0         ; Timer_A0 period
        ; Timer_A1 setup for button debouncing
        mov.w   #TASSEL_1, &TA1CTL      ; ACLK
        mov.w   #CCIS_2, &TA1CCTL0      ; compare channel 0
        mov.w   #CCIS_2, &TA1CCTL1      ; compare channel 1
        mov.w   #CCIS_2, &TA1CCTL2      ; compare channel 2
        
        call    #Init_RAM
loop:   bis.w   #LPM3+GIE, SR           ; enter LPM3 sleep mode
        nop

        tst.b   &event                  ; is any event set?
        jz      loop                    ; NO - wait for event
        mov.b   &state, R5              ; YES - jump to state processing
        rla.b   R5                      ; R5 = state*2 for the jump table
        add.w   R5, PC                  ; jump to state processing
        jmp     state0                  ; jump table
        jmp     state1
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
state2:                                 ; RECORDING
        bit.b   #Switch, &event         ; switch moved?    
        jz      s22                     ; NO
        clr.w   &recCnt                 ; YES - clear counter
        clr.b   &event                  ; clear all event flags
        mov.b   &switch, &state         ; new state
        cmp.b   #2, &switch
        jne     s21a
        bis.b   #Pause, &status
        call    #Stop_Start        
        jmp     loop
s21a:   cmp.b   #1, &switch                                    
        jne     s21b
        bic.b   #Pause, &status         ; switch to temp display mode
        call    #Clear_LCD
        jmp     s10
s21b:   mov.w   #1, &step               ; temp reading step
        bis.b   #Pause, &status
        call    #Clear_LCD
        jmp     loop                    ; switch to playback mode

s22:    bit.b   #Mode, &event           ; Mode button ?        
        jz      s23
        bic.b   #Mode, &event           ; clear event flag
        xor.b   #Pause, &status         ; flip state
        call    #Stop_Start             ; change status bit        
        jmp     loop

s23:    bit.b   #Down, &event           ; "<" button ? 
        jz      s24
        bic.b   #Down+Up, &event        ; clear flags
        call    #Dec_Period
        jmp     loop

s24:    bit.b   #Up, &event             ; ">" button ?
        jz      s25
        bic.b   #Down+Up, &event        ; clear flags
        call    #Inc_Period
        jmp     loop
        
s25:    bit.b   #Period, &event         ; time to display new value?
        jz      s26                     ; NO        
s20:    bit.b   #Pause, &status         ; pause mode ?
        jnz     loop                    ; YES - wait
        call    #Read_Temp              ; NO  - get temp from sensor 
        call    #Write_FRAM             ; and write it to FRAM
        call    #Display_Temp  
        bic.b   #Period, &event         ; clear event flag
        jmp     loop    

s26:    clr.b   &event                  ; clear event flags
        jmp     loop      

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
state1:                                 ; DISPLAY TEMP
        bit.b   #Switch, &event         ; switch moved?    
        jz      s12                     ; NO
        clr.w   &recCnt                 ; YES - clear counter
        clr.b   &event                  ; clear all event flags
        mov.b   &switch, &state         ; new state
        cmp.b   #1, &switch
        jeq     loop
        bis.b   #Pause, &status
        call    #Clear_LCD
        cmp.b   #2, &switch             ; switch to recording mode                       
        jeq     s20
        mov.w   #1, &step               ; temp reading step
        jmp     loop                    ; switch to playback mode

s12:    bit.b   #Mode, &event           ; Mode button ?        
        jz      s13
        bic.b   #Mode, &event           ; clear event flag
        xor.b   #Pause, &status         ; flip state
        call    #Stop_Start             ; change status bit        
        jmp     loop

s13:    bit.b   #Down, &event           ; "<" button ? 
        jz      s14
        bic.b   #Down+Up, &event        ; clear flags
        call    #Dec_Period
        jmp     loop

s14:    bit.b   #Up, &event             ; ">" button ?
        jz      s15
        bic.b   #Down+Up, &event        ; clear flags
        call    #Inc_Period
        jmp     loop
        
s15:    bit.b   #Period, &event         ; time to display new value?
        jz      s16                     ; NO        
s10:    bit.b   #Pause, &status         ; pause mode ?
        jnz     loop                    ; YES - wait
        call    #Read_Temp              ; NO  - get temp from sensor        
        call    #Display_Temp           
        bic.b   #Period, &event         ; clear event flag
        jmp     loop    

s16:    clr.b   &event                  ; clear event flags
        jmp     loop        
        
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
state0:                                 ; PLAYBACK
        bit.b   #Switch, &event         ; switch moved?    
        jz      s02                     ; NO
        clr.w   &recCnt                 ; YES - clear counter
        clr.b   &event                  ; clear all event flags
        mov.b   &switch, &state         ; new state
        cmp.b   #0, &switch
        jne     s01a
        bis.b   #Pause, &status
        call    #Stop_Start
        jmp     loop

s01a:   cmp.b   #2, &switch             ; switch to recording mode                       
        jne     s01b
        bis.b   #Pause, &status
        call    #Clear_LCD
        jmp     s20
s01b:   bic.b   #Pause, &status         ; switch to temp mode
        call    #Clear_LCD
        jmp     s10                    

s02:    bit.b   #Mode, &event           ; Mode button ?        
        jz      s03
        bic.b   #Mode, &event           ; clear event flag
        cmp.w   #1000, &step            ; is step at upper bound yet?
        jne     s02a                    ; NO - update step size
        mov.w   #1, &step               ; YES - reset step size
        jmp     s02b
s02a:   mov.b   #10, &MPY_B             ; multiply step by 10
        mov.b   &step, &OP2_B           ; width to get the digit data offset
        nop                             ; in the font table
        nop
        mov.w   &RES0, &step            ; set step size
s02b:   call    #Display_Multiple        
        jmp     loop              

s03:    bit.b   #Down, &event           ; "<" button ? 
        jz      s04
        bic.b   #Down+Up, &event        ; clear flags
        sub.w   &step, &recCnt          ; decrement records counter
        jge     s03a
        clr.w   &recCnt                 ; lower bound for the counter
s03a:   tst.w   &Buffer                 ; check if there is data to display
        jz      loop
        jmp     s00                     ; display data        
        
s04:    bit.b   #Up, &event             ; ">" button ?
        jz      s05
        bic.b   #Down+Up, &event        ; clear flags
        add.w   &step, &recCnt          ; increment records counter
        cmp.w   &Buffer, &recCnt
        jl      s00                     ; display data
        mov.w   &Buffer, &recCnt        ; set upper bound for counter
        dec.w   &recCnt
        jmp     loop
               
s05:    bit.b   #Period, &event         ; time to display new value?
        jz      s06                     ; NO                 
        bic.b   #Period, &event         ; clear event flag
        jmp     loop                    ; ignore timeout event

s06:    clr.b   &event                  ; clear event flags
        jmp     loop
        
s00:    call    #Read_FRAM              ; get temp from FRAM 
        call    #Display_Temp           ; and display it
        call    #Display_Counter
        jmp     loop
        
;===PROCEDURES==============================================================
Init_RAM:                               ; initialize used variables in RAM
        mov.b   #1, &state              ; initialization of used                  
        mov.w   #0xFF, &btState
        mov.w   #0xFF, &shiftM
        mov.w   #0xFF, &shiftD
        mov.w   #0xFF, &shiftU
        clr.b   &P1IFG                  ; clear P1 interrupt flags
        clr.b   &P2IFG                  ; clear P2 interrupt flags
        bis.w   #ADC10ENC, &ADC10CTL0   ; enable ADC conversions
        bis.w   #MC_1, &TA0CTL          ; start Timer_A0 in Up mode
        bis.w   #MC_2, &TA1CTL          ; start Timer_A1 in Continuous mode
        mov.b   #1, &periCnt
        mov.w   #1, &step               ; temp reading step
        clr.w   &width
        clr.b   &event
        clr.b   &status
        ret

;------------------------------------------------------------------------
Inc_Period:
        push.w  R15
        mov.b   &period, R15
        bic.b   #1, R15                 ; increment monitoring period
        add.b   #10, R15
        cmp.b   #70, R15
        jl      idp0
        sub.b   #10, R15
idp0:   mov.b   R15, &period
        call    #Display_Period
        mov.b   #1, &periCnt
        pop.w   R15
        ret

Dec_Period:
        push.w  R15
        mov.b   &period, R15
        sub.b   #10, R15                ; decrement monitoring period
        jl      idp1
        jnz     idp1
idp1:   mov.b   #1, R15
        jmp     idp0

;------------------------------------------------------------------------
Stop_Start:                             ; pause or restart the process
        mov.b   #45, &x
        mov.b   #7, &y
        mov.w   #Start_Symb, R11
        bit.b   #Pause, &status
        jnz     ss1
        mov.w   #Pause_Symb, R11
ss1:    jmp     Display_Bitmap

;------------------------------------------------------------------------
Read_FRAM:
        mov.w   &recCnt, R5             ; setup new record pointer
        rla.w   R5                      ; adjust to words count
        add.w   #Buffer+2, R5
        mov.w   @R5, R4                 ; read temp from FRAM
        ret
        
;------------------------------------------------------------------------
Write_FRAM:                             ; write temp BCD in R4 to FRAM
        mov.w   &recCnt, R5             ; setup new recore pointer
        rla.w   R5                      ; adjust to words count
        add.w   #Buffer+2, R5
        mov.w   R4, 0(R5)               ; write temp to FRAM
        inc.w   &recCnt                 ; update records counter
        mov.w   &recCnt, &Buffer
        incd.w  R5                      ; update the pointer
        cmp.w   #0xFF80, R5             ; check for end of memory
        jeq     halt
        ret
halt:   jmp     Power_Off
        
;------------------------------------------------------------------------       
Read_Temp:                              ; read temp from sensor
        mov.b   #0x07, &i2cb            ; read ambient temp
        mov.b   #1, &cnt                ; # of bytes to send
        mov.w   #i2cb, R11              ; set data pointer
        bic.w   #UCSWRST, &UCB0CTLW0    ; clear I2C reset
        bis.w   #UCTXIE0+UCNACKIE, &UCB0IE  ; enable I2C TX interrupt
        bis.w   #UCTR+UCTXSTT, &UCB0CTLW0   ; send start condition and write  
        bis.w   #LPM0+GIE, SR           ; enter LPM0 
        nop                             ; remain in LPM0      

        mov.w   #3, &UCB0TBCNT          ; prepare to receive 3 bytes via I2C
        bic.w   #UCTR, &UCB0CTLW0       ; set receiver mode        
        mov.w   #UCASTP_2, &UCB0CTLW1   ; automatic stop generation
        bic.w   #UCSWRST, &UCB0CTLW0    ; clear I2C reset 
        mov.w   #UCSTPIE, &UCB0IE       ; enable I2C stop interrupt 
        bis.w   #DMAEN, &DMA2CTL        ; enable DMA_2 transfer  
        bis.w   #UCTXSTT, &UCB0CTLW0    ; send start condition 
        bis.w   #LPM0+GIE, SR           ; enter LPM0 
        nop                             ; remain in LPM0
        bic.w   #DMAEN, &DMA2CTL        ; disable DMA channel 2
        bis.w   #UCSWRST, &UCB0CTLW0    ; I2C reset   
        
        mov.w   &i2cb, R10
        rla.w   R10
        sub.w   #27315, R10             ; R10 = temp*100
        
;------------------------------------------------------------------------
Format_Temp:                            ; convert R10 into 5-digit BCD
        clrx.a  R4                      ; storage for 4-digit BCD
        mov.b   #16, R5                 ; loop cnt = # of bits
        
        add.w   #5, R10                 ; rounding off
        mov.w   R10, R14                ; save rounded off in R14
        tst.w   R10                     ; R10 >=0 ?
        jge     bb1                     ; YES - proceed
        xor.w   #0xFFFF, R10            ; NO  - 2-complement R10 
        add.w   #1, R10
        
bb1:    rla.w   R10                     ; use decimal addition
        daddx.a R4, R4                  ; operation to convert R4
        dec.b   R5                      ; into BCD
        jnz     bb1 

        tst.w   R14                     ; temp >= 0 ?
        jn      bb2                     ; YES

        cmp.w   #10000, R14             ; NO - proceed
        jl      bb4
        daddx.a #0x45, R4               ; round off to an integer
        rrum.a  #4, R4                  ; get rid of decimal digits
        rrum.w  #4, R4
        bis.w   #0xC000, R4             ; fill in blanks (C)
        ret

bb2:    cmp.w   #-999, R14              ; R14 has 1 integer digit? 
        jge     bb3                     ; YES - proceed                              
        dadd.w  #0x45, R4               ; NO  - round off to an integer
        rrum.w  #4, R4                  ; get rid of fraction   
        rrum.w  #4, R4          
        bis.w   #0xCB00, R4             ; add the minus sign (B)
        ret

bb3:    bis.w   #0xB000, R4             ; add the minus sign (B)
bb4:    mov.b   R4, R10
        rrum.w  #4, R10                 ; get rid of the 2nd decimal        
        bis.b   #0xA0, R10              ; add decimal point
        bic.w   #0xFF, R4
        add.w   R10, R4                 ; R4 is formatted BCD(temp)
        bit.w   #0xF000, R4
        jnz     bb5
        bis.w   #0xC000, R4
bb5:    ret        
                        
;---------------------------------------------------------------------------
Send_CMD:
        bic.w   #CD, &PJOUT             ; sending command to LCD
        mov.w   R10, &UCA0TXBUF         ; start SPI transmission
        bit.w   #0x02, &UCA0IFG   
        jz      $-4
        
        mov.w   #50, R15                ; 0.5 msec delay
        dec.w   R15
        jnz     $-2        
        ret

;---------------------------------------------------------------------------
Power_Off:                              ; shut down the device
        bic.w   #RST, &PJOUT            ; LCD reset
        mov.w   #13333, R5              ; 5 msec delay
        dec.w   R5
        jnz     $-2
        bic.b   #Power, &P1DIR          ; disable DC/DC
        jmp     $                       ; wait for shut down

;---------------------------------------------------------------------------
Send_UART:                              
        bit.b   #Mode, &P1IN            ; wait for release of the Mode button
        jz      $-4

        push.w  &UCA0CTLW0              ; preserve SPI setup
        push.w  &UCA0BRW
        mov.w   #UCSWRST+UCSSEL_2, &UCA0CTLW0 ; keep eUSCI_A module in reset
        mov.b   #52, &UCA0BR0           ; clock division for 9600 bod

        mov.w   #Buffer, R11            ; pointer to stored data values
        mov.w   @R11+, R15              ; data counter
        tst.w   R15                     ; exit if the buffer is empty
        jz      su7
su1:    mov.w   @R11+, R4               ; get data

        mov.b   #4, R14                 ; nibble counter
su2:    rpt     #5
        rlcx.w  R4
        mov.b   R4, R10                 ; get symbol
        rrc.w   R4                      ; restore R4 (shift involves 5 bits)
        and.b   #0x0F, R10              ; leave only the needed nibble

        cmp.b   #0x0A, R10              ; "." sign ?
        jne     su3
        mov.b   #0x2E, R13              ; ASCII code of "."
        jmp     su6        
su3:    cmp.b   #0x0B, R10              ; "-" sign ?
        jne     su4
        mov.b   #0x2D, R13              ; ASCII code of "-"
        jmp     su6
su4:    cmp.b   #0x0C, R10              ; " " sign ?
        jne     su5
        mov.b   #0x20, R13              ; ASCII code of space
        jmp     su6
su5:    add.b   #0x30, R13              ; ASCII conversion of digit    
su6:    mov.w   R13, &UCA0TXBUF         ; send it through UART
        bis.w   #LPM0+GIE, SR           ; put CPU in LMP 0 mode
        nop                             ; wait for the end of transmission
        dec.b   R14
        jnz     su2                     ; repeat this for all nibbles
        
        mov.w   #0x0D, &UCA0TXBUF       ; send CR control code         
        bis.w   #LPM0+GIE, SR           ; put CPU in LMP 0 mode
        nop                             ; wait for the end of transmission
        mov.w   #0x0A, &UCA0TXBUF       ; send LF control code
        bis.w   #LPM0+GIE, SR           ; put CPU in LMP 0 mode
        nop
        
        dec.w   R15                     ; loop for all stored data
        jnz     su1

su7:    pop.w   &UCA0BRW                ; restore SPI settings
        pop.w   &UCA0CTLW0
        ret

;------------------------------------------------------------------------
Init_LCD:
        bic.w   #RST, &PJOUT            ; hardware reset
        mov.w   #13333, R5              ; 5 msec delay
        dec.w   R5
        jnz     $-2
        bis.w   #RST, &PJOUT            ; release LCD reset pin
        mov.w   #26666, R5              ; 10 msec delay
        dec.w   R5
        jnz     $-2

        bis.b   #BIT5, &P1SEL1          ; connect pins to SPI
        bis.b   #BIT0+BIT1, &P2SEL1        
        bic.b   #UCSWRST, &UCA0CTL1     ; enable SPI module
        bic.w   #CS, &PJOUT             ; enable device interface

        mov.w   #LCD_Setup, &DMA0SAL    ; DMA source address
        mov.w   #13, &DMA0SZ            ; amount to transfer        
        mov.w   #DMALEVEL+DMASRCINCR_3+DMASRCBYTE+DMAIE, &DMA0CTL
        bic.w   #CD, &PJOUT             ; prepare to send commands
        bis.w   #DMAEN, &DMA0CTL        ; start DMA transfer
        bis.w   #LPM0+GIE, SR           ; enter LPM0 sleep mode   
        nop
        mov.b   #1, &period             ; display period
        mov.b   #1, &state
        mov.w   #1, step
        clr.w   &recCnt
        bic.b   #Pause, &status
        clr.b   &algn
        
;------------------------------------------------------------------------
Clear_LCD:
        clr.b   &zero                   ; value to fill in
        mov.w   #zero, &DMA0SAL         ; DMA source address
        mov.w   #103, &DMA0SZ           ; amount to transfer
        mov.w   #DMALEVEL+DMASRCBYTE+DMAIE, &DMA0CTL ; level-triggered, INT enable
        
        bis.b   #BIT5, &P1SEL1          ; connect pins to SPI
        bis.b   #BIT0+BIT1, &P2SEL1        
        bic.b   #UCSWRST, &UCA0CTL1     ; enable SPI module
        bic.w   #CS, &PJOUT             ; enable device interface

	mov.b	#7, R7			; set page 
next_page:
	mov.b	R7, R10
	bis.b	#0xB0, R10		; set page command
	call	#Send_CMD

	mov.b	#0x11, R10		; set column address (MSB)
	call	#Send_CMD
	mov.b   #0x0E, R10
	call	#Send_CMD	

        bis.w   #CD, &PJOUT             ; prepare to send data
        bis.w   #DMAEN, &DMA0CTL        ; start DMA transfer
        bis.w   #LPM0+GIE, SR           ; enter LPM0 sleep mode

        dec.b   R7                      ; CPU is awake now
	jge	next_page
        bis.w   #CS, &PJOUT             ; disable device interface
        bis.b   #UCSWRST, &UCA0CTL1     ; disable SPI module
        bic.b   #BIT5, &P1SEL1          ; disconnect pins from SPI
        bic.b   #BIT0+BIT1, &P2SEL1

        mov.b   #85, &x                 ; display degree symbol
        mov.b   #5, &y
        mov.w   #Deg_C, R11
        call    #Display_Bitmap

        clr.b   &x                      ; display arrows
        mov.b   #7, &y
        mov.w   #Left_Arrow, R11
        call    #Display_Bitmap
        mov.b   #97, &x
        mov.w   #Right_Arrow, R11
        call    #Display_Bitmap        
        tst.b   &state                  ; display cross in state 0
        jz      cs2a                    ; and start symbol in other
        call    #Stop_Start             ; states
        jmp     cs2b
cs2a:   mov.b   #45, &x
        mov.w   #Cross_Symb, R11
        call    #Display_Bitmap
        
cs2b:   cmp.b   #0, &state              ; display special symbols
        jeq     cs0                     ; depending on state
        cmp.b   #1, &state
        jeq     cs1
        clr.b   &x                      ; state 2: display REC sign
        mov.b   #1, &y
        mov.w   #Rec_Symb, R11
        call    #Display_Bitmap
cs1:    call    #Display_Period
        ret

cs0:    tst.w   &Buffer                 ; state 0: display 1st records 
        jz      cs0a                    ; if exists
        call    #Read_FRAM              ; get 1st record from FRAM
        call    #Display_Temp
        call    #Display_Counter
cs0a:   mov.b   #47, &x                 ; display "/"
        mov.b   #1, &y
        mov.w   #Slash_Symb, R11
        call    #Display_Bitmap
        mov.b   #58, &x                 ; display total # or records
        mov.w   &Buffer, R10
        mov.b   #1, &algn               ; request left alignment
        call    #Display_Rec_No
        ret

;------------------------------------------------------------------------
Display_Temp:
        clr.b   &x                      ; setup LCD coordinates
        mov.b   #6, &y       
        mov.b   #4, &height             ; large font parameters
        mov.w   #21, &width
        mov.w   #Large_Font, &font

Display_Number:                         ; display 4-symbol number in R4
        push.w  R4                      ; save R4
        mov.w   #digits, R5             ; filling digit pointer table
dn1:    rpt     #5
        rlcx.w  R4
        mov.b   R4, R11                 ; get digit
        rrc.w   R4                      ; restore R4 (shift involves 5 bits)
        and.b   #0x0F, R11              ; leave only the needed nibble
        rla.b   R11                     ; multiply the digit by 2 or 4
        bit.b   #BIT2, &height
        jz      dn2
        rla.b   R11                     ; (every digit takes 2 04 4 LCD rows)
dn2:    mov.b   &width, &MPY_B          ; multiply the result by the digit
        mov.b   R11, &OP2_B             ; width to get the digit data offset
        nop                             ; in the font table
        nop
        mov.w   &RES0, R11              ; R11 = offset of digit              
        add.w   &font, R11              ; R11 = address of digit
        mov.w   R11, 0(R5)              ; load it to the table
        incd.w  R5                      ; advance the pointer
        cmp.w   #digits+8, R5
        jne     dn1                     ; pointer table is ready now
        pop.w   R4                      ; restore R4

        mov.w   &width, &DMA0SZ         ; amount to transfer
        mov.w   #DMALEVEL+DMASRCINCR_3+DMASRCBYTE+DMAIE, &DMA0CTL
        bis.b   #BIT5, &P1SEL1          ; connect pins to SPI
        bis.b   #BIT0+BIT1, &P2SEL1        
        bic.b   #UCSWRST, &UCA0CTL1     ; enable SPI module
        bic.w   #CS, &PJOUT             ; enable device interface 

dn3:    mov.w   #digits, R5             ; reset table pointer
        call    #Set_Cursor
        bis.w   #CD, &PJOUT             ; prepare to send data
dn4:    mov.w   @R5, &DMA0SAL           ; DMA source address
        bis.w   #DMAEN, &DMA0CTL        ; start DMA transfer
        bis.w   #LPM0+GIE, SR           ; enter LPM0 sleep mode
        nop
        add.w   &width, 0(R5)           ; advance digit pointer to next row
        incd.w  R5
        cmp.w   #digits+8, R5
        jne     dn4    
        dec.b   &y
        call    #delay
        dec.b   &height
        jnz     dn3

        bis.w   #CS, &PJOUT             ; disable device interface
        bis.b   #UCSWRST, &UCA0CTL1     ; disable SPI module
        bic.b   #BIT5, &P1SEL1          ; disconnect pins from SPI
        bic.b   #BIT0+BIT1, &P2SEL1        
        ret
        
;------------------------------------------------------------------------
Display_Bitmap:				; display 2-dim bitmap pointed by R11
	mov.b	@R11+, &width	        ; get bitmap width
	mov.b	@R11+, &height          ; get bitmap height      
        mov.w   #DMALEVEL+DMASRCINCR_3+DMASRCBYTE+DMAIE, &DMA0CTL         
        mov.b   &width, R6
        mov.w   R6, &DMA0SZ             ; amount to transfer
        push.w  &y                      ; preserve y-coord. 
        bis.b   #BIT5, &P1SEL1          ; connect pins to SPI
        bis.b   #BIT0+BIT1, &P2SEL1        
        bic.b   #UCSWRST, &UCA0CTL1     ; enable SPI module
        bic.w   #CS, &PJOUT             ; enable device interface

dbm1:   call    #Set_Cursor
        bis.w   #CD, &PJOUT             ; prepare to send data
        mov.w   R11, &DMA0SAL           ; DMA source address
        bis.w   #DMAEN, &DMA0CTL        ; start DMA transfer
        bis.w   #LPM0+GIE, SR           ; enter LPM0 sleep mode
        nop
        call    #delay
        add.w   R6, R11                 ; update pointer
        dec.b	&y
	dec.b	&height
	jnz	dbm1
        pop.w   &y                      ; restore y-coord.
        
        bis.w   #CS, &PJOUT             ; disable device interface
        bis.b   #UCSWRST, &UCA0CTL1     ; disable SPI module
        bic.b   #BIT5, &P1SEL1          ; disconnect pins from SPI
        bic.b   #BIT0+BIT1, &P2SEL1 
	ret

;----------------------------------------------------------------------
Display_Period:                         ; display measurement period
        mov.b   #58, &x                 
        mov.b   #1, &y
        mov.b   #2, &height             ; small font parameters
        mov.w   #11, &width
        mov.w   #Small_Font, &font

        clr.w   R4                      ; storage for 4-digit BCD
        mov.b   #8, R5                  ; loop cnt = # of bits
        mov.b   &period, R10        
dp0:    rla.b   R10                     ; use decimal addition
        dadd.w  R4, R4                  ; operation to convert R4
        dec.b   R5                      ; into BCD
        jnz     dp0 

        rpt     #4                      ; add "T        s" part
        rlcx.w  R4
        bis.w   #0xC00B, R4
        cmp.b   #1, &period
        jne     dp1
        bic.w   #0x0F00, R4             ; add "=" sign
        bis.w   #0x0A00, R4
dp1:    jmp     Display_Number

;----------------------------------------------------------------------
Display_Counter:
        clr.b   &x
        mov.w   &recCnt, R10
        inc.w   R10
Display_Rec_No:        
        mov.b   #1, &y
        mov.b   #2, &height             ; small font parameters
        mov.w   #11, &width
        mov.w   #Small_Font, &font

        clr.w   R4                      ; storage for 4-digit BCD
        mov.b   #16, R5                 ; loop cnt = # of bits        
dc1:    rla.w   R10                     ; use decimal addition
        dadd.w  R4, R4                  ; operation to convert R4
        dec.b   R5                      ; into BCD
        jnz     dc1 
        
        mov.b   #3, R10                 ; loop counter
        tst.b   &algn
        jnz     ra
la:     bit.w   #0xF000, R4             ; perform right alignment
        jnz     dc2                     ; by replacing leading zeros
        bis.w   #0xD000, R4             ; with blanks (code 0xD)
        bit.w   #0x0F00, R4
        jnz     dc2
        bis.w   #0x0D00, R4
        bit.b   #0xF0, R4
        jnz     dc2
        bis.w   #0x00D0, R4
        jmp     dc2
        
ra:     bit.w   #0xF000, R4             ; perform left alignment
        jnz     dc2                     ; by suppresing leading zeros
        rpt     #4                      ; and incerting the tailing
        rlcx.w  R4                      ; blanks (code 0xD)
        bis.w   #0x000D, R4
        dec.b   R10
        jnz     ra

dc2:    clr     &algn
        jmp     Display_Number

;----------------------------------------------------------------------
Display_Multiple:
        mov.b   #7, &y                  ; arrow row on LCD
        mov.w   #Left_Arrow, R11        ; preload bitmap pointer
        cmp.w   #10, &step
        jge     dm1a
        mov.w   #Blank_Arrow, R11
dm1a:   mov.b   #5, &x
        call    #Display_Bitmap
        mov.b   #92, &x
        call    #Display_Bitmap        

        mov.w   #Left_Arrow, R11
        cmp.w   #100, &step
        jge     dm1b
        mov.w   #Blank_Arrow, R11
dm1b:   mov.b   #10, &x
        call    #Display_Bitmap
        mov.b   #87, &x
        call    #Display_Bitmap 

        mov.w   #Left_Arrow, R11
        cmp.w   #1000, &step
        jge     dm1c
        mov.w   #Blank_Arrow, R11
dm1c:   mov.b   #15, &x
        call    #Display_Bitmap
        mov.b   #82, &x
        call    #Display_Bitmap         
        ret
        
;----------------------------------------------------------------------
Set_Cursor:                             ; set LCD cursor to x, y
	mov.b	&y, R10
	bis.b	#0xB0, R10					
	call	#Send_CMD		; set page

        mov.b   &x, R10
        add.b   #30, R10
        push.w  R10
        rrum.w  #4, R10
	bis.b	#0x10, R10		; set column address (MSB)
	call	#Send_CMD
        pop.w   R10
	bic.b   #0xF0, R10              ; set column address (LSB)
	call	#Send_CMD	
        ret
        
;----------------------------------------------------------------------
delay:
        push.w  R15
        mov.w   #100, R15               ; short delay to allow LCD
        dec.w   R15                     ; to catch up
        jnz     $-2
        pop.w   R15
        ret
        
;======================================================================
UART_ISR:
        add     &UCA0IV,PC              ; add offset to PC
        reti                            ; no interrupt
        reti                            ; UCRXIFG break
        reti                            ; UCTXIFG break
        reti                            ; UCSTTIFG break
                                        ; UCTXCPTIFG break
        bic.w   #LPM0,0(SP)             ; wake-up CPU       
        reti                            ; as transmission is complete
        
;----------------------------------------------------------------------
I2C_ISR:
        add     &UCB0IV,PC              ; add offset to PC
        reti                            ; no interrupt
        reti                            ; ALIFG break
        reti                            ; NACKIFG break
        reti                            ; STTIFG break
        jmp     I2end                   ; STPIFG break
        reti                            ; RXIFG3 break
        reti                            ; TXIFG3 break
        reti                            ; RXIFG2 break
        reti                            ; TXIFG2 break
        reti                            ; RXIFG1 break
        reti                            ; TXIFG1 break
        reti                            ; RXIFG0 break
        jmp     I2TX                    ; TXIFG0 break
        reti                            ; BCNTIFG break
        reti                            ; clock low timeout break
        reti                            ; 9th bit break

I2TX:   cmp.b   #0, &cnt
        jeq     I2end
        mov.b   @R11+, R10
        mov.w   R10, &UCB0TXBUF         ; Load TX buffer
        dec.b   &cnt                    ; Decrement TX byte counter
        reti
        
I2end:  bic.w   #LPM0,0(SP)             ; wake-up CPU       
        reti
        
;----------------------------------------------------------------------
ADC10_ISR: 
        add.w   &ADC10IV, PC            ; add offset to PC
        reti                            ; No Interrupt
        reti                            ; ADC10_B overflow
        reti                            ; ADC10_B timing overflow
        jmp     ADC_hi                  ; ADC10_B window comparator high
        jmp     ADC_lo                  ; ADC10_B window comparator low
        jmp     ADC_in                  ; ADC10_B window comparator in

        dec.b   &periCnt                ; ADC_10B completion
        jnz     ADC_fi                  ; period expired? NO - exit
        mov.b   &period, &periCnt       ; restore the counter
        rla.b   &periCnt
        bis.b   #Period, &event         ; set event

ADC_fi: clr.w   &ADC10IFG               ; clear interrupt flags
        bic.w   #LPM0, 0(SP)            ; conversion complete, wake-up CPU 
        reti
ADC_hi: mov.b   #2, &switch             ; new state
        bis.b   #Switch, &event         ; set event
        mov.w   #ADC10LOIE+ADC10INIE+ADC10IFG0, &ADC10IE
        jmp     ADC_fi
ADC_lo: clr.b   &switch                 ; new state
        bis.b   #Switch, &event         ; set event
        mov.w   #ADC10HIIE+ADC10INIE+ADC10IFG0, &ADC10IE
        jmp     ADC_fi
ADC_in: mov.b   #1, &switch             ; new state
        bis.b   #Switch, &event         ; set event
        mov.w   #ADC10LOIE+ADC10HIIE+ADC10IFG0, &ADC10IE
        jmp     ADC_fi
        nop
        
;----------------------------------------------------------------------
TA0_ISR:                                ; timestamp for every 0.5 sec
        bic.w   #TAIFG, &TA0CTL         ; clear Timer_A0 interrupt flag
        bis.w   #ADC10ENC+ADC10SC, &ADC10CTL0 ; trigger ADC conversion
        bic.w   #SCG0+SCG1, 0(SP)       ; enter LPM0 mode
        reti
        
;----------------------------------------------------------------------
DMA_ISR:
        add.w   &DMAIV, PC              ; add offset to jump table
        reti
        jmp     DMA0_HND
        jmp     DMA1_HND
DMA2_HND:
        bic.w   #LPM0, 0(SP)            ; wake-up CPU
        bic.w   #DMAEN, &DMA2CTL        ; disable DMA channel 2
        reti
DMA1_HND:
        bic.w   #LPM0, 0(SP)            ; wake-up CPU
        bic.w   #DMAEN, &DMA1CTL        ; disable DMA channel 1
        reti
DMA0_HND:
        bic.w   #LPM0, 0(SP)            ; wake-up CPU
        bic.w   #DMAEN, &DMA0CTL        ; disable DMA channel 0
        reti

;----------------------------------------------------------------------
CCR0_ISR:
        clrc                            
        rrc.b   &shiftM                 ; debouncing the Mode button          
        bit.b   #Mode, &P1IN            ; shift in the button value
        jz      $+8                     ; jump over the next instruction
        bis.b   #BIT7, &shiftM          ; the shift register is updated
        
        bit.b   #Mode, &btState         ; old state == "up" ?
        jz      ccr0_1                  ; NO - it is "down"

        cmp.b   #pressTsch, &shiftM     ; has old "up" state changed?
        jhs     ccr0_2                  ; NO - setup another CCR event
        bic.b   #Mode, &btState         ; YES - set new state="down"
        bis.b   #Mode, &event           ; set event  
        bic.w   #LPM3, 0(SP)            ; wake-up CPU        
        jmp     ccr0_2                  ; setup new event time

ccr0_1: cmp.b   #releaseTsch, &shiftM   ; has old "down" state changed?
        jlo     ccr0_2                  ; NO - keep waiting
        bis.b   #Mode, &btState         ; YES - set new state="up"
        bic.w   #CCIE, &TA1CCTL0        ; disable CCR1 compare interrupt
        bic.b   #Mode, &P1IFG           ; clear P1 interrupt flag
        bis.b   #Mode, &P1IE            ; enable button interrupt
        reti

ccr0_2: push.w  R7                      ; save used reg
        mov.w   &TA1R, R7               ; compute next CCR0 event time
        add.w   &ta_d, R7
        mov.w   R7, &TA1CCR0
        pop.w   R7                      ; restore used reg        
        reti

;----------------------------------------------------------------------
TA1_ISR:
        add.w   &TA1IV, PC              ; add offset to jump table 
        reti                            ; no interrupt 
        jmp     CCR1                    ; TA1CCR1
        jmp     CCR2                    ; TA1CCR2 
        reti                            ; TA1CCR3 
        reti                            ; TA1CCR4 
        reti                            ; TA1CCR5 
        reti                            ; TA1CCR6
        reti
        
CCR1:   clrc                            
        rrc.b   &shiftD                 ; debouncing the "<" button          
        bit.b   #Down, &P1IN            ; shift in the button value
        jz      $+8                     ; jump over the next instruction
        bis.b   #BIT7, &shiftD          ; the shift register is updated
        
        bit.b   #Down, &btState         ; old state == "up" ?
        jz      ccr1_1                  ; NO - it is "down"

        cmp.b   #pressTsch, &shiftD     ; has old "up" state changed?
        jhs     ccr1_2                  ; NO - setup another CCR event
        bic.b   #Down, &btState         ; YES - set new state="down"
        bis.b   #Down, &event           ; set event    
        bic.w   #LPM3, 0(SP)            ; wake-up CPU
        jmp     ccr1_2                  ; setup new event time

ccr1_1: cmp.b   #releaseTsch, &shiftD   ; has old "down" state changed?
        jlo     ccr1_2                  ; NO - keep waiting
        bis.b   #Down, &btState         ; YES - set new state="up"
        bic.w   #CCIE, &TA1CCTL1        ; disable CCR1 compare interrupt
        bic.b   #Down, &P1IFG           ; clear P1 interrupt flag
        bis.b   #Down, &P1IE            ; enable button interrupt
        reti

ccr1_2: push.w  R7                      ; save used reg
        mov.w   &TA1R, R7               ; compute next CCR0 event time
        add.w   &ta_d, R7
        mov.w   R7, &TA1CCR1
        pop.w   R7                      ; restore used reg
        reti
        
CCR2:   clrc                            
        rrc.b   &shiftU                 ; debouncing the ">" button          
        bit.b   #Up, &P1IN              ; shift in the button value
        jz      $+8                     ; jump over the next instruction
        bis.b   #BIT7, &shiftU          ; the shift register is updated
        
        bit.b   #Up, &btState           ; old state == "up" ?
        jz      ccr2_1                  ; NO - it is "down"

        cmp.b   #pressTsch, &shiftU     ; has old "up" state changed?
        jhs     ccr2_2                  ; NO - setup another CCR event
        bic.b   #Up, &btState           ; YES - set new state="down"
        bis.b   #Up, &event             ; set event    
        bic.w   #LPM3, 0(SP)            ; wake-up CPU
        jmp     ccr2_2                  ; setup new event time

ccr2_1: cmp.b   #releaseTsch, &shiftU   ; has old "down" state changed?
        jlo     ccr2_2                  ; NO - keep waiting
        bis.b   #Up, &btState           ; YES - set new state="up"
        bic.w   #CCIE, &TA1CCTL2        ; disable CCR1 compare interrupt
        bic.b   #Up, &P1IFG             ; clear P1 interrupt flag
        bis.b   #Up, &P1IE              ; enable button interrupt
        reti

ccr2_2: push.w  R7                      ; save used reg
        mov.w   &TA1R, R7               ; compute next CCR0 event time
        add.w   &ta_d, R7
        mov.w   R7, &TA1CCR2
        pop.w   R7                      ; restore used reg
        reti     
        
;----------------------------------------------------------------------
P1_ISR: 
        push.w  R6
        push.w  R7                      ; save used regs
        mov.w   &TA1R, R7               ; compute next CC event time
        add.w   &ta_d, R7

        mov.w   &P1IV, R6               ; compute pin number that
        sub.w   #4, R6                  ; 0:">", 2:mode, 4:"<"
        add.w   R6, PC
        jmp     p1g
        jmp     p1m

p1l:    mov.w   R7, &TA1CCR1            ; debouncing the "<" button
        mov.w   #CCIS_2+CCIE, &TA1CCTL1 ; enable compare Timer_A1 interr.
        bic.b   #Down, &P1IE            ; disable port interrupt
        jmp     p1end
        
p1g:    mov.w   R7, &TA1CCR2            ; debouncing the ">" button
        mov.w   #CCIS_2+CCIE, &TA1CCTL2 ; enable compare Timer_A1 interr.
        bic.b   #Up, &P1IE              ; disable port interrupt
        jmp     p1end

p1m:    mov.w   R7, &TA1CCR0            ; debounsing the "Mode" button 
        mov.w   #CCIS_2+CCIE, &TA1CCTL0 ; enable compare Timer_A1 interr.
        bic.b   #Mode, &P1IE            ; disable port interrupt
        
p1end:  pop.w   R7
        pop.w   R6
        reti

;----------------------------------------------------------------------
P2_ISR:
        cmp.b   #2, &state              ; save records counter
        jne     p2_1                    ; if in recording mode
        mov.w   &recCnt, &Buffer        
p2_1:   br      #Power_Off              ; shut down the device
        nop
        
;----------------------------------------------------------------------
LCD_Setup:
DB      0x40, 0xA0, 0xC0, 0xA4, 0xA6, 0xA2, 0x2F, 0x27, 0x81, 0x08, 0xFA
DB      0x90, 0xAF

Large_Font:	; 19x32 font
DB	0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0xFF, 0xE0, 0xC0, 0xE0	; 0
DB	0xFF, 0x7F, 0x7F, 0x3F, 0x1F, 0x0F, 0x03, 0x00, 0x00, 0x00
DB	0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00
DB	0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00
DB	0x00, 0xC0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0x07, 0x03, 0x07
DB	0xFF, 0xFE, 0xFE, 0xFC, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x07, 0x0F, 0x1F, 0x7F, 0xFF	; 1
DB	0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
DB	0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
DB	0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
DB	0xFF, 0xFF, 0xFF, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x07, 0x1F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xE0, 0xC0, 0xC0, 0xE0	; 2
DB	0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F, 0x0F, 0x03, 0x00, 0x00
DB	0x80, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x01, 0x0F
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x1F, 0x3E, 0x7E, 0xFC, 0xF8
DB	0xF0, 0xE0, 0xE0, 0xC0, 0x81, 0x01, 0x01, 0x01, 0x00, 0x00
DB	0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xBF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
DB	0x3F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFE, 0xE0, 0x00, 0x00
DB	0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0xFF, 0xE0, 0xC0, 0xC0, 0xE0, 0xF0	; 3
DB	0xFF, 0x7F, 0x7F, 0x7F, 0x3F, 0x1F, 0x07, 0x00, 0x00, 0x00
DB	0x80, 0xC0, 0xC0, 0xC0, 0xC3, 0x83, 0x03, 0x03, 0x03, 0x07, 0x0F
DB	0xFF, 0xFF, 0xFD, 0xFC, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00
DB	0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x80, 0xE0
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x00, 0x00
DB	0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0x07, 0x03, 0x03, 0x07, 0x0F
DB	0xFF, 0xFE, 0xFE, 0xFE, 0xFC, 0xF8, 0xF0, 0xC0, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03	; 4
DB	0x0F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x3E, 0x78, 0xFF, 0xFF
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
DB	0x07, 0x0F, 0x3F, 0x7F, 0xFB, 0xE3, 0x83, 0x03, 0x03, 0xFF, 0xFF
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0xFF, 0xFF
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x07, 0x00, 0x00
DB	0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC	; 5
DB	0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x1F, 0x1C, 0x1C, 0x1C, 0x1E, 0x1F
DB	0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00
DB	0x01, 0x83, 0x83, 0x83, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00
DB	0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0x03, 0x03, 0x03, 0x03, 0x07
DB	0xFF, 0xFE, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0x80, 0x00, 0x00
DB	0x00, 0x00, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x3F, 0x7C, 0x70, 0xF0	; 6
DB	0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00
DB	0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x70, 0x70
DB	0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x07, 0x01, 0x00, 0x00
DB	0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00
DB	0x00, 0xE0, 0xF0, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0x07, 0x03, 0x07
DB	0xFF, 0xFE, 0xFE, 0xFC, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00
DB	0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC	; 7
DB	0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0, 0x00, 0x00
DB	0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F
DB	0x3F, 0xFF, 0xFF, 0xF8, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1F, 0xFF, 0xFF, 0xFF
DB	0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
DB	0xFF, 0xFF, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x07, 0x1F, 0x3F, 0x7F, 0x7F, 0xFF, 0xF0, 0xE0, 0xC0, 0xC0	; 8
DB	0xE0, 0xF0, 0x7F, 0x7F, 0x3F, 0x1F, 0x07, 0x00, 0x00, 0x00
DB	0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F
DB	0x0F, 0x3F, 0xFF, 0xFF, 0xF9, 0xF0, 0xC0, 0x00, 0x00, 0x00
DB	0x07, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xF0, 0xE0, 0xF0, 0xF8, 0xF8
DB	0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x00, 0x00
DB	0xC0, 0xF0, 0xFC, 0xFC, 0xFE, 0xFE, 0x1F, 0x07, 0x03, 0x03, 0x03
DB	0x07, 0x0E, 0xFE, 0xFE, 0xFC, 0xF8, 0xF0, 0xC0, 0x00, 0x00
DB	0x00, 0x07, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0	; 9
DB	0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F, 0x07, 0x00, 0x00, 0x00
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00
DB	0x80, 0xE0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0x1E, 0x0E, 0x1C
DB	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00
DB	0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x0E, 0x0E, 0x3E
DB	0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00

Point:
;DB	0x15, 0x04	; WxH of "."
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F	
DB	0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Minus:
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07	
DB	0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0	
DB	0xE0, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Blank:
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Small_Font:	; 10x16 font
DB      0x1F, 0x7F, 0x7F, 0xE0, 0xC0, 0xC0, 0xE0, 0x7F, 0x7F, 0x1F, 0x00 ; 0
DB      0xF8, 0xFE, 0xFE, 0x07, 0x03, 0x03, 0x07, 0xFE, 0xFE, 0xF8, 0x00
DB      0x00, 0x00, 0x0E, 0x1C, 0x1C, 0x38, 0xFF, 0xFF, 0xFF, 0x00, 0x00 ; 1
DB      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00
DB      0x30, 0x70, 0xF0, 0xE0, 0xC0, 0xC1, 0xE3, 0x7F, 0x7F, 0x1C, 0x00 ; 2
DB      0x03, 0x0F, 0x1F, 0x3F, 0xFB, 0xF3, 0xC3, 0x83, 0x03, 0x03, 0x00
DB      0x10, 0x70, 0x70, 0xE0, 0xC3, 0xC7, 0xFF, 0x7F, 0x3C, 0x00, 0x00 ; 3
DB      0x0C, 0x0E, 0x0F, 0x07, 0x03, 0x03, 0x87, 0xFE, 0xFE, 0x78, 0x00
DB      0x00, 0x00, 0x01, 0x07, 0x1E, 0x38, 0xFF, 0xFF, 0xFF, 0x00, 0x00 ; 4
DB      0x38, 0xF8, 0xD8, 0x98, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0x18, 0x00
DB      0x03, 0x1F, 0xFF, 0xFE, 0xE6, 0xC6, 0xC7, 0xC7, 0xC3, 0x00, 0x00 ; 5
DB      0x0C, 0x0E, 0x0F, 0x07, 0x03, 0x03, 0x07, 0xFE, 0xFC, 0xF8, 0x00
DB      0x1F, 0x7F, 0x7F, 0xE1, 0xC3, 0xC3, 0xE3, 0xF3, 0x71, 0x30, 0x00 ; 6
DB      0xF8, 0xFE, 0xFE, 0x87, 0x03, 0x03, 0x87, 0xFE, 0xFE, 0x78, 0x00
DB      0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0xCF, 0xDF, 0xFC, 0xF0, 0xE0, 0x00 ; 7
DB      0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00
DB      0x3C, 0x7E, 0x7F, 0xE3, 0xC1, 0xC1, 0xE3, 0x7F, 0x7E, 0x3C, 0x00 ; 8
DB      0x3C, 0x7E, 0xFE, 0xC7, 0x83, 0x83, 0xC7, 0xFE, 0x7E, 0x3C, 0x00
DB      0x1E, 0x7F, 0x7F, 0xE1, 0xC0, 0xC0, 0xE1, 0x7F, 0x7F, 0x1F, 0x00 ; 9
DB      0x0C, 0x8E, 0xCF, 0xC7, 0xC3, 0xC3, 0x87, 0xFE, 0xFE, 0xF8, 0x00
DB      0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x00, 0x00 ; =
DB      0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x00, 0x00
DB      0x03, 0x07, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x06, 0x02, 0x00 ; s
DB      0x84, 0xC6, 0xE7, 0xE3, 0xE3, 0x73, 0x73, 0x7F, 0x3E, 0x1C, 0x00
DB      0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0 ; T
DB      0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
DB      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ;
DB      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Deg_C:
DB      0x11, 0x02      ; WxH of deg_C
DB	0x78, 0xFC, 0x84, 0x84, 0xFC, 0x78, 0x00, 0x0F, 0x3F, 0x7F, 0xE0
DB	0xC0, 0x80, 0x80, 0x80, 0xC0, 0xC0
DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0xFC, 0x0E
DB	0x06, 0x02, 0x02, 0x02, 0x06, 0x04

Blank_Arrow:
DB      0x05, 0x01      ; WxH
DB      0x00, 0x00, 0x00, 0x00, 0x00
DB      0x05, 0x01      ; WxH
DB      0x00, 0x00, 0x00, 0x00, 0x00

Left_Arrow:
DB      0x05, 0x01      ; WxH
DB      0x10, 0x38, 0x7C, 0xFE, 0x00

Right_Arrow:
DB      0x05, 0x01      ; WxH
DB      0x00, 0xFE, 0x7C, 0x38, 0x10

Start_Symb:
DB      0x0C, 0x01      ; WxH
DB      0x7E, 0xFF, 0xC3, 0xC3, 0xDB, 0xDB, 0xDB, 0xDB, 0xC3, 0xC3, 0xFF 
DB      0x7E

Pause_Symb:     
DB      0x0C, 0x01      ; WxH
DB      0x00, 0x00, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0x00, 0x00

Rec_Symb:
DB      0x2C, 0x02      ; WxH of "REC"
DB      0xFF, 0xFF, 0xFF, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xFF
DB      0x7F, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE3
DB      0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE0, 0x00, 0x00
DB      0x07, 0x1F, 0x3F, 0x78, 0x70, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0
DB      0x70, 0x78, 0x38, 0x10
DB      0xFF, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0xE0, 0xF0, 0xFC, 0x3F
DB      0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x87
DB      0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x07, 0x00, 0x00
DB      0xE0, 0xF8, 0xFC, 0x1E, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07
DB      0x0E, 0x1E, 0x1C, 0x08

Slash_Symb:
DB      0x06, 0x02      ; WxH of " / "
DB      0x00, 0x00, 0x03, 0x3F, 0xFC, 0xC0
DB      0x03, 0x3F, 0xFC, 0xC0, 0x00, 0x00

Cross_Symb:
DB      0x0C, 0x01      ; WxH 0d "x"
DB      0x00, 0x82, 0xC6, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0xC6, 0x82, 0x00, 0x00

EVEN
Buffer:                                 ; storage for temp data
DW      0                               ; empty buffer upon programming

;---------------------------------------------------------------------------
        COMMON  INTVEC                  ; MSP430 interrupt vectors

        ORG     RESET_VECTOR
        DW      reset                   ; POR, ext. Reset, Watchdog
        
        ORG     USCI_A0_VECTOR          ; USCI_A vector
        DW      UART_ISR
        
        ORG     USCI_B0_VECTOR          ; USCI_B vector
        DW      I2C_ISR        

        ORG     ADC10_VECTOR            ; ADC vector
        DW      ADC10_ISR       

        ORG     TIMER0_A1_VECTOR        ; Timer_A0 vector
        DW      TA0_ISR

        ORG     DMA_VECTOR              ; DMA vector
        DW      DMA_ISR

        ORG     TIMER1_A0_VECTOR        ; CCR0 vector
        DW      CCR0_ISR
        
        ORG     TIMER1_A1_VECTOR        ; Timer_A1 vector
        DW      TA1_ISR

        ORG     PORT1_VECTOR            ; P1 vector
        DW      P1_ISR
        
        ORG     PORT2_VECTOR            ; P2 vector
        DW      P2_ISR
        END

