blob: 692fcd920dbd1942970b60c6b82ce9de1eafd58b [file] [log] [blame]
/*
* -------------------------------------------
* MSP432 DriverLib - v3_10_00_09
* -------------------------------------------
*
* --COPYRIGHT--,BSD,BSD
* Copyright (c) 2014, 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--*/
/* Standard Includes */
#include <stdint.h>
/* DriverLib Includes */
#include <cs.h>
#include <debug.h>
#include <sysctl.h>
#include <interrupt.h>
/* Statics */
static uint32_t hfxtFreq;
static uint32_t lfxtFreq;
#ifdef DEBUG
bool _CSIsClockDividerValid(uint8_t divider)
{
return ((divider == CS_CLOCK_DIVIDER_1) || (divider == CS_CLOCK_DIVIDER_2)
|| (divider == CS_CLOCK_DIVIDER_4) || (divider == CS_CLOCK_DIVIDER_8)
|| (divider == CS_CLOCK_DIVIDER_16) || (divider == CS_CLOCK_DIVIDER_32)
|| (divider == CS_CLOCK_DIVIDER_64) || (divider == CS_CLOCK_DIVIDER_128));
}
#endif
static uint32_t _CSGetHFXTFrequency()
{
if (hfxtFreq >= CS_1MHZ && hfxtFreq <= CS_4MHZ)
return CS_CTL2_HFXTFREQ_0;
else if (hfxtFreq > CS_4MHZ && hfxtFreq <= CS_8MHZ)
return CS_CTL2_HFXTFREQ_1;
else if (hfxtFreq > CS_8MHZ && hfxtFreq <= CS_16MHZ)
return CS_CTL2_HFXTFREQ_2;
else if (hfxtFreq > CS_16MHZ && hfxtFreq <= CS_24MHZ)
return CS_CTL2_HFXTFREQ_3;
else if (hfxtFreq > CS_24MHZ && hfxtFreq <= CS_32MHZ)
return CS_CTL2_HFXTFREQ_4;
else if (hfxtFreq > CS_32MHZ && hfxtFreq <= CS_40MHZ)
return CS_CTL2_HFXTFREQ_5;
else if (hfxtFreq > CS_40MHZ && hfxtFreq <= CS_48MHZ)
return CS_CTL2_HFXTFREQ_5;
else
{
ASSERT(false);
return 0;
}
}
static uint32_t _CSGetDividerValue(uint32_t wDivider)
{
switch (wDivider)
{
case CS_CLOCK_DIVIDER_1:
return 1;
case CS_CLOCK_DIVIDER_2:
return 2;
case CS_CLOCK_DIVIDER_4:
return 4;
case CS_CLOCK_DIVIDER_8:
return 8;
case CS_CLOCK_DIVIDER_16:
return 16;
case CS_CLOCK_DIVIDER_32:
return 32;
case CS_CLOCK_DIVIDER_64:
return 64;
case CS_CLOCK_DIVIDER_128:
return 128;
default:
ASSERT(false);
return 1;
}
}
static uint32_t _CSComputeCLKFrequency(uint32_t wClockSource, uint32_t wDivider)
{
uint_fast8_t bDivider;
bDivider = _CSGetDividerValue(wDivider);
switch (wClockSource)
{
case CS_LFXTCLK_SELECT:
{
if (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
{
CS_clearInterruptFlag(CS_LFXT_FAULT);
if (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
{
if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
return (128000 / bDivider);
else
return (32768 / bDivider);
}
}
return lfxtFreq / bDivider;
}
case CS_HFXTCLK_SELECT:
{
if (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
{
CS_clearInterruptFlag(CS_HFXT_FAULT);
if (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
{
if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
return (128000 / bDivider);
else
return (32768 / bDivider);
}
}
return hfxtFreq / bDivider;
}
case CS_VLOCLK_SELECT:
return CS_VLOCLK_FREQUENCY / bDivider;
case CS_REFOCLK_SELECT:
{
if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
return (128000 / bDivider);
else
return (32768 / bDivider);
}
case CS_DCOCLK_SELECT:
return (CS_getDCOFrequency() / bDivider);
case CS_MODOSC_SELECT:
return CS_MODCLK_FREQUENCY / bDivider;
default:
ASSERT(false);
return 0;
}
}
//******************************************************************************
// Internal function for getting DCO nominal frequency
//******************************************************************************
static uint32_t _CSGetDOCFrequency(void)
{
uint32_t dcoFreq;
switch (CS->CTL0 & CS_CTL0_DCORSEL_MASK)
{
case CS_CTL0_DCORSEL_0:
dcoFreq = 1500000;
break;
case CS_CTL0_DCORSEL_1:
dcoFreq = 3000000;
break;
case CS_CTL0_DCORSEL_2:
dcoFreq = 6000000;
break;
case CS_CTL0_DCORSEL_3:
dcoFreq = 12000000;
break;
case CS_CTL0_DCORSEL_4:
dcoFreq = 24000000;
break;
case CS_CTL0_DCORSEL_5:
dcoFreq = 48000000;
break;
default:
dcoFreq = 0;
}
return (dcoFreq);
}
void CS_setExternalClockSourceFrequency(uint32_t lfxt_XT_CLK_frequency,
uint32_t hfxt_XT_CLK_frequency)
{
hfxtFreq = hfxt_XT_CLK_frequency;
lfxtFreq = lfxt_XT_CLK_frequency;
}
void CS_initClockSignal(uint32_t selectedClockSignal, uint32_t clockSource,
uint32_t clockSourceDivider)
{
ASSERT(_CSIsClockDividerValid(clockSourceDivider));
/* Unlocking the CS Module */
CS->KEY = CS_KEY;
switch (selectedClockSignal)
{
case CS_ACLK:
{
/* Making sure that the clock signal for ACLK isn't set to anything
* invalid
*/
ASSERT(
(selectedClockSignal != CS_DCOCLK_SELECT)
&& (selectedClockSignal != CS_MODOSC_SELECT)
&& (selectedClockSignal != CS_HFXTCLK_SELECT));
/* Waiting for the clock source ready bit to be valid before
* changing */
while (!BITBAND_PERI(CS->STAT, CS_STAT_ACLK_READY_OFS))
;
/* Setting the divider and source */
CS->CTL1 = ((clockSourceDivider >> CS_ACLK_DIV_BITPOS)
| (clockSource << CS_ACLK_SRC_BITPOS))
| (CS->CTL1 & ~(CS_CTL1_SELA_MASK | CS_CTL1_DIVA_MASK));
/* Waiting for ACLK to be ready again */
while (!BITBAND_PERI(CS->STAT, CS_STAT_ACLK_READY_OFS))
;
break;
}
case CS_MCLK:
{
/* Waiting for the clock source ready bit to be valid before
* changing */
while (!BITBAND_PERI(CS->STAT, CS_STAT_MCLK_READY_OFS))
;
CS->CTL1 = ((clockSourceDivider >> CS_MCLK_DIV_BITPOS)
| (clockSource << CS_MCLK_SRC_BITPOS))
| (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK));
/* Waiting for MCLK to be ready */
while (!BITBAND_PERI(CS->STAT, CS_STAT_MCLK_READY_OFS))
;
break;
}
case CS_SMCLK:
{
/* Waiting for the clock source ready bit to be valid before
* changing */
while (!BITBAND_PERI(CS->STAT, CS_STAT_SMCLK_READY_OFS))
;
CS->CTL1 = ((clockSourceDivider >> CS_SMCLK_DIV_BITPOS)
| (clockSource << CS_HSMCLK_SRC_BITPOS))
| (CS->CTL1 & ~(CS_CTL1_DIVS_MASK | CS_CTL1_SELS_MASK));
/* Waiting for SMCLK to be ready */
while (!BITBAND_PERI(CS->STAT, CS_STAT_SMCLK_READY_OFS))
;
break;
}
case CS_HSMCLK:
{
/* Waiting for the clock source ready bit to be valid before
* changing */
while (!BITBAND_PERI(CS->STAT, CS_STAT_HSMCLK_READY_OFS))
;
CS->CTL1 = ((clockSourceDivider >> CS_HSMCLK_DIV_BITPOS)
| (clockSource << CS_HSMCLK_SRC_BITPOS))
| (CS->CTL1 & ~(CS_CTL1_DIVHS_MASK | CS_CTL1_SELS_MASK));
/* Waiting for HSMCLK to be ready */
while (!BITBAND_PERI(CS->STAT, CS_STAT_HSMCLK_READY_OFS))
;
break;
}
case CS_BCLK:
{
/* Waiting for the clock source ready bit to be valid before
* changing */
while (!BITBAND_PERI(CS->STAT, CS_STAT_BCLK_READY_OFS))
;
/* Setting the clock source and then returning
* (cannot divide CLK)
*/
if (clockSource == CS_LFXTCLK_SELECT)
BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS) = 0;
else if (clockSource == CS_REFOCLK_SELECT)
BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS) = 1;
else
ASSERT(false);
/* Waiting for BCLK to be ready */
while (!BITBAND_PERI(CS->STAT, CS_STAT_BCLK_READY_OFS))
;
break;
}
default:
{
/* Should never get here */
ASSERT(false);
}
}
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
bool CS_startHFXT(bool bypassMode)
{
return CS_startHFXTWithTimeout(bypassMode, 0);
}
bool CS_startHFXTWithTimeout(bool bypassMode, uint32_t timeout)
{
uint32_t wHFFreqRange;
uint_fast8_t bNMIStatus;
bool boolTimeout;
/* Unlocking the CS Module */
CS->KEY = CS_KEY;
/* Saving status and temporarily disabling NMIs for UCS faults */
bNMIStatus = SysCtl_getNMISourceStatus() & SYSCTL_CS_SRC;
SysCtl_disableNMISource(SYSCTL_CS_SRC);
/* Determining which frequency range to use */
wHFFreqRange = _CSGetHFXTFrequency();
boolTimeout = (timeout == 0) ? false : true;
/* Setting to maximum drive strength */
BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 1;
CS->CTL2 = (CS->CTL2 & (~CS_CTL2_HFXTFREQ_MASK)) | (wHFFreqRange);
if (bypassMode)
{
BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTBYPASS_OFS) = 1;
} else
{
BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTBYPASS_OFS) = 0;
}
/* Starting and Waiting for frequency stabilization */
BITBAND_PERI(CS->CTL2, CS_CTL2_HFXT_EN_OFS) = 1;
while (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
{
if (boolTimeout && ((--timeout) == 0))
break;
BITBAND_PERI(CS->CLRIFG,CS_CLRIFG_CLR_HFXTIFG_OFS) = 1;
}
/* Setting the drive strength */
if (!bypassMode)
{
if (wHFFreqRange != CS_CTL2_HFXTFREQ_0)
BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 1;
else
BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 0;
}
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
/* Enabling the NMI state */
SysCtl_enableNMISource(bNMIStatus);
if(boolTimeout && timeout == 0)
return false;
return true;
}
bool CS_startLFXT(uint32_t xtDrive)
{
return CS_startLFXTWithTimeout(xtDrive, 0);
}
bool CS_startLFXTWithTimeout(uint32_t xtDrive, uint32_t timeout)
{
uint8_t bNMIStatus;
bool boolBypassMode, boolTimeout;
ASSERT(lfxtFreq != 0)
ASSERT(
(xtDrive == CS_LFXT_DRIVE0) || (xtDrive == CS_LFXT_DRIVE1)
|| (xtDrive == CS_LFXT_DRIVE2)
|| (xtDrive == CS_LFXT_DRIVE3)
|| (xtDrive == CS_LFXT_BYPASS));
/* Unlocking the CS Module */
CS->KEY = CS_KEY;
/* Saving status and temporarily disabling NMIs for UCS faults */
bNMIStatus = SysCtl_getNMISourceStatus() & SYSCTL_CS_SRC;
SysCtl_disableNMISource(SYSCTL_CS_SRC);
boolBypassMode = (xtDrive == CS_LFXT_BYPASS) ? true : false;
boolTimeout = (timeout == 0) ? false : true;
/* Setting to maximum drive strength */
if (boolBypassMode)
{
BITBAND_PERI(CS->CTL2, CS_CTL2_LFXTBYPASS_OFS) = 1;
} else
{
CS->CTL2 |= (CS_LFXT_DRIVE3);
BITBAND_PERI(CS->CTL2, CS_CTL2_LFXTBYPASS_OFS) = 0;
}
/* Waiting for frequency stabilization */
BITBAND_PERI(CS->CTL2, CS_CTL2_LFXT_EN_OFS) = 1;
while (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
{
if (boolTimeout && ((--timeout) == 0))
break;
BITBAND_PERI(CS->CLRIFG,CS_CLRIFG_CLR_LFXTIFG_OFS) = 1;
}
/* Setting the drive strength */
if (!boolBypassMode)
{
CS->CTL2 = ((CS->CTL2 & ~CS_LFXT_DRIVE3) | xtDrive);
}
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
/* Enabling the NMI state */
SysCtl_enableNMISource(bNMIStatus);
if(boolTimeout && timeout == 0)
return false;
return true;
}
void CS_enableClockRequest(uint32_t selectClock)
{
ASSERT(
selectClock == CS_ACLK || selectClock == CS_HSMCLK
|| selectClock == CS_SMCLK || selectClock == CS_MCLK);
/* Unlocking the module */
CS->KEY = CS_KEY;
CS->CLKEN |= selectClock;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_disableClockRequest(uint32_t selectClock)
{
ASSERT(
selectClock == CS_ACLK || selectClock == CS_HSMCLK
|| selectClock == CS_SMCLK || selectClock == CS_MCLK);
/* Unlocking the module */
CS->KEY = CS_KEY;
CS->CLKEN &= ~selectClock;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_setReferenceOscillatorFrequency(uint8_t referenceFrequency)
{
ASSERT(
referenceFrequency == CS_REFO_32KHZ
|| referenceFrequency == CS_REFO_128KHZ);
/* Unlocking the module */
CS->KEY = CS_KEY;
BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS) = referenceFrequency;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_enableDCOExternalResistor(void)
{
/* Unlocking the module */
CS->KEY = CS_KEY;
BITBAND_PERI(CS->CTL0,CS_CTL0_DCORES_OFS) = 1;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_setDCOExternalResistorCalibration(uint_fast8_t calData,
uint_fast8_t freqRange)
{
uint_fast8_t rselVal;
/* Unlocking the module */
CS->KEY = CS_KEY;
rselVal = (CS->CTL0 | CS_CTL0_DCORSEL_MASK)>>CS_CTL0_DCORSEL_OFS;
CS->CTL0 &= ~CS_CTL0_DCORSEL_MASK;
if( (freqRange == CS_OVER32MHZ) && ( TLV->HWREV > DEVICE_PG1_1))
{
CS->DCOERCAL1 &= ~CS_DCOERCAL1_DCO_FCAL_RSEL5_MASK;
CS->DCOERCAL1 |= (calData);
}
else
{
CS->DCOERCAL0 &= ~CS_DCOERCAL0_DCO_FCAL_RSEL04_MASK;
CS->DCOERCAL0 |= (calData)<<CS_DCOERCAL0_DCO_FCAL_RSEL04_OFS;
}
CS->CTL0 |= (rselVal)<<CS_CTL0_DCORSEL_OFS;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_disableDCOExternalResistor(void)
{
/* Unlocking the module */
CS->KEY = CS_KEY;
BITBAND_PERI(CS->CTL0,CS_CTL0_DCORES_OFS) = 0;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_setDCOCenteredFrequency(uint32_t dcoFreq)
{
ASSERT(
dcoFreq == CS_DCO_FREQUENCY_1_5 || dcoFreq == CS_DCO_FREQUENCY_3
|| dcoFreq == CS_DCO_FREQUENCY_6
|| dcoFreq == CS_DCO_FREQUENCY_12
|| dcoFreq == CS_DCO_FREQUENCY_24
|| dcoFreq == CS_DCO_FREQUENCY_48);
/* Unlocking the CS Module */
CS->KEY = CS_KEY;
/* Resetting Tuning Parameters and Setting the frequency */
CS->CTL0 = ((CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dcoFreq);
/* Locking the CS Module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_tuneDCOFrequency(int16_t tuneParameter)
{
CS->KEY = CS_KEY;
uint16_t dcoTuneMask = 0x1FFF;
uint16_t dcoTuneSigned = 0x1000;
if (TLV->HWREV > DEVICE_PG1_1) {
dcoTuneMask = 0x3FF;
dcoTuneSigned = 0x200;
}
if (tuneParameter < 0)
{
CS->CTL0 = ((CS->CTL0 & ~dcoTuneMask) | (tuneParameter
& dcoTuneMask) | dcoTuneSigned);
}
else
{
CS->CTL0 = ((CS->CTL0 & ~dcoTuneMask) | (tuneParameter
& dcoTuneMask));
}
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
uint32_t CS_getDCOFrequency(void)
{
float dcoConst;
int32_t calVal;
uint32_t centeredFreq;
int16_t dcoTune;
uint_fast8_t tlvLength;
SysCtl_CSCalTLV_Info *csInfo;
uint32_t retVal;
centeredFreq = _CSGetDOCFrequency();
/* Parsing the TLV and getting the maximum erase pulses */
SysCtl_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**)&csInfo);
if(tlvLength == 0)
{
return centeredFreq;
}
/* Checking to see if we need to do signed conversion */
if ( TLV->HWREV > DEVICE_PG1_1)
{
dcoTune = CS->CTL0 & 0x3FF;
if (dcoTune & 0x200)
{
dcoTune = dcoTune | 0xFE00;
}
}
else
{
dcoTune = CS->CTL0 & 0x1FFF;
if (dcoTune & 0x1000)
{
dcoTune = dcoTune | 0xF000;
}
}
if (dcoTune == 0)
return (uint32_t) centeredFreq;
/* DCORSEL = 5 */
if ((centeredFreq == 48000000) && ( TLV->HWREV > DEVICE_PG1_1))
{
/* External Resistor */
if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
{
dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL5);
calVal = csInfo->rDCOER_FCAL_RSEL5;
}
/* Internal Resistor */
else
{
dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL5);
calVal = csInfo->rDCOIR_FCAL_RSEL5;
}
}
/* DCORSEL = 4 */
else
{
/* External Resistor */
if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
{
dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL04);
calVal = csInfo->rDCOER_FCAL_RSEL04;
}
/* Internal Resistor */
else
{
dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL04);
calVal = csInfo->rDCOIR_FCAL_RSEL04;
}
}
if( TLV->HWREV > DEVICE_PG1_1 )
{
retVal = (uint32_t) (centeredFreq)
/ (1 - ((dcoConst * dcoTune)
/ ((1 + dcoConst * (768 - calVal)))));
}
else
{
retVal = (uint32_t) (centeredFreq)
/ (1 - ((dcoConst * dcoTune)
/ (8 * (1 + dcoConst * (768 - calVal)))));
}
return retVal;
}
void CS_setDCOFrequency(uint32_t dcoFrequency)
{
int32_t nomFreq, calVal, dcoSigned;
int16_t dcoTune;
float dcoConst;
bool rsel5 = false;
dcoSigned = (int32_t) dcoFrequency;
uint_fast8_t tlvLength;
SysCtl_CSCalTLV_Info *csInfo;
if (dcoFrequency < 2000000)
{
nomFreq = CS_15MHZ;
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_1_5);
} else if (dcoFrequency < 4000000)
{
nomFreq = CS_3MHZ;
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_3);
} else if (dcoFrequency < 8000000)
{
nomFreq = CS_6MHZ;
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_6);
} else if (dcoFrequency < 16000000)
{
nomFreq = CS_12MHZ;
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
} else if (dcoFrequency < 32000000)
{
nomFreq = CS_24MHZ;
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_24);
} else if (dcoFrequency < 640000001)
{
nomFreq = CS_48MHZ;
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
rsel5 = true;
} else
{
ASSERT(false);
return;
}
/* Parsing the TLV and getting the maximum erase pulses */
SysCtl_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**)&csInfo);
if(dcoFrequency == nomFreq || tlvLength == 0)
{
CS_tuneDCOFrequency(0);
return;
}
if ((rsel5) && ( TLV->HWREV > DEVICE_PG1_1))
{
/* External Resistor*/
if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
{
dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL5);
calVal = csInfo->rDCOER_FCAL_RSEL5;
}
/* Internal Resistor */
else
{
dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL5);
calVal = csInfo->rDCOIR_FCAL_RSEL5;
}
}
/* DCORSEL = 4 */
else
{
/* External Resistor */
if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
{
dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL04);
calVal = csInfo->rDCOER_FCAL_RSEL04;
}
/* Internal Resistor */
else
{
dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL04);
calVal = csInfo->rDCOIR_FCAL_RSEL04;
}
}
if ( TLV->HWREV > DEVICE_PG1_1)
dcoTune = (int16_t) (((dcoSigned - nomFreq)
* (1.0f + dcoConst * (768.0f - calVal)))
/ (dcoSigned * dcoConst));
else
dcoTune = (int16_t) (((dcoSigned - nomFreq)
* (1.0f + dcoConst * (768.0f - calVal)) * 8.0f)
/ (dcoSigned * dcoConst));
CS_tuneDCOFrequency(dcoTune);
}
uint32_t CS_getBCLK(void)
{
if (BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS))
return _CSComputeCLKFrequency(CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
else
return _CSComputeCLKFrequency(CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
}
uint32_t CS_getHSMCLK(void)
{
uint32_t wSource, wDivider;
wSource = (CS->CTL1 & CS_CTL1_SELS_MASK) >> CS_HSMCLK_SRC_BITPOS;
wDivider = ((CS->CTL1 & CS_CTL1_DIVHS_MASK) << CS_HSMCLK_DIV_BITPOS);
return _CSComputeCLKFrequency(wSource, wDivider);
}
uint32_t CS_getACLK(void)
{
uint32_t wSource, wDivider;
wSource = (CS->CTL1 & CS_CTL1_SELA_MASK) >> CS_ACLK_SRC_BITPOS;
wDivider = ((CS->CTL1 & CS_CTL1_DIVA_MASK) << CS_ACLK_DIV_BITPOS);
return _CSComputeCLKFrequency(wSource, wDivider);
}
uint32_t CS_getSMCLK(void)
{
uint32_t wDivider, wSource;
wSource = (CS->CTL1 & CS_CTL1_SELS_MASK) >> CS_HSMCLK_SRC_BITPOS;
wDivider = ((CS->CTL1 & CS_CTL1_DIVS_MASK));
return _CSComputeCLKFrequency(wSource, wDivider);
}
uint32_t CS_getMCLK(void)
{
uint32_t wSource, wDivider;
wSource = (CS->CTL1 & CS_CTL1_SELM_MASK) << CS_MCLK_SRC_BITPOS;
wDivider = ((CS->CTL1 & CS_CTL1_DIVM_MASK) << CS_MCLK_DIV_BITPOS);
return _CSComputeCLKFrequency(wSource, wDivider);
}
void CS_enableFaultCounter(uint_fast8_t counterSelect)
{
ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER ||
counterSelect == CS_HFXT_FAULT_COUNTER);
/* Unlocking the module */
CS->KEY = CS_KEY;
if (counterSelect == CS_HFXT_FAULT_COUNTER)
{
BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTHF_EN_OFS) = 1;
} else
{
BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTLF_EN_OFS) = 1;
}
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_disableFaultCounter(uint_fast8_t counterSelect)
{
ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER ||
counterSelect == CS_HFXT_FAULT_COUNTER);
/* Unlocking the module */
CS->KEY = CS_KEY;
if (counterSelect == CS_HFXT_FAULT_COUNTER)
{
BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTHF_EN_OFS) = 0;
} else
{
BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTLF_EN_OFS) = 0;
}
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_resetFaultCounter(uint_fast8_t counterSelect)
{
ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER ||
counterSelect == CS_HFXT_FAULT_COUNTER);
/* Unlocking the module */
CS->KEY = CS_KEY;
if (counterSelect == CS_HFXT_FAULT_COUNTER)
{
BITBAND_PERI(CS->CTL3, CS_CTL3_RFCNTHF_OFS) = 1;
} else
{
BITBAND_PERI(CS->CTL3, CS_CTL3_RFCNTLF_OFS) = 1;
}
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_startFaultCounter(uint_fast8_t counterSelect, uint_fast8_t countValue)
{
ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER ||
counterSelect == CS_HFXT_FAULT_COUNTER);
ASSERT(countValue == CS_FAULT_COUNTER_4096_CYCLES ||
countValue == CS_FAULT_COUNTER_8192_CYCLES ||
countValue == CS_FAULT_COUNTER_16384_CYCLES ||
countValue == CS_FAULT_COUNTER_32768_CYCLES);
/* Unlocking the module */
CS->KEY = CS_KEY;
if (counterSelect == CS_HFXT_FAULT_COUNTER)
{
CS->CTL3 = ((CS->CTL3 & ~CS_CTL3_FCNTHF_MASK) | (countValue << 4));
} else
{
CS->CTL3 = ((CS->CTL3 & ~CS_CTL3_FCNTLF_MASK) | (countValue));
}
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_enableInterrupt(uint32_t flags)
{
/* Unlocking the module */
CS->KEY = CS_KEY;
CS->IE |= flags;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_disableInterrupt(uint32_t flags)
{
/* Unlocking the module */
CS->KEY = CS_KEY;
CS->IE &= ~flags;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
uint32_t CS_getInterruptStatus(void)
{
return CS->IFG;
}
uint32_t CS_getEnabledInterruptStatus(void)
{
return CS_getInterruptStatus() & CS->IE;
}
void CS_clearInterruptFlag(uint32_t flags)
{
/* Unlocking the module */
CS->KEY = CS_KEY;
CS->CLRIFG |= flags;
/* Locking the module */
BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
void CS_registerInterrupt(void (*intHandler)(void))
{
//
// Register the interrupt handler, returning an error if an error occurs.
//
Interrupt_registerInterrupt(INT_CS, intHandler);
//
// Enable the system control interrupt.
//
Interrupt_enableInterrupt(INT_CS);
}
void CS_unregisterInterrupt(void)
{
//
// Disable the interrupt.
//
Interrupt_disableInterrupt(INT_CS);
//
// Unregister the interrupt handler.
//
Interrupt_unregisterInterrupt(INT_CS);
}