;-------------------------------------------
; DCO CALIBRATION SUBROUTINE
;
; LAST MODIFIED: 13.04.2002
;
; DISCLAIMER:
; This software is provided "as is" for evaluation of our MSP430-1121STK
; development board. You are free to use this code in your projects, but 
; without warranty of any kind. If you can't understand how and what the 
; code does it's better to start by learning the MSP430 datasheets, and 
; assembly language, but don't call OLIMEX with questions regarding this 
; software. OLIMEX will not teach you how to write assembly language nor 
; how to use MSP430 peripherials, there is plenty of datasheets about them.
;
; (C) 2002 OLIMEX Ltd, All rights reserved
;-------------------------------------------------------------------------

#define     DCO_TR0   R9                    /* temprary registers for DCO   */
#define     DCO_TR1   R10                   /* calibration                  */
#define     Delta     150                   /* DCO 150*32768/4            */

;--------------------------------------------
; Calibrate DCO to 1228800 Hz (150*32768/4)
;--------------------------------------------
Delay       push    #0FFFFh                 ;Delay to top of stack
L1          dec     0(SP)                   ;Decrement value on top of stack
            jnz     L1                      ;Loop if value not = 0
            incd    SP                      ;Clean top of stack
            ret                             ;
;--------------------------------------------
Set_DCO     clr     DCO_TR0                 ;Clear register
Setup_CC2   mov     #CCIS0+CM0+CAP,&CCTL2   ;Define CCR2=ACLK,CAP mode,pos. edge
Test_DCO    bit     #CCIFG,&CCTL2           ;Test flag, capture occured?
            jz      Test_DCO                ;No, loop until captured
            bic     #CCIFG,&CCTL2           ;Yes, clear interrupt flag
AdjDCO      mov     &CCR2,DCO_TR0           ;Move captured SMCLK to DCO_TR0
            sub     DCO_TR1,DCO_TR0         ;SMCLK difference into DCO_TR0
            mov     &CCR2,DCO_TR1           ;Save SMCLK to DCO_TR1 in case another loop
                                            ;is needed to complete calibration
            cmp     #Delta,DCO_TR0          ;Delta = SMCLK/(32768/4)?
            jlo     IncDCO                  ;Jump if lower to increment DCO
            jeq     DoneDCO                 ;Jump if equal to done
DecDCO      dec.b   &DCOCTL                 ;If neither, then decrement DCO 
            jmp     Test_DCO                ;Loop to test again
IncDCO      inc.b   &DCOCTL                 ;Increment DCO speed
            jmp     Test_DCO                ;Loop to test again 
DoneDCO     clr     &CCTL2                  ;Calibration complete stop CCR2 
            ret                             ;
