Part Number: MSP430F67791A
Tool/software: Code Composer Studio
Dear sir,
P1SEL0 |= BIT2; // P1.2 for debugging purposes.
UCSCTL6 &= ~(XT1OFF); // XT1 On
UCSCTL6 |= XCAP_3; // Internal load cap
{
//Clear OSC flaut Flags
HWREG8(UCS_BASE + OFS_UCSCTL7_L) &= ~(DCOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
#include <msp430.h>
void delay(unsigned int j)
{
unsigned int i;
for(i=0; i<=j; i++)
{
__delay_cycles(50000); __delay_cycles(50000);
}
}
void UART_init()
{
// Setup P3.0 UCA0RXD, P3.1 UCA0TXD
P3SEL0 |= BIT0 | BIT1; // Set P3.0, P3.1 to non-IO
P3DIR |= BIT0 | BIT1; // Enable UCA0RXD, UCA0TXD
P1DIR |= BIT2; // ACLK set out to pin
P1SEL0 |= BIT2; // P1.2 for debugging purposes.
// Setup LFXT1
UCSCTL6 &= ~(XT1OFF); // XT1 On
UCSCTL6 |= XCAP_3; // Internal load cap
// Setup eUSCI_A0
UCA0CTLW0 |= UCSWRST; // **Put state machine in reset**
UCA0CTLW0 |= UCSSEL_1; // CLK = ACLK
UCA0BRW_L = 0x03; // 32kHz/9600=3.41 (see User's Guide)
UCA0BRW_H = 0x00; //
UCA0MCTLW = 0x5300; // Modulation UCBRSx=0x53, UCBRFx=0
UCA0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
// UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
}
void UART_Tx(unsigned char a)
{
while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = a;
}
unsigned char UART_Rx()
{
unsigned char rx;
rx = UCA0RXBUF;
while (!(UCA0IFG & UCRXIFG)); // USCI_A0 TX buffer ready?
return rx;
}
void UART_Str(unsigned char *a)
{
while(*a!='\0')
{
UART_Tx(*a);
a++;
}
}
void main(void)
{
unsigned char read;
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
UART_init();
while(1)
{
UART_Str("EMDC...");
}
}
#include <stdint.h>
#include "hal.h"
#include "hmi.h"
#include "EMLibGUIApp.h"
#include "EM_userConfig.h"
/*** FUNCTIONS ***/
static void MSP_GUI_System_setup(void);
//*****************************************************************************
//
//! In this software main will call a few initialization routines and then it
//! will jump to the main loop for the Energy Measurement Library.
//!
//! \return none
//
// *****************************************************************************
void main(void)
{
MSP_GUI_System_setup();
// Initialize the EM Lib to default settings and start conversions
EMLibGUIApp_Init();
// This is the Design Centers Main Loop
EMLibGUIApp_Engine();
}
//*****************************************************************************
//
//! This Function Initializes all the ports on the MCU
//!
//! \return none
//
// *****************************************************************************
static void MSP_GUI_System_setup(void)
{
// Stop WDT
WDTCTL = WDTPW + WDTHOLD;
// Initializes the basic functionality of the system
hal_system_Init();
// Initialize interfaces to user including GUI
HMI_Init();
}
#include "inc/hw_memmap.h"
#if defined(__MSP430_HAS_UCS__) || defined(__MSP430_HAS_UCS_RF__)
#include "ucs.h"
#include <assert.h>
#ifdef __GNUC__
#define __delay_cycles(x) \
({ \
volatile unsigned int j; \
for(j = 0; j < x; j++) \
{ \
__no_operation(); \
} \
})
#endif
#define CC430_DEVICE (defined (__CC430F5133__) || defined(__CC430F5135__) || \
defined(__CC430F5137__) || \
defined(__CC430F6125__) || defined(__CC430F6126__) || \
defined(__CC430F6127__) || \
defined(__CC430F6135__) || defined(__CC430F6137__) || \
defined(__CC430F5123__) || \
defined(__CC430F5125__) || defined(__CC430F5143__) || \
defined(__CC430F5145__) || \
defined(__CC430F5147__) || defined(__CC430F6143__) || \
defined(__CC430F6145__) || \
defined(__CC430F6147__))
#define NOT_CC430_DEVICE (!defined (__CC430F5133__) && \
!defined(__CC430F5135__) && \
!defined(__CC430F5137__) && \
!defined(__CC430F6125__) && \
!defined(__CC430F6126__) && \
!defined(__CC430F6127__) && \
!defined(__CC430F6135__) && \
!defined(__CC430F6137__) && \
!defined(__CC430F5123__) && \
!defined(__CC430F5125__) && \
!defined(__CC430F5143__) && \
!defined(__CC430F5145__) && \
!defined(__CC430F5147__) && \
!defined(__CC430F6143__) && \
!defined(__CC430F6145__) && \
!defined(__CC430F6147__))
//******************************************************************************
//
// The XT1 crystal frequency. Should be set with
// UCS_setExternalClockSource if XT1 is used and user intends to
// invoke UCS_getSMCLK, UCS_getMCLK or UCS_getACLK
//
//******************************************************************************
static uint32_t privateXT1ClockFrequency = 0;
//******************************************************************************
//
// The XT2 crystal frequency. Should be set with
// UCS_setExternalClockSource if XT1 is used and user intends to invoke
// UCS_getSMCLK, UCS_getMCLK or UCS_getACLK
//
//******************************************************************************
static uint32_t privateXT2ClockFrequency = 0;
static uint32_t privateUCSSourceClockFromDCO(uint16_t FLLRefCLKSource)
{
assert((SELM__DCOCLKDIV == FLLRefCLKSource) ||
(SELM__DCOCLK == FLLRefCLKSource)
);
uint16_t D_value = 1;
uint16_t N_value;
uint16_t n_value = 1;
uint32_t Fref_value;
uint8_t i;
N_value = (HWREG16(UCS_BASE + OFS_UCSCTL2)) & 0x03FF;
uint16_t tempDivider = HWREG8(UCS_BASE + OFS_UCSCTL3) & FLLREFDIV_7;
if(tempDivider < 4)
{
n_value <<= tempDivider;
}
else if(tempDivider == 4)
{
n_value = 12;
}
else if(tempDivider == 5)
{
n_value = 16;
}
switch((HWREG8(UCS_BASE + OFS_UCSCTL3)) & SELREF_7)
{
case SELREF__XT1CLK:
Fref_value = privateXT1ClockFrequency;
if(XTS != (HWREG16(UCS_BASE + OFS_UCSCTL6) & XTS))
{
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG)
{
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG)
{
Fref_value = UCS_REFOCLK_FREQUENCY;
}
}
}
else
{
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1HFOFFG)
{
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1HFOFFG)
{
Fref_value = UCS_REFOCLK_FREQUENCY;
}
}
}
break;
case SELREF__REFOCLK:
Fref_value = UCS_REFOCLK_FREQUENCY;
break;
case SELREF__XT2CLK:
Fref_value = privateXT2ClockFrequency;
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG)
{
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG)
{
Fref_value = UCS_REFOCLK_FREQUENCY;
}
}
break;
default: assert(0);
}
uint32_t CLKFrequency = Fref_value * (N_value + 1) / n_value;
if(SELM__DCOCLK == FLLRefCLKSource)
{
tempDivider = (HWREG16(UCS_BASE + OFS_UCSCTL2)) & FLLD_7;
tempDivider = tempDivider >> 12;
for(i = 0; i < tempDivider; i++)
{
D_value = D_value * 2;
}
CLKFrequency *= D_value;
}
return (CLKFrequency);
}
static uint32_t privateUCSComputeCLKFrequency(uint16_t CLKSource,
uint16_t CLKSourceDivider)
{
uint32_t CLKFrequency;
uint8_t CLKSourceFrequencyDivider = 1;
uint8_t i = 0;
for(i = 0; i < CLKSourceDivider; i++)
{
CLKSourceFrequencyDivider *= 2;
}
switch(CLKSource)
{
case SELM__XT1CLK:
CLKFrequency = (privateXT1ClockFrequency /
CLKSourceFrequencyDivider);
if(XTS != (HWREG16(UCS_BASE + OFS_UCSCTL6) & XTS))
{
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG)
{
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG)
{
CLKFrequency = UCS_REFOCLK_FREQUENCY;
}
}
}
else
{
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1HFOFFG)
{
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1HFOFFG)
{
CLKFrequency = UCS_REFOCLK_FREQUENCY;
}
}
}
break;
case SELM__VLOCLK:
CLKFrequency =
(UCS_VLOCLK_FREQUENCY / CLKSourceFrequencyDivider);
break;
case SELM__REFOCLK:
CLKFrequency =
(UCS_REFOCLK_FREQUENCY / CLKSourceFrequencyDivider);
break;
case SELM__XT2CLK:
CLKFrequency =
(privateXT2ClockFrequency / CLKSourceFrequencyDivider);
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG)
{
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~XT2OFFG;
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
if(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG)
{
CLKFrequency =
privateUCSSourceClockFromDCO(SELM__DCOCLKDIV);
}
break;
case SELM__DCOCLK:
case SELM__DCOCLKDIV:
CLKFrequency = privateUCSSourceClockFromDCO(
CLKSource) / CLKSourceFrequencyDivider;
break;
}
return (CLKFrequency);
}
void UCS_setExternalClockSource(uint32_t XT1CLK_frequency,
uint32_t XT2CLK_frequency)
{
privateXT1ClockFrequency = XT1CLK_frequency;
privateXT2ClockFrequency = XT2CLK_frequency;
}
void UCS_initClockSignal(uint8_t selectedClockSignal,
uint16_t clockSource,
uint16_t clockSourceDivider)
{
assert(
(UCS_XT1CLK_SELECT == clockSource) ||
(UCS_VLOCLK_SELECT == clockSource) ||
(UCS_REFOCLK_SELECT == clockSource) ||
(UCS_DCOCLK_SELECT == clockSource) ||
(UCS_DCOCLKDIV_SELECT == clockSource) ||
(UCS_XT2CLK_SELECT == clockSource)
);
assert(
(UCS_CLOCK_DIVIDER_1 == clockSourceDivider) ||
(UCS_CLOCK_DIVIDER_2 == clockSourceDivider) ||
(UCS_CLOCK_DIVIDER_4 == clockSourceDivider) ||
(UCS_CLOCK_DIVIDER_8 == clockSourceDivider) ||
(UCS_CLOCK_DIVIDER_16 == clockSourceDivider) ||
(UCS_CLOCK_DIVIDER_32 == clockSourceDivider)
);
uint16_t temp = HWREG16(UCS_BASE + OFS_UCSCTL5);
switch(selectedClockSignal)
{
case UCS_ACLK:
HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELA_7);
clockSource = clockSource << 8;
HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);
clockSourceDivider = clockSourceDivider << 8;
HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVA_7) | clockSourceDivider;
break;
case UCS_SMCLK:
HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELS_7);
clockSource = clockSource << 4;
HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);
clockSourceDivider = clockSourceDivider << 4;
HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVS_7) | clockSourceDivider;
break;
case UCS_MCLK:
HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7);
HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);
HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVM_7) | clockSourceDivider;
break;
case UCS_FLLREF:
assert(clockSource <= SELA_5);
HWREG8(UCS_BASE + OFS_UCSCTL3) &= ~(SELREF_7);
clockSource = clockSource << 4;
HWREG8(UCS_BASE + OFS_UCSCTL3) |= (clockSource);
temp = HWREG8(UCS_BASE + OFS_UCSCTL3) & 0x00FF;
//Note that dividers for FLLREF are slightly different
//Hence handled differently from other CLK signals
switch(clockSourceDivider)
{
case UCS_CLOCK_DIVIDER_12:
HWREG8(UCS_BASE +
OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | FLLREFDIV__12;
break;
case UCS_CLOCK_DIVIDER_16:
HWREG8(UCS_BASE +
OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | FLLREFDIV__16;
break;
default:
HWREG8(UCS_BASE +
OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | clockSourceDivider;
break;
}
break;
}
}
void UCS_turnOnLFXT1(uint16_t xt1drive,
uint8_t xcap)
{
assert((xcap == UCS_XCAP_0) ||
(xcap == UCS_XCAP_1) ||
(xcap == UCS_XCAP_2) ||
(xcap == UCS_XCAP_3));
assert((xt1drive == UCS_XT1_DRIVE_0) ||
(xt1drive == UCS_XT1_DRIVE_1) ||
(xt1drive == UCS_XT1_DRIVE_2) ||
(xt1drive == UCS_XT1_DRIVE_3));
//Switch ON XT1 oscillator
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1OFF;
//Highest drive setting for XT1startup
HWREG16(UCS_BASE + OFS_UCSCTL6_L) |= XT1DRIVE1_L + XT1DRIVE0_L;
//Enable LF mode and clear xcap and bypass
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~(XTS + XCAP_3 + XT1BYPASS);
HWREG16(UCS_BASE + OFS_UCSCTL6) |= xcap;
while(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG)
{
//Clear OSC flaut Flags fault flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
//set requested Drive mode
HWREG16(UCS_BASE + OFS_UCSCTL6) = (HWREG16(UCS_BASE + OFS_UCSCTL6) &
~(XT1DRIVE_3)
) |
(xt1drive);
}
void UCS_turnOnHFXT1(uint16_t xt1drive)
{
//Switch ON XT1 oscillator
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1OFF;
//Check if drive value is the expected one
if((HWREG16(UCS_BASE + OFS_UCSCTL6) & XT1DRIVE_3) != xt1drive)
{
//Clear XT1drive field
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1DRIVE_3;
//Set requested value
HWREG16(UCS_BASE + OFS_UCSCTL6) |= xt1drive;
}
//Enable HF mode
HWREG16(UCS_BASE + OFS_UCSCTL6) |= XTS;
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1BYPASS;
// Check XT1 fault flags
while((HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1HFOFFG)))
{
//Clear OSC flaut Flags fault flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
}
void UCS_bypassXT1(uint8_t highOrLowFrequency)
{
assert((UCS_XT1_LOW_FREQUENCY == highOrLowFrequency) ||
(UCS_XT1_HIGH_FREQUENCY == highOrLowFrequency)
);
//Enable HF/LF mode
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XTS;
HWREG16(UCS_BASE + OFS_UCSCTL6) |= highOrLowFrequency;
//Switch OFF XT1 oscillator and enable BYPASS mode
HWREG16(UCS_BASE + OFS_UCSCTL6) |= (XT1BYPASS + XT1OFF);
if(UCS_XT1_LOW_FREQUENCY == highOrLowFrequency)
{
while(HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1LFOFFG))
{
//Clear OSC flaut Flags fault flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
// Clear the global fault flag. In case the XT1 caused the global fault
// flag to get set this will clear the global error condition. If any
// error condition persists, global flag will get again.
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
}
else
{
while(HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1HFOFFG))
{
//Clear OSC flaut Flags fault flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
//Clear the global fault flag. In case the XT1 caused the global fault
//flag to get set this will clear the global error condition. If any
//error condition persists, global flag will get again.
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
}
}
bool UCS_turnOnLFXT1WithTimeout(uint16_t xt1drive,
uint8_t xcap,
uint16_t timeout)
{
assert((xcap == UCS_XCAP_0) ||
(xcap == UCS_XCAP_1) ||
(xcap == UCS_XCAP_2) ||
(xcap == UCS_XCAP_3));
assert((xt1drive == UCS_XT1_DRIVE_0) ||
(xt1drive == UCS_XT1_DRIVE_1) ||
(xt1drive == UCS_XT1_DRIVE_2) ||
(xt1drive == UCS_XT1_DRIVE_3));
assert(timeout > 0);
//Switch ON XT1 oscillator
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1OFF;
//Highest drive setting for XT1startup
HWREG16(UCS_BASE + OFS_UCSCTL6_L) |= XT1DRIVE1_L + XT1DRIVE0_L;
//Enable LF mode and clear xcap and bypass
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~(XTS + XCAP_3 + XT1BYPASS);
HWREG16(UCS_BASE + OFS_UCSCTL6) |= xcap;
do
{
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
while((HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG) && --timeout);
if(timeout)
{
//set requested Drive mode
HWREG16(UCS_BASE + OFS_UCSCTL6) = (HWREG16(UCS_BASE + OFS_UCSCTL6) &
~(XT1DRIVE_3)
) |
(xt1drive);
return (STATUS_SUCCESS);
}
else
{
return (STATUS_FAIL);
}
}
bool UCS_turnOnHFXT1WithTimeout(uint16_t xt1drive,
uint16_t timeout)
{
assert((xt1drive == UCS_XT1_DRIVE_0) ||
(xt1drive == UCS_XT1_DRIVE_1) ||
(xt1drive == UCS_XT1_DRIVE_2) ||
(xt1drive == UCS_XT1_DRIVE_3));
assert(timeout > 0);
//Switch ON XT1 oscillator
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1OFF;
//Check if drive value is the expected one
if((HWREG16(UCS_BASE + OFS_UCSCTL6) & XT1DRIVE_3) != xt1drive)
{
//Clear XT1drive field
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1DRIVE_3;
//Set requested value
HWREG16(UCS_BASE + OFS_UCSCTL6) |= xt1drive;
}
//Enable HF mode
HWREG16(UCS_BASE + OFS_UCSCTL6) |= XTS;
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1BYPASS;
// Check XT1 fault flags
do
{
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
while((HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1HFOFFG))
&& --timeout);
if(timeout)
{
return (STATUS_SUCCESS);
}
else
{
return (STATUS_FAIL);
}
}
bool UCS_bypassXT1WithTimeout(uint8_t highOrLowFrequency,
uint16_t timeout)
{
assert((UCS_XT1_LOW_FREQUENCY == highOrLowFrequency) ||
(UCS_XT1_HIGH_FREQUENCY == highOrLowFrequency)
);
assert(timeout > 0);
//Enable HF/LF mode
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XTS;
HWREG16(UCS_BASE + OFS_UCSCTL6) |= highOrLowFrequency;
//Switch OFF XT1 oscillator and enable bypass
HWREG16(UCS_BASE + OFS_UCSCTL6) |= (XT1BYPASS + XT1OFF);
if(UCS_XT1_LOW_FREQUENCY == highOrLowFrequency)
{
do
{
//Clear OSC flaut Flags fault flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
// Clear the global fault flag. In case the XT1 caused the global fault
// flag to get set this will clear the global error condition. If any
// error condition persists, global flag will get again.
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
while((HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1LFOFFG)) && --timeout);
}
else
{
do
{
//Clear OSC flaut Flags fault flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
//Clear the global fault flag. In case the XT1 caused the global fault
//flag to get set this will clear the global error condition. If any
//error condition persists, global flag will get again.
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
while((HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1HFOFFG))&& --timeout);
}
if(timeout)
{
return (STATUS_SUCCESS);
}
else
{
return (STATUS_FAIL);
}
}
void UCS_turnOffXT1(void)
{
//Switch off XT1 oscillator
HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT1OFF;
}
void UCS_turnOnXT2(uint16_t xt2drive)
{
#if NOT_CC430_DEVICE
//Check if drive value is the expected one
if((HWREG16(UCS_BASE + OFS_UCSCTL6) & XT2DRIVE_3) != xt2drive)
{
//Clear XT2drive field
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2DRIVE_3;
//Set requested value
HWREG16(UCS_BASE + OFS_UCSCTL6) |= xt2drive;
}
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2BYPASS;
#endif
//Enable XT2 and Switch on XT2 oscillator
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2OFF;
while(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG)
{
//Clear OSC flaut Flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
#if CC430_DEVICE
// CC430 uses a different fault mechanism. It requires 3 VLO clock
// cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
// case.
__delay_cycles(5000);
#endif
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
}
void UCS_bypassXT2(void)
{
//Switch on XT2 oscillator
#if NOT_CC430_DEVICE
HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2BYPASS;
#endif
HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2OFF;
while(HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG)
{
//Clear OSC flaut Flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
#if CC430_DEVICE
// CC430 uses a different fault mechanism. It requires 3 VLO clock
// cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
// case.
__delay_cycles(5000);
#endif
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
}
bool UCS_turnOnXT2WithTimeout(uint16_t xt2drive,
uint16_t timeout)
{
assert(timeout > 0);
#if NOT_CC430_DEVICE
//Check if drive value is the expected one
if((HWREG16(UCS_BASE + OFS_UCSCTL6) & XT2DRIVE_3) != xt2drive)
{
//Clear XT2drive field
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2DRIVE_3;
//Set requested value
HWREG16(UCS_BASE + OFS_UCSCTL6) |= xt2drive;
}
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2BYPASS;
#endif
//Switch on XT2 oscillator
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2OFF;
do
{
//Clear OSC flaut Flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
#if CC430_DEVICE
// CC430 uses a different fault mechanism. It requires 3 VLO clock
// cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
// case.
__delay_cycles(5000);
#endif
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
while((HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG) && --timeout);
if(timeout)
{
return (STATUS_SUCCESS);
}
else
{
return (STATUS_FAIL);
}
}
bool UCS_bypassXT2WithTimeout(uint16_t timeout)
{
assert(timeout > 0);
//Switch off XT2 oscillator and enable BYPASS mode
#if NOT_CC430_DEVICE
HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2BYPASS;
#endif
HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2OFF;
do
{
//Clear OSC flaut Flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
#if CC430_DEVICE
// CC430 uses a different fault mechanism. It requires 3 VLO clock
// cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
// case.
__delay_cycles(5000);
#endif
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
while((HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG) && --timeout);
if(timeout)
{
return (STATUS_SUCCESS);
}
else
{
return (STATUS_FAIL);
}
}
void UCS_turnOffXT2(void)
{
//Switch off XT2 oscillator
HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2OFF;
}
void UCS_initFLLSettle(uint16_t fsystem,
uint16_t ratio)
{
volatile uint16_t x = ratio * 32;
UCS_initFLL(fsystem, ratio);
while(x--)
{
__delay_cycles(30);
}
}
void UCS_initFLL(uint16_t fsystem,
uint16_t ratio)
{
uint16_t d, dco_div_bits;
uint16_t mode = 0;
//Save actual state of FLL loop control, then disable it. This is needed to
//prevent the FLL from acting as we are making fundamental modifications to
//the clock setup.
uint16_t srRegisterState = __get_SR_register() & SCG0;
d = ratio;
//Have at least a divider of 2
dco_div_bits = FLLD__2;
if(fsystem > 16000)
{
d >>= 1;
mode = 1;
}
else
{
//fsystem = fsystem * 2
fsystem <<= 1;
}
while(d > 512)
{
//Set next higher div level
dco_div_bits = dco_div_bits + FLLD0;
d >>= 1;
}
// Disable FLL
__bis_SR_register(SCG0);
//Set DCO to lowest Tap
HWREG8(UCS_BASE + OFS_UCSCTL0_H) = 0x0000;
//Reset FN bits
HWREG16(UCS_BASE + OFS_UCSCTL2) &= ~(0x03FF);
HWREG16(UCS_BASE + OFS_UCSCTL2) = dco_div_bits | (d - 1);
if(fsystem <= 630) //fsystem < 0.63MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_0;
}
else if(fsystem < 1250) //0.63MHz < fsystem < 1.25MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_1;
}
else if(fsystem < 2500) //1.25MHz < fsystem < 2.5MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_2;
}
else if(fsystem < 5000) //2.5MHz < fsystem < 5MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_3;
}
else if(fsystem < 10000) //5MHz < fsystem < 10MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_4;
}
else if(fsystem < 20000) //10MHz < fsystem < 20MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_5;
}
else if(fsystem < 40000) //20MHz < fsystem < 40MHz
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_6;
}
else
{
HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_7;
}
// Re-enable FLL
__bic_SR_register(SCG0);
while(HWREG8(UCS_BASE + OFS_UCSCTL7_L) & DCOFFG)
{
//Clear OSC flaut Flags
HWREG8(UCS_BASE + OFS_UCSCTL7_L) &= ~(DCOFFG);
//Clear OFIFG fault flag
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
}
// Restore previous SCG0
__bis_SR_register(srRegisterState);
if(mode == 1)
{
//fsystem > 16000
//Select DCOCLK
HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7 + SELS_7);
HWREG16(UCS_BASE + OFS_UCSCTL4) |= SELM__DCOCLK + SELS__DCOCLK;
}
else
{
//Select DCODIVCLK
HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7 + SELS_7);
HWREG16(UCS_BASE + OFS_UCSCTL4) |= SELM__DCOCLKDIV + SELS__DCOCLKDIV;
}
}
void UCS_enableClockRequest(uint8_t selectClock)
{
HWREG8(UCS_BASE + OFS_UCSCTL8) |= selectClock;
}
void UCS_disableClockRequest(uint8_t selectClock)
{
HWREG8(UCS_BASE + OFS_UCSCTL8) &= ~selectClock;
}
uint8_t UCS_getFaultFlagStatus(uint8_t mask)
{
assert(mask <= UCS_XT2OFFG);
return (HWREG8(UCS_BASE + OFS_UCSCTL7) & mask);
}
void UCS_clearFaultFlag(uint8_t mask)
{
assert(mask <= UCS_XT2OFFG);
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~mask;
}
void UCS_turnOffSMCLK(void)
{
HWREG16(UCS_BASE + OFS_UCSCTL6) |= SMCLKOFF;
}
void UCS_turnOnSMCLK(void)
{
HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~SMCLKOFF;
}
uint32_t UCS_getACLK(void)
{
//Find ACLK source
uint16_t ACLKSource = (HWREG16(UCS_BASE + OFS_UCSCTL4) & SELA_7);
ACLKSource = ACLKSource >> 8;
uint16_t ACLKSourceDivider = HWREG16(UCS_BASE + OFS_UCSCTL5) & DIVA_7;
ACLKSourceDivider = ACLKSourceDivider >> 8;
return (privateUCSComputeCLKFrequency(
ACLKSource,
ACLKSourceDivider
));
}
uint32_t UCS_getSMCLK(void)
{
uint16_t SMCLKSource = HWREG8(UCS_BASE + OFS_UCSCTL4_L) & SELS_7;
SMCLKSource = SMCLKSource >> 4;
uint16_t SMCLKSourceDivider =
HWREG16(UCS_BASE + OFS_UCSCTL5) & DIVS_7;
SMCLKSourceDivider = SMCLKSourceDivider >> 4;
return (privateUCSComputeCLKFrequency(
SMCLKSource,
SMCLKSourceDivider)
);
}
uint32_t UCS_getMCLK(void)
{
//Find AMCLK source
uint16_t MCLKSource = (HWREG16(UCS_BASE + OFS_UCSCTL4) & SELM_7);
uint16_t MCLKSourceDivider = HWREG16(UCS_BASE + OFS_UCSCTL5) & DIVM_7;
return (privateUCSComputeCLKFrequency(
MCLKSource,
MCLKSourceDivider)
);
}
uint16_t UCS_clearAllOscFlagsWithTimeout(uint16_t timeout)
{
assert(timeout > 0);
do
{
// Clear all osc fault flags
HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(DCOFFG +
XT1LFOFFG +
XT1HFOFFG +
XT2OFFG
);
#if CC430_DEVICE
// CC430 uses a different fault mechanism. It requires 3 VLO clock
// cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
// case.
__delay_cycles(5000);
#endif
// Clear the global osc fault flag.
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
// Check XT1 fault flags
}
while((HWREG8(SFR_BASE + OFS_SFRIFG1) & OFIFG) && --timeout);
return (HWREG8(UCS_BASE + OFS_UCSCTL7) & (DCOFFG +
XT1LFOFFG +
XT1HFOFFG +
XT2OFFG)
);
}
#endif
//*****************************************************************************
//
//! Close the doxygen group for ucs_api
//! @}
//
//*****************************************************************************

