#include  "msp430x12x.h"
;******************************************************************************
;   MSP-FET430P120 Demo - USART0 UART 19200 Ultra-low Echo ISR, 32kHz ACLK+DCO
;
;   Description; Echo a received character, USART0 RX ISR at high-speed used 
;   with ultra-low power techniques. Normal operation in LPM3, Set_DCO 
;   subroutine needs to be called to stabalizes DCO used for UART baud 
;   generation. On valid RX character, character echoed  back. Use start-bit 
;   edge detect - URXSE - to automatically (re)enable DCO and trigger ISR. ISR
;   must insure a clock source (DCO remains enabled for the UART to receive 
;   full character. Software needs to insure character has been completely 
;   TX'ed before entering LPM3, which disables DCO.  
;   ACLK = LFXT1/8 = 32768/8,  MCLK = SMCLK = UCLK0 = DCOCLK  = 1048576
;   Baud rate divider with 1048576hz = 1048576Hz/19200 ~ 55 (0036h)
;   //*An external 32kHz watch crystal on XIN XOUT is required for ACLK*//	  
;
Delta   equ   256    ; Delta = (target DCO)/(4096) = 1048576
;              
;                MSP430F123(2)
;             -----------------
;         /|\|              XIN|-  
;          | |                 | 32768Hz  
;          --|RST          XOUT|-
;            |                 |
;            |             P3.4|------------> 
;            |                 |  19200 - 8N1
;            |             P3.5|<------------
;
;    M.Buccini
;    Texas Instruments, Inc
;    February 2002
;******************************************************************************
;------------------------------------------------------------------------------ 
            ORG     0E000h                  ; Program Start
;------------------------------------------------------------------------------ 
RESET       mov.w   #0300h,SP               ; Initialize stackpointer
            call    #Init_Sys               ;
                                            ;
Mainloop    bit.b   #TXEPT,&UTCTL0          ; Confirm no TXing before --> LPM3 
            jz      Mainloop                ;
            bis.b   #LPM3,SR                ; Enter LPM3
            jmp     Mainloop                ;            
                                            ;
;------------------------------------------------------------------------------ 
Init_Sys;   Initalize MSP430 system
;------------------------------------------------------------------------------ 
StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT
SetupBC     bis.b   #DIVA1+DIVA0,&BCSCTL1   ; ACLK = LFXT1CLK/8 
            call    #Set_DCO                ; Calibrate DCOCLK
SetupUART0  mov.b   #CHAR,&UCTL0            ; 8-bit char
            mov.b   #SSEL1+URXSE,&UTCTL0    ; UCLK = SMCLK, start edge detect
            mov.b   #036h,&UBR00            ; 1MHz 19200 
            mov.b   #000h,&UBR10            ; 1MHz 19200
            mov.b   #000h,&UMCTL0           ; 1MHz 19200 modulation 
            bis.b   #UTXE0+URXE0,&ME2       ; Enable USART0 TXD/RXD
            bis.b   #URXIE0,&IE2            ; Enable USART0 RX interrupt
SetupP3     bis.b   #030h,&P3SEL            ; P3.4,5 = USART0 TXD/RXD
            bis.b   #010h,&P3DIR            ; P3.4 = output direction 
            eint                            ; General enable interrupts
            ret                             ; Return from subroutine
                                            ;             
;----------------------------------------------------------------------------- 
Set_DCO;    Subroutine: Sets DCO to selected frequency based on Delta.
;           R14 and R15 are used, ACLK= 32768/8 Timer_A clocked by DCOCLK
;----------------------------------------------------------------------------- 
            clr.w   R15                     ;							
Setup_TA    mov.w   #TASSEL1+TACLR+MC1,&TACTL   ; SMCLK, clear, cont. mode
Setup_CC2   mov.w   #CCIS0+CM0+CAP,&CCTL2   ; Define CCR2,CAP,ACLK									
Test_DCO    bit.w   #CCIFG,&CCTL2           ; Test capture flag
            jz      Test_DCO                ;
            bic.w   #CCIFG,&CCTL2           ; Clear capture flag
                                            ;
AdjDCO      mov.w   &CCR2,R14               ; R14 = captured SMCLK
            sub.w   R15,R14                 ; R14 = capture difference
            mov.w   &CCR2,R15               ; R15 = captured SMCLK
            cmp.w   #Delta,R14              ; Delta = SMCLK/(32768/4)
            jlo     IncDCO                  ;
            jeq     DoneDCO                 ;
DecDCO      dec.b   &DCOCTL                 ; Slow DCO with DCO and MOD
            jnz     Test_DCO                ; Slower?
            bit.b   #07h,&BCSCTL1           ; Can RSEL.x be decremented?
            jz      DoneDCO                 ; jmp>DCO at slowest setting
            dec.b   &BCSCTL1                ; Decrement RSEL.x 
            jmp     Test_DCO                ;
IncDCO      inc.b   &DCOCTL                 ; Speed DCO with DCO and MOD
            jnc     Test_DCO                ; Faster?
            cmp.b   #07h,&BCSCTL1           ; Can RSEL.x be increased?
            jz      DoneDCO                 ; jmp> DCO at fastest settting
            inc.b   &BCSCTL1                ; Increment RSEL.x
            jmp     Test_DCO                ;
DoneDCO     clr.w   &CCTL2                  ; Stop CCR2
            clr.w   &TACTL                  ; Stop timer_A
            ret                             ; Return from subroutine
                                            ;
;------------------------------------------------------------------------------ 
USART0RX_ISR;  Echo back RXed character, confirm TX buffer is ready first
;------------------------------------------------------------------------------ 
            bit.b   #URXIFG0,&IFG2          ; Interrupt from complete char?
            jc      TX1                     ; Jump--> interrupt from char
            bic.b   #SCG1+SCG0,0(SP)        ; Enter LPM0 on reti
            reti                            ; 
                                            ;   
TX1         bit.b   #UTXIFG0,&IFG2          ; USART0 TX buffer ready?
            jz      TX1                     ; Jump is TX buffer not ready
            mov.b   &RXBUF0,&TXBUF0         ; TX -> RXed character
            bic.b   #LPM3,0(SP)             ; Exit LPM3 on reti
            reti                            ; 
                                            ;
;------------------------------------------------------------------------------ 
;           Interrupt Vectors Used MSP430x12x        
;------------------------------------------------------------------------------ 
            ORG     0FFFEh                  ; 
            DW      RESET                   ; POR, ext. Reset, Watchdog
            ORG     0FFEEh                  ; 
            DW      USART0RX_ISR            ; USART0 receive
            end