#include "msp430.h"

BUT         EQU     BIT0                    ; record button
SENS        EQU     BIT0                    ; sensor input
SENS_PWR    EQU     BIT1                    ; sensor power
RXD         EQU     BIT2                    ; UART input
ADIN        EQU     BIT3                    ; ADC input pin
PWR         EQU     BIT4                    ; record LED indicator
PWM         EQU     BIT6                    ; PWM output @ PORT2
CS          EQU     BIT7                    ; memory enable
bittime     EQU     416                     ; 16MHz / 38400 = 416.6

            RSEG    CSTACK                  ; stack segment
            RSEG    DATA16_N                ; data segment
buf         DS      2*8                     ; circular buffer
RxTempData  DS      2
RxData      DS      1
RxBitCnt    DS      1

;----------------------------------------------------------------------------- 
            RSEG    CODE                    
main  
RESET       mov.w   #SFE(CSTACK), SP        ; initialize stack pointer
            mov.w   #WDTPW+WDTHOLD, &WDTCTL ; stop WDT

            ; clock setup
            mov.b   &CALBC1_16MHZ, &BCSCTL1 ; set 16 MHz clock            
            mov.b   &CALDCO_16MHZ, &DCOCTL
            bis.b   #DIVA_2, &BCSCTL1       ; set 1:4 ACLK divider
            mov.b   #2, &BCSCTL2            ; SMCLK=DCO/2
            
            ; ports setup
            clr.b   &P1OUT                  ; disable sensor power  
            bis.b   #BIT7+BUT, &P1REN       ; enable pull-down for MISO & BUT
            mov.b   #0x72, &P1DIR           ; input on P1.7 (MISO), P1.0 1.2 1.3
            bis.b   #ADIN, &ADC10AE0        ; enable analog input
            
            mov.b   #PWM, &P2SEL            ; PWM output for P2.6, GPIO on P2.7
            bis.b   #BIT6+BIT7, &P2DIR      ; configure P2 for output 
 
            ; SPI setup         
            mov.b   #0x81, &USICTL1         ; SPI mode 0
            mov.b   #USISSEL_2, &USICKCTL   ; USI closk setup

            ; timer setup
            mov.w   #TASSEL_2+TACLR, &TACTL ; SMCLK clocks TA 
            mov.w   #OUTMOD_7, &TACCTL1     ; toggle mode

            bis.b   #BIT6, &P1OUT           ; CLK up (needed for SST memory)
            bis.b   #CS, &P2OUT             ; power-up sequence
            bis.b   #PWR, &P1OUT            ; power on
            call    #delay
            
            bit.b   #BUT, &P1IN             ; USB transfer request? 
            jnz     check1                  ; YES - get file 
            bic.b   #PWR, &P1OUT            ; NO - shut down memory
            bic.b   #BIT6, &P1OUT
            bic.b   #CS, &P2OUT             ; and deactivate it            
            jmp     check2
            
check1      bit.b   #BUT, &P1IN             ; wait for button release 
            jnz     $-4                     ; (user plugs-in the USB cord)

            bic.b   #BIT5, &P1OUT           ; CLK down (needed for SST memory)
            bic.b   #PWR, &P1OUT            ; NO - shut down memory
            bic.b   #CS, &P2OUT             ; and deactivate it    
            call    #delay
            
            bit.b   #RXD, &P1IN             ; is UART line up?
            jz      loop                    ; NO 
            call    #receiveFile            ; get file from USB
            jmp     loop                           

check2      mov.w   #ADC10SHT_1+ADC10ON, &ADC10CTL0
            mov.w   #INCH_3, &ADC10CTL1     ; single ADC conversion
            
            bis.w   #ADC10SC+ENC, &ADC10CTL0; start ADC conversion
            bit.w   #ADC10BUSY, &ADC10CTL1  ; wait for end of conversion
            jnz     $-4
            
            bic.w   #ENC, &ADC10CTL0        ; disable ADC 
            clr.w   &ADC10CTL0              ; ADC off
            cmp.w   #256, &ADC10MEM         ; mic record request?
            jl      loop                    ; NO - dive into main loop                     
            call    #record                 ; YES - record sounds from mic
            
loop        bis.b   #SENS_PWR, &P1OUT       ; activate sensor
            bis.b   #SENS, &P1IE            ; enable rising edge interrupt
            clr.b   &P1IES
            clr.b   &P1IFG                  ; clear interrupt flag

            bis.w   #LPM4+GIE, SR           ; wait for PORT1 interrupt 
            clr.b   &P1IE                   ; disable sensor interrupt
            bic.w   #GIE, SR                ; disable interrupts globally
            bic.b   #SENS_PWR, &P1OUT       ; turn off sensor power

            call    #play                   ; play sound

            bis.b   #LFXT1S_2, &BCSCTL3     ; enable VLOCLK oscillator
WDT_loop    mov.w   #WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL, &WDTCTL ; start WDT
            clr.b   &IFG1                   ; clear WDT interrupt flag
            bis.b   #WDTIE, &IE1            ; enable WDT interrupt
            bis.w   #LPM3+GIE, SR           ; wait for WDT timeout
            bic.w   #GIE, SR                ; disable interrupts globally
            mov.w   #WDTPW+WDTHOLD, &WDTCTL ; stop WDT
            
            bis.b   #SENS_PWR, &P1OUT       ; activate sensor
            call    #delay                  ; wait for sensor power to stabilize 
            bit.b   #SENS, &P1IN            ; is water present?
            jz      monitor                 ; NO - keep monitoring
            
            bic.b   #SENS_PWR, &P1OUT       ; YES - turn off sensor power
            call    #play                   ; play sound
            jmp     WDT_loop                ; wait for another check interval
            
monitor     clr.b   &BCSCTL3                ; stop VLOCLK oscillator
            bic.b   #WDTIE, &IE1            ; disable WDT interrupt
            jmp     loop                    ; keep sensor monitoring 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
initMem     bis.b   #BIT6, &P1OUT
            bis.b   #CS, &P2OUT
            call    #delay
            bis.b   #PWR, &P1OUT            ; power on            
            call    #delay
            bic.b   #GIE, SR
            mov.b   #0xEB, &USICTL0         ; configure USI as SPI master
            bic.b   #USISWRST, &USICTL0     ; enable USI module
            bis.b   #USIIE, &USICTL1        ; enable USI interrupt     
            bic.b   #BIT6, &P1OUT 
 
            ; erase flash and set it up for recording
            mov.b   #0x06, &USISRL          ; send WREN command 
            call    #TX_USI8a
            mov.b   #0x50, &USISRL          ; send EWSR command
            call    #TX_USI8a
            mov.w   #0x0100, &USISR         ; send WRSR command 
            call    #TX_USI16            
            
            mov.b   #0x06, &USISRL          ; send WREN command 
            call    #TX_USI8a
            call    #getStatus

            mov.b   #0x60, &USISRL          ; send chip erase command
            call    #TX_USI8a
            call    #wait_4_flash

            mov.b   #0x06, &USISRL          ; send WREN command 
            call    #TX_USI8a
            call    #getStatus
            
            bic.b   #CS, &P2OUT
            mov.b   #0xAF, &USISRL          ; send AAI command
            call    #TX_USI8b
            clr.b   &USISRL               
            call    #TX_USI8b
            clr.b   &USISRL
            call    #TX_USI8b
            ret
            
;-----------------------------------------------------------------------------
receiveFile clr.b   &BCSCTL2                ; SMCLK = MCLK (needed for UART)
            call    #initMem                ; set up flash for recording                 
            clr.b   &USISRL                 ; data address in flash
            call    #TX_USI8b               

            bic.b   #PWM, &P2DIR            ; disable PWM output
            bis.w   #MC_2, &TACTL           ; start timer_A in continuous mode 
            call    #startUART

            ; load the file length in R4:R5
            bis.w   #LPM0+GIE, SR           ; wait for the first byte
            mov.b   &RxData, R4
            mov.b   R4, &USISRL             ; load 1st file len byte to flash
            call    #TX_USI8c            
                        
            bis.w   #LPM0+GIE, SR           ; wait for the second byte
            mov.b   &RxData, R6
            bic.b   #CS, &P2OUT
            mov.b   #0xAF, &USISRL          ; send AAI command
            call    #TX_USI8b               
            mov.b   R6, &USISRL
            call    #TX_USI8c               ; load 2nd file len byte to flash
            swpb    R6
            add.w   R6, R4  
                  
            bis.w   #LPM0+GIE, SR           ; wait for the third byte
            mov.b   &RxData, R5 
            bic.b   #CS, &P2OUT
            mov.b   #0xAF, &USISRL          ; send AAI command
            call    #TX_USI8b
            mov.b   R5, &USISRL
            call    #TX_USI8c               ; load 3rd file len byte to flash
                        
            bis.w   #LPM0+GIE, SR           ; wait for the fourth byte
            mov.b   &RxData, R6             ; we store just 3-byte file length
            swpb    R6                      ; in flash, so do not write this one
            add.w   R6, R5              

rec_loop1   add.w   #-1, R4                 ; decrement counter R4:R5
            jc      $+4
            add.w   #-1, R5                 ; all bytes processed?
            jnc     rec_end                 ; YES - proceed          

            bis.w   #LPM0+GIE, SR           ; wait for the next byte
            bic.b   #CS, &P2OUT
            mov.b   #0xAF, &USISRL          ; send AAI command
            call    #TX_USI8b
            mov.b   &RxData, &USISRL
            call    #TX_USI8c               ; write byte to flash            
            jmp     rec_loop1
         
rec_end     bic.b   #RXD, &P1IE             ; disable P1 interrupt
            bic.w   #MC_2, &TACTL           ; stop timer
            mov.b   #0x04, &USISRL          ; cancel the AAI mode by 
            call    #TX_USI8a               ; sending WRDI command
            call    #getStatus  
            mov.b   #2, &BCSCTL2            ; SMCLK=DCO/2
            jmp     play                    ; control play of received file

;-----------------------------------------------------------------------------
record      mov.w   #SREF_1+ADC10SHT_1+REF2_5V+REFON+ADC10IE+ADC10ON, &ADC10CTL0
            mov.w   #INCH_3+SHS_1+CONSEQ_2, &ADC10CTL1  ; repeated conversions 

            call    #initMem                       
            mov.b   #3, &USISRL             ; data address in flash
            call    #TX_USI8b                                           
            clr.b   &USISRL
            call    #TX_USI8c               ; write fake byte to flash

            mov.b   #14, R9                 ; clear digital filter buffer
            clr.w   buf(R9)
            decd.b  R9
            jge     $-6
            clr.w   R9                      ; init cycle buffer pointer
            clr.w   R8                      ; clear moving sum value
            
            mov.w   #1, R4                  ; initialize samples counter
            clr.w   R5
            clr.b   R12                     ; clear case counter
                       
            bis.w   #ENC, &ADC10CTL0        ; enable ADC conversion 
            mov.w   #0xFF, &TACCR0          ; set PWM frequency 32KHz
            mov.w   #128, &TACCR1           ; set ADC conversion period
            bic.b   #PWM, &P2DIR            ; disable PWM output
            bis.w   #MC_1+TACLR, &TACTL     ; start timer_A in up mode 

            bit.b   #BUT, &P1IN             ; wait for pressing the button 
            jz      $-4 

rec_loop2   bis.w   #LPM0+GIE, SR           ; get conversion in R7

            bic.b   #CS, &P2OUT
            mov.b   #0xAF, &USISRL          ; send AAI command
            call    #TX_USI8b               ; 35 cycles
            mov.b   R7, &USISRL             ; write byte to flash
            call    #TX_USI8c               ; 127 cycles

            inc.w   R4                      ; update samples counter
            jnc     $+4
            inc.w   R5
            
            bit.b   #BUT, &P1IN             ; is button still pressed?
            jnz     rec_loop2               ; YES - write another byte to flash

            bic.w   #ENC, &ADC10CTL0        ; disable ADC conversion (must be
            clr.w   &ADC10CTL0              ;   done before turning ADC off) 
            bic.w   #MC_1, &TACTL           ; stop timer  
                        
            mov.b   #0x04, &USISRL          ; cancel the AAI mode by 
            call    #TX_USI8a               ; sending WRDI command
            call    #getStatus  
            
            mov.b   #0x06, &USISRL          ; send WREN command 
            call    #TX_USI8a
            call    #getStatus            
           
            bic.b   #CS, &P2OUT             ; writing the file length
            mov.b   #0xAF, &USISRL          ; send ADI command again
            call    #TX_USI8b
            clr.b   &USISRL               
            call    #TX_USI8b
            clr.b   &USISRL
            call    #TX_USI8b
            clr.b   &USISRL                 ; data address in flash
            call    #TX_USI8b
            mov.b   R4, &USISRL             ; write LSB of bytes counter
            call    #TX_USI8c
            
            bic.b   #CS, &P2OUT
            mov.b   #0xAF, &USISRL          ; send AAI command
            call    #TX_USI8b
            swpb    R4
            mov.b   R4, &USISRL             ; write MSB of bytes counter
            call    #TX_USI8c 
            
            bic.b   #CS, &P2OUT
            mov.b   #0xAF, &USISRL          ; send AAI command
            call    #TX_USI8b
            mov.b   R5, &USISRL             ; write MSB of bytes counter
            call    #TX_USI8c 
                        
            mov.b   #0x04, &USISRL          ; send WRDI command 
            call    #TX_USI8a
            call    #getStatus 
            jmp     play         
            
;-----------------------------------------------------------------------------
read_mem    bic.b   #GIE, SR
            mov.b   #0xEB, &USICTL0         ; configure USI as SPI master
            bic.b   #USISWRST, &USICTL0     ; enable USI module
            bis.b   #USIIE, &USICTL1        ; enable USI interrupt            
            call    #delay
            bis.b   #PWR, &P1OUT            ; power on            
            call    #delay            
            
            mov.b   #0xAB, &USISRL          ; send RES command in order
            call    #TX_USI16               ; to wake-up memory
            call    #getStatus
            
            bic.b   #CS, &P2OUT
            mov.b   #0x03, &USISRL          ; read command
            call    #TX_USI8b
            clr.b   &USISRL               
            call    #TX_USI8b
            clr.b   &USISRL               
            call    #TX_USI8b
            clr.b   &USISRL               
            call    #TX_USI8b

            clr.w   R7
            clr.w   R8
rd_loop2    call    #RX_USI8                ; read byte
            mov.b   &USISRL, R4
            inc.w   R7
            jmp     rd_loop2

;-----------------------------------------------------------------------------
play        bis.b   #BIT6, &P1OUT
            bis.b   #CS, &P2OUT
            call    #delay
            bis.b   #PWR, &P1OUT            ; power on            
            call    #delay
            bic.b   #GIE, SR
            mov.b   #0xEB, &USICTL0         ; configure USI as SPI master
            bic.b   #USISWRST, &USICTL0     ; enable USI module
            bis.b   #USIIE, &USICTL1        ; enable USI interrupt     
            bic.b   #BIT6, &P1OUT

            mov.b   #0xAB, &USISRL          ; send RES command in order
            call    #TX_USI16               ; to wake-up memory
            call    #getStatus

            bic.w   #CCIFG, &TACCTL1        ; clear interrupt flag
            bis.w   #CCIE, &TACCTL1         ; enable CCR1 interrupt 

            bic.b   #CS, &P2OUT
            mov.b   #0x03, &USISRL          ; read command
            call    #TX_USI8b
            clr.b   &USISRL               
            call    #TX_USI8b
            clr.b   &USISRL               
            call    #TX_USI8b
            clr.b   &USISRL               
            call    #TX_USI8b
                        
            call    #RX_USI8                ; read file length in R4:R5
            mov.b   &USISRL, R4             
            call    #RX_USI8               
            mov.b   &USISRL, R6          
            swpb    R6
            add.w   R6, R4
            call    #RX_USI8                
            mov.b   &USISRL, R5             
                        
            call    #RX_USI8                ; read first byte
            mov.b   &USISRL, R10            ; sample1
            call    #RX_USI8                ; read second byte
            mov.b   &USISRL, R11            ; sample2

            mov.w   #0xFF, &TACCR0          ; set PWM frequency 32KHz
            mov.w   R10, &TACCR1            ; load sample1 to timer
            clr.b   R12                     ; clear case counter
            bis.w   #MC_1+TACLR, &TACTL     ; start timer_A in up mode 
            bis.b   #PWM, &P2DIR            ; enable PWM output

rd_loop     add.w   #-1, R4                 ; decrement counter R4:R5
            jc      $+4
            add.w   #-1, R5
            jnc     end_play
          
            bis.w   #LPM0+GIE, SR           ; wait for CCR1 interrupt
            mov.b   R11, R10                ; update old byte (R10)       
            
            mov.b   #8, &USICNT             ; read next byte in R11
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt
            mov.b   &USISRL, R11
            jmp     rd_loop
      
end_play    bis.b   #CS, &P2OUT             ; stop play
            bic.b   #GIE, SR                ; disable interrupts
            bic.w   #MC_1, &TACTL           ; stop timer
            bic.b   #PWM, &P2DIR            ; disable PWM output
            bic.w   #CCIE, &TACCTL1         ; disable CCR1 interrupt
            bic.b   #RXD, &P1IE             ; disable UART interrupt
            mov.b   #1, &USICTL0            ; deactivate USI
            bic.b   #USIIE, &USICTL1        ; disable USI interrupt
            bic.b   #PWR, &P1OUT            ; power off
            bic.b   #CS, &P2OUT
            ret

;-----------------------------------------------------------------------------
startUART   mov.b   #8, &RxBitCnt           ; receive 8 bits
            clr.w   &TACCTL0                ; config TA for compare mode            
            bis.b   #RXD, &P1IE             ; enable falling edge interrupt at
            mov.b   #RXD, &P1IES            ; RXD pin             
            clr.b   &P1IFG                  ; clear P1 interrupt flags
            ret
            
;-----------------------------------------------------------------------------
delay       mov.w   #5, R5                  ; ~0.1 sec delay
del1        clr.w   R4                      ; for MC @ 16 MHz
del2        dec.w   R4                      
            jnz     del2                        
            dec.w   R5                      
            jnz     del1                      
            ret 
            
;-----------------------------------------------------------------------------
wait_4_flash
            bic.b   #CS, &P2OUT             ; activate memory chip
            mov.b   #5, &USISRL             ; RDSR command
            mov.b   #8, &USICNT
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt 
            nop
            
w4f_loop    clr.b   &USISRL
            mov.b   #8, &USICNT
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt 
            nop            
            bit.b   #BIT0, &USISRL          ; check the BUSY bit
            jnz     w4f_loop
            bis.b   #CS, &P2OUT
            ret

getStatus
            bic.b   #CS, &P2OUT             ; activate memory chip
            mov.b   #5, &USISRH             ; RDSR command
            mov.b   #16+USI16B, &USICNT
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt 
            nop
            bis.b   #CS, &P2OUT
            ret
            
;----------------------------------------------------------------------------- 
RX_USI8     mov.b   #8, &USICNT             ; receive 8 bits
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt
            ret

TX_USI8a    bic.b   #CS, &P2OUT
            mov.b   #8, &USICNT             ; transmit 8 bits  
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt 
            nop
            bis.b   #CS, &P2OUT
            ret

TX_USI8b    
            mov.b   #8, &USICNT             ; transmit 8 bits  
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt 
            nop
            ret

TX_USI8c
            mov.b   #8, &USICNT             ; transmit 8 bits  
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt 
            nop
            bis.b   #CS, &P2OUT
            call    #wait_4_flash
            ret


TX_USI16    bic.b   #CS, &P2OUT
            mov.b   #16+USI16B, &USICNT     ; transmit 16 bits  
            bis.w   #LPM0+GIE, SR           ; wait for USI interrupt 
            nop
            bis.b   #CS, &P2OUT
            call    #wait_4_flash
            ret

;----------------------------------------------------------------------------- 
CCP_ISR     add.w   &TAIV, PC               ; 3: Add Timer_A offset vector
            reti                            ; vector 0 - no source
            jmp     TACCR1_HND              ; 2: vector 2 - TACCR1
            reti                            ; vector 4 - TACCR2
            reti                            ; vector 6 - reserved
            reti                            ; vector 8 - reserved 

TA_HND      bic.w   #CCIFG, &TACCTL1        ; clear TACCR1 IFG
            bis.w   #CCIE, &TACCTL1         ; enable TACCR1 interrupt
            bic.w   #TAIE, &TACTL           ; disable TA interrupt
            reti
            
TACCR1_HND  mov.b   R11, R13                ; 1:
            sub.b   R10, R13                ; 1: R13 = sample differecnce
            cmp.b   #68, R13
            jl      cases                   ; 2: NO - proceed
            bic.w   #TAIFG, &TACTL          ; 4: clear overflow flag TAIFG IFG
            bis.w   #TAIE, &TACTL           ; 4: enable overflow interrupt TAIFG
            bic.w   #CCIE, &TACCTL1         ; 5: disable TACCR1 interrupt   
   
cases       incd.b  R12                     ; 1: R12 += 2
            and.b   #6, R12                 ; 2: take R12 mod 7
            add.w   R12, PC                 ; 2: check cases     
            jmp     case6
            jmp     case0                   ; 2:
            jmp     case2
            jmp     case4

case0       mov.b   R10, R13
            add.w   R10, R13
            add.w   R10, R13
            add.w   R11, R13
            rra.w   R13
            rra.w   R13                     ; 6: R13 = (sample1*3 + sample2)/4
            mov.w   R13, &TACCR1            ; 4:
            bic.w   #CCIFG, &TACCTL1        ; clear TACCR1 IFG
            reti
            
case2       mov.b   R10, R13 
            add.w   R10, R13
            add.w   R11, R13
            add.w   R11, R13
            rra.w   R13
            rra.w   R13                     ; R13 = (sample1 + sample2)/2
            mov.w   R13, &TACCR1
            bic.w   #CCIFG, &TACCTL1        ; clear TACCR1 IFG
            reti
            
case4       mov.b   R11, R13
            add.w   R11, R13
            add.w   R11, R13
            add.w   R10, R13           
            rra.w   R13
            rra.w   R13                     ; R13 = (sample1 + sample2*3)/4
            mov.w   R13, &TACCR1
            bic.w   #CCIFG, &TACCTL1        ; clear TACCR1 IFG
            reti

case6       jmp     $+2                     ; 6 cycles delay to equate
            jmp     $+2                     ; setting the new PWM value
            jmp     $+2                     ; in all cases
            mov.w   R11, &TACCR1            ; load sample2
            bic.w   #LPM4, 0(SP)            ; keep CPU active
            bic.w   #CCIFG, &TACCTL1        ; clear TACCR1 IFG
            reti

;---------------------------------------------------------------------------
USI_ISR     bic.b   #USIIFG, &USICTL1       ; clear IF
            bic.w   #LPM0, 0(SP)            ; keep CPU active
            reti

;-----------------------------------------------------------------------------
RX_ISR                                      ; RX ISR            
            add.w   #bittime, &TACCR0       ; next capture time

getBit      rra.b   &RxTempData             ; get bit from UART receiver
            bic.b   #BIT7, &RxTempData      ; make it a 0 in data
            bit.b   #RXD, P1IN              ; if the received bit is 1
            jz      $+8
             bis.b  #BIT7, &RxTempData      ; make it a 1 in data
             
            dec.b   &RxBitCnt               ; update the bit counter
            jnz     rx_end                  ; all 8 bits received?
            
            mov.b   &RxTempData, &RxData    ; YES - save the received data
            call    #startUART              ; prepare for the next byte

            bic.w   #LPM4, 0(SP)            ; keep CPU active
rx_end      reti
            
;---------------------------------------------------------------------------
ADC_ISR     sub.w   buf(R9), R8             ; update R8 - sum of buffer
            mov.w   &ADC10MEM, buf(R9)      ; process the new ADC value
            add.w   &ADC10MEM, R8           ; update the moving sum
            incd.b  R9                      ; update cycle buffer pointer
            and.b   #15, R9  

            inc.b   R12                     ; increment sample number mod 4
            and.b   #0x3, R12
            jz      $+4
            reti
            
            mov.w   R8, R7                  ; return every fourth sample in R7
            rra     R7
            rra     R7
            rra     R7         
            rra     R7
            rra     R7                      ; R7 is 8-bit value        
            bic.w   #LPM0, 0(SP)            ; keep CPU active
            reti

;---------------------------------------------------------------------------
P1_ISR      mov.w   &TAR, &TACCR0           ; get current time stamp
            add.w   #bittime+bittime/2, &TACCR0 ; next sample capture time
            bis.w   #CCIE, &TACCTL0         ; enable TA0 compare interrupts

            bit.b   #SENS, &P1IFG           ; is interrupt triggered by sensor?
            jz      P1_end                  ; NO - proceed
            bic.w   #CCIE, &TACCTL0         ; YES - disable TA0 interrupts      
            bic.w   #LPM4, 0(SP)            ; keep CPU active

P1_end      clr.b   &P1IFG                  ; clear IF
            clr.b   &P1IE                   ; disable P1 interrupt
            reti

;---------------------------------------------------------------------------
WDT_ISR     bic.w   #LPM3, 0(SP)            ; keep CPU active
            reti

;---------------------------------------------------------------------------
            COMMON  INTVEC                  ; MSP430F2012 interrupt vectors

            ORG     RESET_VECTOR
            DW      RESET                   ; POR, ext. Reset, Watchdog

            ORG     WDT_VECTOR
            DW      WDT_ISR

            ORG     TIMERA0_VECTOR
            DW      RX_ISR
            
            ORG     TIMERA1_VECTOR
            DW      CCP_ISR                 ; CCIFG1 interrupt
            
            ORG     USI_VECTOR
            DW      USI_ISR
            
            ORG     ADC10_VECTOR
            DW      ADC_ISR

            ORG     PORT1_VECTOR
            DW      P1_ISR

            END 