1246 lines
37 KiB
C
Executable File
1246 lines
37 KiB
C
Executable File
/* --COPYRIGHT--,BSD
|
|
* Copyright (c) 2016, Texas Instruments Incorporated
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of Texas Instruments Incorporated nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
* --/COPYRIGHT--*/
|
|
//*****************************************************************************
|
|
//
|
|
// cs.c - Driver for the cs Module.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \addtogroup cs_api cs
|
|
//! @{
|
|
//
|
|
//*****************************************************************************
|
|
|
|
#include "inc/hw_memmap.h"
|
|
|
|
#ifdef __MSP430_HAS_CS__
|
|
#include "cs.h"
|
|
|
|
#include <assert.h>
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Internal very low power VLOCLK, low frequency oscillator with 10 kHz typical
|
|
// frequency
|
|
//
|
|
//*****************************************************************************
|
|
#define CS_VLOCLK_FREQUENCY 10000
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Internal, trimmed, low-frequency oscillator with 32768 Hz typical frequency
|
|
//
|
|
//*****************************************************************************
|
|
#define CS_REFOCLK_FREQUENCY 32768
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Internal DCO frequency range
|
|
//
|
|
//*****************************************************************************
|
|
#define CS_DCO_RANGE_1MHZ 1000000
|
|
#define CS_DCO_RANGE_2MHZ 2000000
|
|
#define CS_DCO_RANGE_4MHZ 4000000
|
|
#define CS_DCO_RANGE_8MHZ 8000000
|
|
#define CS_DCO_RANGE_12MHZ 12000000
|
|
#define CS_DCO_RANGE_16MHZ 16000000
|
|
#define CS_DCO_RANGE_20MHZ 20000000
|
|
#define CS_DCO_RANGE_24MHZ 24000000
|
|
|
|
//******************************************************************************
|
|
//
|
|
//The XT1 crystal frequency. Should be set with CS_externalClockSourceInit
|
|
//if XT1 is used and user intends to invoke CS_getSMCLK, CS_getMCLK or
|
|
//CS_getACLK
|
|
//
|
|
//******************************************************************************
|
|
static uint32_t privateXT1ClockFrequency = 0;
|
|
|
|
static uint32_t privateDCORange(void)
|
|
{
|
|
uint32_t res = 0;
|
|
switch((HWREG8(CS_BASE + OFS_CSCTL1)) & DCORSEL_7)
|
|
{
|
|
case DCORSEL_0:
|
|
res = CS_DCO_RANGE_1MHZ;
|
|
break;
|
|
case DCORSEL_1:
|
|
res = CS_DCO_RANGE_2MHZ;
|
|
break;
|
|
case DCORSEL_2:
|
|
res = CS_DCO_RANGE_4MHZ;
|
|
break;
|
|
case DCORSEL_3:
|
|
res = CS_DCO_RANGE_8MHZ;
|
|
break;
|
|
case DCORSEL_4:
|
|
res = CS_DCO_RANGE_12MHZ;
|
|
break;
|
|
case DCORSEL_5:
|
|
res = CS_DCO_RANGE_16MHZ;
|
|
break;
|
|
case DCORSEL_6:
|
|
res = CS_DCO_RANGE_20MHZ;
|
|
break;
|
|
case DCORSEL_7:
|
|
res = CS_DCO_RANGE_24MHZ;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return(res);
|
|
}
|
|
|
|
static uint32_t privateCSSourceClockFromDCO(uint16_t FLLRefCLKSource)
|
|
{
|
|
uint16_t N_value;
|
|
uint16_t n_value = 1;
|
|
uint32_t Fref_value;
|
|
|
|
N_value = (HWREG16(CS_BASE + OFS_CSCTL2)) & 0x03FF;
|
|
uint16_t tempDivider = HWREG8(CS_BASE + OFS_CSCTL3) & FLLREFDIV_7;
|
|
|
|
if(tempDivider > 1)
|
|
{
|
|
n_value = 32 << (tempDivider - 1);
|
|
}
|
|
|
|
switch((HWREG8(CS_BASE + OFS_CSCTL3)) & SELREF_3)
|
|
{
|
|
case SELREF__XT1CLK:
|
|
Fref_value = privateXT1ClockFrequency;
|
|
|
|
if(HWREG8(CS_BASE + OFS_CSCTL7) & XT1OFFG)
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG);
|
|
//Clear OFIFG fault flag
|
|
HWREG8(CS_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
|
|
if(HWREG8(CS_BASE + OFS_CSCTL7) & XT1OFFG)
|
|
{
|
|
if(HWREG16(CS_BASE + OFS_CSCTL6) & XTS)
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~DCOFFG;
|
|
Fref_value = privateDCORange();
|
|
}
|
|
else
|
|
{
|
|
Fref_value = CS_REFOCLK_FREQUENCY;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case SELREF__REFOCLK:
|
|
Fref_value = CS_REFOCLK_FREQUENCY;
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
return (Fref_value * (N_value + 1) / n_value);
|
|
}
|
|
|
|
static uint32_t privateCSComputeCLKFrequency(uint16_t CLKSource,
|
|
uint16_t CLKSourceDivider,
|
|
uint8_t CLKDest)
|
|
{
|
|
uint32_t CLKFrequency = 0;
|
|
uint8_t CLKSourceFrequencyDivider = 1;
|
|
|
|
CLKSourceFrequencyDivider = 1 << CLKSourceDivider;
|
|
|
|
switch(CLKSource)
|
|
{
|
|
case SELMS__XT1CLK:
|
|
CLKFrequency = (privateXT1ClockFrequency /
|
|
CLKSourceFrequencyDivider);
|
|
|
|
if(HWREG8(CS_BASE + OFS_CSCTL7) & XT1OFFG)
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG);
|
|
//Clear OFIFG fault flag
|
|
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
//fail-safe operation
|
|
if(HWREG8(CS_BASE + OFS_CSCTL7) & XT1OFFG)
|
|
{
|
|
//fail-safe for ACLK or XT1 mode is LF
|
|
if(CLKDest == CS_ACLK ||
|
|
(HWREG16(CS_BASE + OFS_CSCTL6) & XTS) == 0)
|
|
{
|
|
CLKFrequency = CS_REFOCLK_FREQUENCY;
|
|
}
|
|
//XT1 mode is HF
|
|
else
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~DCOFFG;
|
|
CLKFrequency = privateDCORange();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SELMS__VLOCLK:
|
|
CLKFrequency =
|
|
(CS_VLOCLK_FREQUENCY / CLKSourceFrequencyDivider);
|
|
break;
|
|
case SELMS__REFOCLK:
|
|
CLKFrequency =
|
|
(CS_REFOCLK_FREQUENCY / CLKSourceFrequencyDivider);
|
|
break;
|
|
case SELMS__DCOCLKDIV:
|
|
CLKFrequency =
|
|
privateCSSourceClockFromDCO(CLKSource)
|
|
/ CLKSourceFrequencyDivider;
|
|
break;
|
|
}
|
|
|
|
return (CLKFrequency);
|
|
}
|
|
|
|
static void privateCSComputeDCOFTrim(CS_initFLLParam *param)
|
|
{
|
|
uint16_t oldDcoTap = 0xffff;
|
|
uint16_t newDcoTap = 0xffff;
|
|
uint16_t newDcoDelta = 0xffff;
|
|
uint16_t bestDcoDelta = 0xffff;
|
|
uint16_t csCtl0Copy = 0;
|
|
uint16_t csCtl1Copy = 0;
|
|
uint16_t csCtl0Read = 0;
|
|
uint16_t csCtl1Read = 0;
|
|
uint16_t dcoFreqTrim = 3;
|
|
bool endLoop = false;
|
|
|
|
do
|
|
{
|
|
HWREG16(CS_BASE + OFS_CSCTL0) = DCO8; // DCO Tap = 256
|
|
do
|
|
{
|
|
HWREG16(CS_BASE + OFS_CSCTL7) &= ~DCOFFG; // Clear DCO fault flag
|
|
}
|
|
while(HWREG16(CS_BASE + OFS_CSCTL7) & DCOFFG);
|
|
|
|
switch((HWREG16(CS_BASE + OFS_CSCTL1) & DCORSEL_7) >> 1)
|
|
{
|
|
// Wait FLL lock status (FLLUNLOCK) stable
|
|
// Suggest to wait 24 cycles of divided FLL refclk
|
|
case 0: // 1 MHz
|
|
__delay_cycles((uint16_t)3000);
|
|
break;
|
|
case 1: // 2 MHz
|
|
__delay_cycles((uint16_t)3000 * 2);
|
|
break;
|
|
case 2: // 4 MHz
|
|
__delay_cycles((uint16_t)3000 * 4);
|
|
break;
|
|
case 3: // 8 MHz
|
|
__delay_cycles((uint16_t)3000 * 8);
|
|
break;
|
|
case 4: // 12 MHz
|
|
__delay_cycles((uint16_t)3000 * 12);
|
|
break;
|
|
case 5: // 16 MHz
|
|
__delay_cycles((uint16_t)3000 * 16);
|
|
break;
|
|
case 6: // 20 MHz
|
|
__delay_cycles((uint16_t)3000 * 20);
|
|
break;
|
|
case 7: // 24 MHz
|
|
__delay_cycles((uint32_t)3000 * 24);
|
|
break;
|
|
default: // reserved
|
|
__delay_cycles((uint16_t)3000 * 16);
|
|
break;
|
|
}
|
|
|
|
// Poll the FLLUNLOCK bits and DCOFFG bit until FLL is locked or DCO fault
|
|
while((HWREG16(CS_BASE + OFS_CSCTL7) & (FLLUNLOCK0 | FLLUNLOCK1)) &&
|
|
((HWREG16(CS_BASE + OFS_CSCTL7) & DCOFFG) == 0))
|
|
{
|
|
;
|
|
}
|
|
|
|
csCtl0Read = HWREG16(CS_BASE + OFS_CSCTL0); // Read CSCTL0
|
|
csCtl1Read = HWREG16(CS_BASE + OFS_CSCTL1); // Read CSCTL1
|
|
|
|
oldDcoTap = newDcoTap; // Record DCOTAP value of last time
|
|
newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time
|
|
dcoFreqTrim = (csCtl1Read & 0x0070) >> 4; // Get DCOFTRIM value
|
|
|
|
if(newDcoTap < 256) // DCOTAP < 256
|
|
{
|
|
newDcoDelta = 256 - newDcoTap; // Delta value between DCOTAP and 256
|
|
if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
|
|
{
|
|
endLoop = true; // Stop while loop
|
|
}
|
|
else
|
|
{
|
|
dcoFreqTrim--;
|
|
HWREG16(CS_BASE +
|
|
OFS_CSCTL1) =
|
|
(csCtl1Read & (~0x0070)) | (dcoFreqTrim << 4);
|
|
}
|
|
}
|
|
else // DCOTAP >= 256
|
|
{
|
|
newDcoDelta = newDcoTap - 256; // Delta value between DCOTAP and 256
|
|
if(oldDcoTap < 256) // DCOTAP cross 256
|
|
{
|
|
endLoop = true; // Stop while loop
|
|
}
|
|
else
|
|
{
|
|
dcoFreqTrim++;
|
|
HWREG16(CS_BASE +
|
|
OFS_CSCTL1) =
|
|
(csCtl1Read & (~0x0070)) | (dcoFreqTrim << 4);
|
|
}
|
|
}
|
|
|
|
if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256
|
|
{
|
|
csCtl0Copy = csCtl0Read;
|
|
csCtl1Copy = csCtl1Read;
|
|
bestDcoDelta = newDcoDelta;
|
|
}
|
|
}
|
|
while(endLoop == false); // Poll until endLoop == 1
|
|
|
|
HWREG16(CS_BASE + OFS_CSCTL0) = csCtl0Copy; // Reload locked DCOTAP
|
|
HWREG16(CS_BASE + OFS_CSCTL1) = csCtl1Copy; // Reload locked DCOFTRIM
|
|
param->csCtl0 = csCtl0Copy;
|
|
param->csCtl1 = csCtl1Copy;
|
|
while(HWREG16(CS_BASE + OFS_CSCTL7) & (FLLUNLOCK0 | FLLUNLOCK1))
|
|
{
|
|
; // Poll until FLL is locked
|
|
}
|
|
}
|
|
|
|
void CS_setExternalClockSource(uint32_t XT1CLK_frequency)
|
|
{
|
|
privateXT1ClockFrequency = XT1CLK_frequency;
|
|
}
|
|
|
|
void CS_initClockSignal(uint8_t selectedClockSignal,
|
|
uint16_t clockSource,
|
|
uint16_t clockSourceDivider)
|
|
{
|
|
uint16_t temp;
|
|
switch(selectedClockSignal)
|
|
{
|
|
case CS_ACLK:
|
|
|
|
HWREG16(CS_BASE + OFS_CSCTL4) &= ~(SELA);
|
|
|
|
if(clockSource == CS_XT1CLK_SELECT)
|
|
{
|
|
clockSource = 0x0;
|
|
}
|
|
else if(clockSource == CS_REFOCLK_SELECT)
|
|
{
|
|
clockSource = 0x1;
|
|
}
|
|
else if(clockSource == CS_VLOCLK_SELECT)
|
|
{
|
|
clockSource = 0x2;
|
|
}
|
|
clockSource = clockSource << 8;
|
|
|
|
HWREG16(CS_BASE + OFS_CSCTL4) |= (clockSource);
|
|
#ifdef DIVA0
|
|
if(HWREG16(CS_BASE + OFS_CSCTL6) & XTS)
|
|
{
|
|
temp = HWREG16(CS_BASE + OFS_CSCTL6);
|
|
if(clockSourceDivider != CS_CLOCK_DIVIDER_1)
|
|
{
|
|
clockSourceDivider = (clockSourceDivider - 3) << 8;
|
|
HWREG16(CS_BASE +
|
|
OFS_CSCTL6) |= temp & ~(DIVA3 | DIVA2 | DIVA1 | DIVA0)
|
|
| clockSourceDivider;
|
|
}
|
|
}
|
|
#endif
|
|
break;
|
|
case CS_SMCLK:
|
|
|
|
HWREG16(CS_BASE + OFS_CSCTL4) &= ~(SELMS_7);
|
|
HWREG16(CS_BASE + OFS_CSCTL4) |= (clockSource);
|
|
|
|
temp = HWREG16(CS_BASE + OFS_CSCTL5);
|
|
clockSourceDivider = clockSourceDivider << 4;
|
|
HWREG16(CS_BASE + OFS_CSCTL5) = temp & ~(DIVS_3) | clockSourceDivider;
|
|
break;
|
|
case CS_MCLK:
|
|
|
|
HWREG16(CS_BASE + OFS_CSCTL4) &= ~(SELMS_7);
|
|
HWREG16(CS_BASE + OFS_CSCTL4) |= (clockSource);
|
|
|
|
temp = HWREG16(CS_BASE + OFS_CSCTL5);
|
|
HWREG16(CS_BASE + OFS_CSCTL5) = temp & ~(DIVM_7) | clockSourceDivider;
|
|
break;
|
|
case CS_FLLREF:
|
|
|
|
HWREG8(CS_BASE + OFS_CSCTL3) &= ~(SELREF_3);
|
|
|
|
if(clockSource == CS_XT1CLK_SELECT)
|
|
{
|
|
clockSource = 0x0;
|
|
}
|
|
clockSource = clockSource << 4;
|
|
HWREG8(CS_BASE + OFS_CSCTL3) |= (clockSource);
|
|
|
|
temp = HWREG8(CS_BASE + OFS_CSCTL3);
|
|
//Note that dividers for FLLREF are slightly different
|
|
//Hence handled differently from other CLK signals
|
|
if(clockSourceDivider != CS_CLOCK_DIVIDER_1)
|
|
{
|
|
if(clockSourceDivider == CS_CLOCK_DIVIDER_640)
|
|
{
|
|
HWREG8(CS_BASE +
|
|
OFS_CSCTL3) = temp & ~(FLLREFDIV_7) |
|
|
(clockSourceDivider - 10);
|
|
}
|
|
else if(clockSourceDivider != CS_CLOCK_DIVIDER_512)
|
|
{
|
|
HWREG8(CS_BASE +
|
|
OFS_CSCTL3) = temp & ~(FLLREFDIV_7) |
|
|
(clockSourceDivider - 4);
|
|
}
|
|
else
|
|
{
|
|
HWREG8(CS_BASE +
|
|
OFS_CSCTL3) = temp & ~(FLLREFDIV_7) |
|
|
(clockSourceDivider - 5);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CS_turnOnXT1LF(uint16_t xt1Drive){
|
|
//Switch ON XT1 oscillator
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XT1AUTOOFF;
|
|
|
|
//Highest drive setting for turnOnXT1
|
|
HWREG16(CS_BASE + OFS_CSCTL6_L) |= XT1DRIVE1_L | XT1DRIVE0_L;
|
|
|
|
//Enable LF mode and clear bypass
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~(XTS | XT1BYPASS);
|
|
|
|
while(HWREG8(CS_BASE + OFS_CSCTL7) & XT1OFFG)
|
|
{
|
|
//Clear OSC fault flag
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG);
|
|
|
|
//Clear OFIFG fault flag
|
|
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
}
|
|
|
|
//set requested Drive mode
|
|
HWREG16(CS_BASE + OFS_CSCTL6) = (HWREG16(CS_BASE + OFS_CSCTL6) &
|
|
~(XT1DRIVE_3)
|
|
) |
|
|
(xt1Drive);
|
|
}
|
|
|
|
void CS_bypassXT1(void)
|
|
{
|
|
//Enable HF/LF mode
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XTS;
|
|
|
|
//Switch OFF XT1 oscillator and enable BYPASS mode
|
|
HWREG16(CS_BASE + OFS_CSCTL6) |= (XT1BYPASS | XT1AUTOOFF);
|
|
|
|
while(HWREG8(CS_BASE + OFS_CSCTL7) & (XT1OFFG))
|
|
{
|
|
//Clear OSC fault flags
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG);
|
|
|
|
// 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 CS_turnOnXT1LFWithTimeout(uint16_t xt1Drive,
|
|
uint16_t timeout)
|
|
{
|
|
//Switch ON XT1 oscillator
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XT1AUTOOFF;
|
|
|
|
//Highest drive setting for turnOnXT1
|
|
HWREG16(CS_BASE + OFS_CSCTL6_L) |= XT1DRIVE1_L | XT1DRIVE0_L;
|
|
|
|
//Enable LF mode and clear bypass
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~(XTS | XT1BYPASS);
|
|
|
|
do
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG);
|
|
|
|
//Clear OFIFG fault flag
|
|
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
}
|
|
while((HWREG8(CS_BASE + OFS_CSCTL7) & XT1OFFG) && --timeout);
|
|
|
|
if(timeout)
|
|
{
|
|
//set requested Drive mode
|
|
HWREG16(CS_BASE + OFS_CSCTL6) = (HWREG16(CS_BASE + OFS_CSCTL6) &
|
|
~(XT1DRIVE_3)
|
|
) |
|
|
(xt1Drive);
|
|
|
|
return (STATUS_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
return (STATUS_FAIL);
|
|
}
|
|
}
|
|
|
|
bool CS_bypassXT1WithTimeout(uint16_t timeout)
|
|
{
|
|
//Enable HF/LF mode
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XTS;
|
|
|
|
//Switch OFF XT1 oscillator and enable bypass
|
|
HWREG16(CS_BASE + OFS_CSCTL6) |= (XT1BYPASS | XT1AUTOOFF);
|
|
|
|
do
|
|
{
|
|
//Clear OSC fault flags
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG);
|
|
|
|
// 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(CS_BASE + OFS_CSCTL7) & (XT1OFFG)) && --timeout);
|
|
|
|
if(timeout)
|
|
{
|
|
return (STATUS_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
return (STATUS_FAIL);
|
|
}
|
|
}
|
|
|
|
void CS_turnOffXT1(void)
|
|
{
|
|
//Switch off XT1 oscillator
|
|
HWREG16(CS_BASE + OFS_CSCTL6) |= XT1AUTOOFF;
|
|
}
|
|
|
|
void CS_turnOnXT1HF(uint16_t xt1Drive,
|
|
uint16_t xt1HFFreq){
|
|
#ifdef XT1HFFREQ_3
|
|
//Switch ON XT1 oscillator
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XT1AUTOOFF;
|
|
|
|
//Enable HF and highest drive setting for XT1
|
|
HWREG16(CS_BASE + OFS_CSCTL6_L) |= XTS | XT1DRIVE1_L | XT1DRIVE0_L;
|
|
|
|
//Clear bypass
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XT1BYPASS;
|
|
|
|
while(HWREG8(CS_BASE + OFS_CSCTL7) & XT1OFFG)
|
|
{
|
|
//Clear OSC fault flag
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG);
|
|
|
|
//Clear OFIFG fault flag
|
|
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
}
|
|
|
|
//set requested Drive mode
|
|
HWREG16(CS_BASE + OFS_CSCTL6) = (HWREG16(CS_BASE + OFS_CSCTL6) &
|
|
~(XT1DRIVE_3 | XT1HFFREQ_3)) |
|
|
xt1Drive | xt1HFFreq;
|
|
#endif
|
|
}
|
|
|
|
bool CS_turnOnXT1HFWithTimeout(uint16_t xt1Drive,
|
|
uint16_t xt1HFFreq,
|
|
uint16_t timeout)
|
|
{
|
|
#ifdef XT1HFFREQ_3
|
|
//Switch ON XT1 oscillator
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XT1AUTOOFF;
|
|
|
|
//Enable HF and highest drive setting for XT1
|
|
HWREG16(CS_BASE + OFS_CSCTL6_L) |= XTS | XT1DRIVE1_L | XT1DRIVE0_L;
|
|
|
|
//Clear bypass
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XT1BYPASS;
|
|
|
|
do
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG);
|
|
|
|
//Clear OFIFG fault flag
|
|
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
}
|
|
while((HWREG8(CS_BASE + OFS_CSCTL7) & XT1OFFG) && --timeout);
|
|
|
|
if(timeout)
|
|
{
|
|
//set requested Drive mode
|
|
HWREG16(CS_BASE + OFS_CSCTL6) = (HWREG16(CS_BASE + OFS_CSCTL6) &
|
|
~(XT1DRIVE_3 | XT1HFFREQ_3)) |
|
|
xt1Drive | xt1HFFreq;
|
|
|
|
return (STATUS_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
return (STATUS_FAIL);
|
|
}
|
|
#else
|
|
return (STATUS_FAIL);
|
|
#endif
|
|
}
|
|
|
|
void CS_turnOnSMCLK(void)
|
|
{
|
|
//Turn on SMCLK
|
|
HWREG16(CS_BASE + OFS_CSCTL5) &= ~SMCLKOFF;
|
|
}
|
|
|
|
void CS_turnOffSMCLK(void)
|
|
{
|
|
//Turn off SMCLK
|
|
HWREG16(CS_BASE + OFS_CSCTL5) |= SMCLKOFF;
|
|
}
|
|
|
|
void CS_enableVLOAutoOff(void)
|
|
{
|
|
//Enable VLO Auto Off
|
|
HWREG16(CS_BASE + OFS_CSCTL5) |= VLOAUTOOFF;
|
|
}
|
|
|
|
void CS_disableVLOAutoOff(void)
|
|
{
|
|
//Disable VLO Auto Off
|
|
HWREG16(CS_BASE + OFS_CSCTL5) &= ~VLOAUTOOFF;
|
|
}
|
|
|
|
bool CS_initFLLSettle(uint16_t fsystem,
|
|
uint16_t ratio)
|
|
{
|
|
volatile uint16_t x = ratio * 32;
|
|
|
|
bool status = CS_initFLL(fsystem, ratio);
|
|
|
|
while(x--)
|
|
{
|
|
__delay_cycles(30);
|
|
}
|
|
|
|
return(status);
|
|
}
|
|
|
|
bool CS_initFLL(uint16_t fsystem,
|
|
uint16_t ratio)
|
|
{
|
|
uint16_t dco_FLLN, dco_FLLD = FLLD__1;
|
|
bool status = true;
|
|
|
|
//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;
|
|
|
|
//Have at least a divider of 2
|
|
dco_FLLN = ratio;
|
|
|
|
// Disable FLL
|
|
__bis_SR_register(SCG0);
|
|
|
|
//Set DCO to lowest Tap
|
|
HWREG16(CS_BASE + OFS_CSCTL0) &= ~(DCO8 |
|
|
DCO7 |
|
|
DCO6 |
|
|
DCO5 |
|
|
DCO4 |
|
|
DCO3 |
|
|
DCO2 |
|
|
DCO1 |
|
|
DCO0
|
|
);
|
|
|
|
//Reset FLLN bits
|
|
HWREG16(CS_BASE + OFS_CSCTL2) &= ~(FLLN9 |
|
|
FLLN8 |
|
|
FLLN7 |
|
|
FLLN6 |
|
|
FLLN5 |
|
|
FLLN4 |
|
|
FLLN3 |
|
|
FLLN2 |
|
|
FLLN1 |
|
|
FLLN0
|
|
);
|
|
HWREG16(CS_BASE + OFS_CSCTL2) = dco_FLLD | (dco_FLLN - 1);
|
|
|
|
HWREG8(CS_BASE + OFS_CSCTL1) &= ~DCORSEL_7;
|
|
if(fsystem <= 1000) //fsystem <= 1MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_0;
|
|
}
|
|
else if(fsystem <= 2000) //1MHz < fsystem <= 2MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_1;
|
|
}
|
|
else if(fsystem <= 4000) //2MHz < fsystem <= 4MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_2;
|
|
}
|
|
else if(fsystem <= 8000) //4MHz < fsystem <= 8MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_3;
|
|
}
|
|
else if(fsystem <= 12000) //8MHz < fsystem <= 12MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_4;
|
|
}
|
|
else if(fsystem <= 16000) //12MHz < fsystem <= 16MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_5;
|
|
}
|
|
else if(fsystem <= 20000) //16MHz < fsystem <= 20MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_6;
|
|
}
|
|
else if(fsystem <= 24000) //20MHz < fsystem <= 24MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_7;
|
|
}
|
|
else
|
|
{
|
|
//exceeds 24MHz, not supported
|
|
status = false;
|
|
}
|
|
|
|
// Re-enable FLL
|
|
__bic_SR_register(SCG0);
|
|
|
|
while((HWREG16(CS_BASE + OFS_CSCTL7) & (FLLUNLOCK0 | FLLUNLOCK1)) ||
|
|
(HWREG8(CS_BASE + OFS_CSCTL7_L) & DCOFFG))
|
|
{
|
|
//Clear OSC fault flags
|
|
HWREG8(CS_BASE + OFS_CSCTL7_L) &= ~(DCOFFG);
|
|
|
|
//Clear OFIFG fault flag
|
|
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
}
|
|
|
|
// Restore previous SCG0
|
|
__bis_SR_register(srRegisterState);
|
|
|
|
return(status);
|
|
}
|
|
|
|
bool CS_initFLLCalculateTrim(uint16_t fsystem,
|
|
uint16_t ratio,
|
|
CS_initFLLParam *param)
|
|
{
|
|
uint16_t dco_FLLN, dco_FLLD = FLLD__1;
|
|
bool status = true;
|
|
volatile uint16_t x = ratio * 32;
|
|
|
|
//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;
|
|
|
|
//Have at least a divider of 2
|
|
dco_FLLN = ratio;
|
|
|
|
// Disable FLL
|
|
__bis_SR_register(SCG0);
|
|
|
|
//Set DCO to lowest Tap
|
|
HWREG16(CS_BASE + OFS_CSCTL0) &= ~(DCO8 |
|
|
DCO7 |
|
|
DCO6 |
|
|
DCO5 |
|
|
DCO4 |
|
|
DCO3 |
|
|
DCO2 |
|
|
DCO1 |
|
|
DCO0
|
|
);
|
|
//Reset FLLN bits
|
|
HWREG16(CS_BASE + OFS_CSCTL2) &= ~(FLLN9 |
|
|
FLLN8 |
|
|
FLLN7 |
|
|
FLLN6 |
|
|
FLLN5 |
|
|
FLLN4 |
|
|
FLLN3 |
|
|
FLLN2 |
|
|
FLLN1 |
|
|
FLLN0
|
|
);
|
|
HWREG16(CS_BASE + OFS_CSCTL2) = dco_FLLD | (dco_FLLN - 1);
|
|
|
|
HWREG8(CS_BASE + OFS_CSCTL1) &= ~DCORSEL_7;
|
|
if(fsystem <= 1000) //fsystem <= 1MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_0;
|
|
}
|
|
else if(fsystem <= 2000) //1MHz < fsystem <= 2MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_1;
|
|
}
|
|
else if(fsystem <= 4000) //2MHz < fsystem <= 4MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_2;
|
|
}
|
|
else if(fsystem <= 8000) //4MHz < fsystem <= 8MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_3;
|
|
}
|
|
else if(fsystem <= 12000) //8MHz < fsystem <= 12MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_4;
|
|
}
|
|
else if(fsystem <= 16000) //12MHz < fsystem <= 16MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_5;
|
|
}
|
|
else if(fsystem <= 20000) //16MHz < fsystem <= 20MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_6;
|
|
}
|
|
else if(fsystem <= 24000) //20MHz < fsystem <= 24MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_7;
|
|
}
|
|
else
|
|
{
|
|
//exceeds 24MHz, not supported
|
|
status = false;
|
|
}
|
|
|
|
// Re-enable FLL
|
|
__bic_SR_register(SCG0);
|
|
|
|
// Enable DCO frequency trim
|
|
HWREG16(CS_BASE + OFS_CSCTL1) |= DCOFTRIMEN;
|
|
|
|
// Calculates DCO frequency trim values and stores them in struct pointer
|
|
param->fsystem = fsystem;
|
|
privateCSComputeDCOFTrim(param);
|
|
|
|
while((HWREG16(CS_BASE + OFS_CSCTL7) & (FLLUNLOCK0 | FLLUNLOCK1)) ||
|
|
(HWREG8(CS_BASE + OFS_CSCTL7_L) & DCOFFG))
|
|
{
|
|
//Clear OSC fault flags
|
|
HWREG8(CS_BASE + OFS_CSCTL7_L) &= ~(DCOFFG);
|
|
|
|
//Clear OFIFG fault flag
|
|
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
}
|
|
|
|
// Restore previous SCG0
|
|
__bis_SR_register(srRegisterState);
|
|
|
|
while(x--)
|
|
{
|
|
__delay_cycles(30);
|
|
}
|
|
|
|
return(status);
|
|
}
|
|
|
|
bool CS_initFLLLoadTrim(uint16_t fsystem,
|
|
uint16_t ratio,
|
|
CS_initFLLParam *param)
|
|
{
|
|
if(param->fsystem != fsystem)
|
|
{
|
|
// Protection against wrong clock frequency and trim combination
|
|
return(false);
|
|
}
|
|
|
|
uint16_t dco_FLLN, dco_FLLD = FLLD__1;
|
|
bool status = true;
|
|
volatile uint16_t x = ratio * 32;
|
|
|
|
//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;
|
|
|
|
//Have at least a divider of 2
|
|
dco_FLLN = ratio;
|
|
|
|
// Disable FLL
|
|
__bis_SR_register(SCG0);
|
|
|
|
//Set DCO to proper tap
|
|
HWREG16(CS_BASE + OFS_CSCTL0) &= ~(DCO8 |
|
|
DCO7 |
|
|
DCO6 |
|
|
DCO5 |
|
|
DCO4 |
|
|
DCO3 |
|
|
DCO2 |
|
|
DCO1 |
|
|
DCO0
|
|
);
|
|
HWREG16(CS_BASE + OFS_CSCTL0) |= (param->csCtl0 &
|
|
(DCO8 |
|
|
DCO7 |
|
|
DCO6 |
|
|
DCO5 |
|
|
DCO4 |
|
|
DCO3 |
|
|
DCO2 |
|
|
DCO1 |
|
|
DCO0
|
|
));
|
|
|
|
//Reset FLLN bits
|
|
HWREG16(CS_BASE + OFS_CSCTL2) &= ~(FLLN9 |
|
|
FLLN8 |
|
|
FLLN7 |
|
|
FLLN6 |
|
|
FLLN5 |
|
|
FLLN4 |
|
|
FLLN3 |
|
|
FLLN2 |
|
|
FLLN1 |
|
|
FLLN0
|
|
);
|
|
HWREG16(CS_BASE + OFS_CSCTL2) = dco_FLLD | (dco_FLLN - 1);
|
|
|
|
// Set proper DCORSEL value
|
|
HWREG8(CS_BASE + OFS_CSCTL1) &= ~DCORSEL_7;
|
|
if(fsystem <= 1000) //fsystem <= 1MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_0;
|
|
}
|
|
else if(fsystem <= 2000) //1MHz < fsystem <= 2MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_1;
|
|
}
|
|
else if(fsystem <= 4000) //2MHz < fsystem <= 4MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_2;
|
|
}
|
|
else if(fsystem <= 8000) //4MHz < fsystem <= 8MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_3;
|
|
}
|
|
else if(fsystem <= 12000) //8MHz < fsystem <= 12MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_4;
|
|
}
|
|
else if(fsystem <= 16000) //12MHz < fsystem <= 16MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_5;
|
|
}
|
|
else if(fsystem <= 20000) //16MHz < fsystem <= 20MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_6;
|
|
}
|
|
else if(fsystem <= 24000) //20MHz < fsystem <= 24MHz
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL1) |= DCORSEL_7;
|
|
}
|
|
else
|
|
{
|
|
//exceeds 24MHz, not supported
|
|
status = false;
|
|
}
|
|
|
|
// Enable DCO frequency trim
|
|
HWREG16(CS_BASE + OFS_CSCTL1) |= DCOFTRIMEN;
|
|
|
|
// Set proper DCOFTRIM value
|
|
HWREG16(CS_BASE + OFS_CSCTL1) &= ~(DCOFTRIM0 | DCOFTRIM1 | DCOFTRIM2);
|
|
HWREG16(CS_BASE +
|
|
OFS_CSCTL1) |=
|
|
(param->csCtl1 & (DCOFTRIM0 | DCOFTRIM1 | DCOFTRIM2));
|
|
|
|
// Re-enable FLL
|
|
__bic_SR_register(SCG0);
|
|
|
|
while((HWREG16(CS_BASE + OFS_CSCTL7) & (FLLUNLOCK0 | FLLUNLOCK1)) ||
|
|
(HWREG8(CS_BASE + OFS_CSCTL7_L) & DCOFFG))
|
|
{
|
|
//Clear OSC fault flags
|
|
HWREG8(CS_BASE + OFS_CSCTL7_L) &= ~(DCOFFG);
|
|
|
|
//Clear OFIFG fault flag
|
|
HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
|
|
}
|
|
|
|
// Restore previous SCG0
|
|
__bis_SR_register(srRegisterState);
|
|
|
|
while(x--)
|
|
{
|
|
__delay_cycles(30);
|
|
}
|
|
|
|
return(status);
|
|
}
|
|
|
|
void CS_enableClockRequest(uint8_t selectClock)
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL8) |= selectClock;
|
|
}
|
|
|
|
void CS_disableClockRequest(uint8_t selectClock)
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL8) &= ~selectClock;
|
|
}
|
|
|
|
uint8_t CS_getFaultFlagStatus(uint8_t mask)
|
|
{
|
|
return (HWREG8(CS_BASE + OFS_CSCTL7) & mask);
|
|
}
|
|
|
|
void CS_clearFaultFlag(uint8_t mask)
|
|
{
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~mask;
|
|
}
|
|
|
|
uint32_t CS_getACLK(void)
|
|
{
|
|
//Find ACLK source
|
|
uint16_t ACLKSource = (HWREG16(CS_BASE + OFS_CSCTL4) & SELA);
|
|
|
|
ACLKSource = ACLKSource >> 8;
|
|
|
|
if(ACLKSource == 0x0)
|
|
{
|
|
ACLKSource = SELMS__XT1CLK;
|
|
}
|
|
else if(ACLKSource == 0x1)
|
|
{
|
|
ACLKSource = SELMS__REFOCLK;
|
|
}
|
|
else
|
|
{
|
|
ACLKSource = SELMS__VLOCLK;
|
|
}
|
|
|
|
uint16_t ACLKSourceDivider = 0;
|
|
#ifdef DIVA0
|
|
if(HWREG16(CS_BASE + OFS_CSCTL6) & XTS)
|
|
{
|
|
uint16_t div = (HWREG16(CS_BASE + OFS_CSCTL6) &
|
|
(DIVA0 | DIVA1 | DIVA2 | DIVA3)) >> 8;
|
|
switch(div)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
ACLKSourceDivider = 8 * (1 << div);
|
|
break;
|
|
case 6:
|
|
ACLKSourceDivider = 384;
|
|
break;
|
|
case 7:
|
|
ACLKSourceDivider = 512;
|
|
break;
|
|
case 8:
|
|
ACLKSourceDivider = 768;
|
|
break;
|
|
case 9:
|
|
ACLKSourceDivider = 1024;
|
|
break;
|
|
case 10:
|
|
ACLKSourceDivider = 108;
|
|
break;
|
|
case 11:
|
|
ACLKSourceDivider = 338;
|
|
break;
|
|
case 12:
|
|
ACLKSourceDivider = 414;
|
|
break;
|
|
case 13:
|
|
ACLKSourceDivider = 640;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
return (privateCSComputeCLKFrequency(
|
|
ACLKSource,
|
|
ACLKSourceDivider,
|
|
CS_ACLK)
|
|
);
|
|
}
|
|
|
|
uint32_t CS_getSMCLK(void)
|
|
{
|
|
uint16_t SMCLKSource = HWREG8(CS_BASE + OFS_CSCTL4_L) & SELMS_7;
|
|
|
|
uint16_t SMCLKSourceDivider =
|
|
HWREG16(CS_BASE + OFS_CSCTL5) & DIVS_3;
|
|
SMCLKSourceDivider = SMCLKSourceDivider >> 4;
|
|
|
|
return (privateCSComputeCLKFrequency(
|
|
SMCLKSource,
|
|
SMCLKSourceDivider,
|
|
CS_SMCLK)
|
|
);
|
|
}
|
|
|
|
uint32_t CS_getMCLK(void)
|
|
{
|
|
//Find AMCLK source
|
|
uint16_t MCLKSource = (HWREG16(CS_BASE + OFS_CSCTL4) & SELMS_7);
|
|
|
|
uint16_t MCLKSourceDivider = HWREG16(CS_BASE + OFS_CSCTL5) & DIVM_7;
|
|
|
|
return (privateCSComputeCLKFrequency(
|
|
MCLKSource,
|
|
MCLKSourceDivider,
|
|
CS_MCLK)
|
|
);
|
|
}
|
|
|
|
uint16_t CS_clearAllOscFlagsWithTimeout(uint16_t timeout){
|
|
do
|
|
{
|
|
// Clear all osc fault flags
|
|
HWREG8(CS_BASE + OFS_CSCTL7) &= ~(DCOFFG | XT1OFFG);
|
|
|
|
// 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(CS_BASE + OFS_CSCTL7) & (DCOFFG | XT1OFFG));
|
|
}
|
|
|
|
void CS_enableXT1AutomaticGainControl(void)
|
|
{
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XT1AGCOFF;
|
|
}
|
|
|
|
void CS_disableXT1AutomaticGainControl(void)
|
|
{
|
|
HWREG16(CS_BASE + OFS_CSCTL6) |= XT1AGCOFF;
|
|
}
|
|
|
|
void CS_enableFLLUnlock(void)
|
|
{
|
|
HWREG16(CS_BASE + OFS_CSCTL7) |= FLLULPUC;
|
|
}
|
|
|
|
void CS_disableFLLUnlock(void)
|
|
{
|
|
HWREG16(CS_BASE + OFS_CSCTL7) &= ~FLLULPUC;
|
|
}
|
|
|
|
void CS_enableREFOLP(void)
|
|
{
|
|
#ifdef REFOLP
|
|
HWREG16(CS_BASE + OFS_CSCTL3) |= REFOLP;
|
|
#endif
|
|
}
|
|
|
|
void CS_disableREFOLP(void)
|
|
{
|
|
#ifdef REFOLP
|
|
HWREG16(CS_BASE + OFS_CSCTL3) &= ~REFOLP;
|
|
#endif
|
|
}
|
|
|
|
bool CS_getREFOLP(void)
|
|
{
|
|
#ifdef REFOLP
|
|
return ((HWREG16(CS_BASE + OFS_CSCTL3) & REFOLP) ? true : false);
|
|
#else
|
|
return(false);
|
|
#endif
|
|
}
|
|
|
|
void CS_enableXT1FaultOff(void)
|
|
{
|
|
#ifdef XT1FAULTOFF
|
|
HWREG16(CS_BASE + OFS_CSCTL6) |= XT1FAULTOFF;
|
|
#endif
|
|
}
|
|
|
|
void CS_disableXT1FaultOff(void)
|
|
{
|
|
#ifdef XT1FAULTOFF
|
|
HWREG16(CS_BASE + OFS_CSCTL6) &= ~XT1FAULTOFF;
|
|
#endif
|
|
}
|
|
|
|
bool CS_getXT1FaultOff(void)
|
|
{
|
|
#ifdef XT1FAULTOFF
|
|
return ((HWREG16(CS_BASE + OFS_CSCTL6) & XT1FAULTOFF) ? true : false);
|
|
#else
|
|
return(false);
|
|
#endif
|
|
}
|
|
|
|
bool CS_getREFOReady(void)
|
|
{
|
|
#ifdef REFOREADY
|
|
return ((HWREG16(CS_BASE + OFS_CSCTL7) & REFOREADY) ? true : false);
|
|
#else
|
|
return(false);
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
//*****************************************************************************
|
|
//
|
|
//! Close the doxygen group for cs_api
|
|
//! @}
|
|
//
|
|
//*****************************************************************************
|