empty_project_28377D/device/driverlib/sysctl.c

1467 lines
45 KiB
C

//###########################################################################
//
// FILE: sysctl.c
//
// TITLE: C28x system control driver.
//
//###########################################################################
// $Copyright:
// Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com
//
// 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.
// $
//###########################################################################
#include "cputimer.h"
#include "sysctl.h"
//
// Define to isolate inline assembly
//
#define SYSCTL_DELAY __asm(" .if __TI_EABI__\n" \
" .asg SysCtl_delay , _SysCtl_delay\n" \
" .endif\n" \
" .def _SysCtl_delay\n" \
" .sect \".TI.ramfunc\"\n" \
" .global _SysCtl_delay\n" \
"_SysCtl_delay:\n" \
" SUB ACC,#1\n" \
" BF _SysCtl_delay, GEQ\n" \
" LRETR\n")
#define SYSCTL_CLRC_DBGM __asm(" CLRC DBGM")
//
// Define Timer1 and Timer2 seed values
//
#define TMR1SYSCLKCTR 0xF0000000U
#define TMR2INPCLKCTR 0x800U
#define XTAL_CPUTIMER_PERIOD 1023U
//
// Macro used for adding delay between 2 consecutive writes to CLKSRCCTL1
// register.
// Delay = 300 NOPs
//
#define SYSCTL_CLKSRCCTL1_DELAY asm(" RPT #250 || NOP \n RPT #50 || NOP")
//*****************************************************************************
//
// SysCtl_delay()
//
//*****************************************************************************
SYSCTL_DELAY;
static void
SysCtl_pollCpuTimer(void)
{
//
// Delay for 1 ms while the XTAL powers up
//
// 2000 loops, 5 cycles per loop + 9 cycles overhead = 10009 cycles
//
SysCtl_delay(2000);
//
// Wait for cpu timer 2 to overflow
//
while(CPUTimer_getTimerOverflowStatus(CPUTIMER2_BASE) == false);
{
//
// If your application is stuck in this loop, please check if the
// input clock source is valid.
//
}
//
// Clear cpu timer 2 overflow flag
//
CPUTimer_clearOverflowFlag(CPUTIMER2_BASE);
}
//*****************************************************************************
//
// SysCtl_getClock()
//
//*****************************************************************************
uint32_t
SysCtl_getClock(uint32_t clockInHz)
{
uint32_t temp;
uint32_t oscSource;
uint32_t clockOut;
//
// Don't proceed if an MCD failure is detected.
//
if(SysCtl_isMCDClockFailureDetected())
{
//
// OSCCLKSRC2 failure detected. Returning the INTOSC1 rate. You need
// to handle the MCD and clear the failure.
//
clockOut = SYSCTL_DEFAULT_OSC_FREQ;
}
else
{
//
// If one of the internal oscillators is being used, start from the
// known default frequency. Otherwise, use clockInHz parameter.
//
oscSource = HWREG(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &
(uint32_t)SYSCTL_CLKSRCCTL1_OSCCLKSRCSEL_M;
if((oscSource == (SYSCTL_OSCSRC_OSC2 >> SYSCTL_OSCSRC_S)) ||
(oscSource == (SYSCTL_OSCSRC_OSC1 >> SYSCTL_OSCSRC_S)))
{
clockOut = SYSCTL_DEFAULT_OSC_FREQ;
}
else
{
clockOut = clockInHz;
}
//
// If the PLL is enabled calculate its effect on the clock
//
if((HWREG(CLKCFG_BASE + SYSCTL_O_SYSPLLCTL1) &
(SYSCTL_SYSPLLCTL1_PLLEN | SYSCTL_SYSPLLCTL1_PLLCLKEN)) == 3U)
{
//
// Calculate portion from fractional multiplier
//
temp = (clockInHz * ((HWREG(CLKCFG_BASE + SYSCTL_O_SYSPLLMULT) &
SYSCTL_SYSPLLMULT_FMULT_M) >>
SYSCTL_SYSPLLMULT_FMULT_S)) / 4U;
//
// Calculate integer multiplier and fixed divide by 2
//
clockOut = clockOut * ((HWREG(CLKCFG_BASE + SYSCTL_O_SYSPLLMULT) &
SYSCTL_SYSPLLMULT_IMULT_M) >>
SYSCTL_SYSPLLMULT_IMULT_S);
//
// Add in fractional portion
//
clockOut += temp;
}
if((HWREG(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) &
SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M) != 0U)
{
clockOut /= (2U * (HWREG(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) &
SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M));
}
}
return(clockOut);
}
//*****************************************************************************
//
// SysCtl_getAuxClock()
//
//*****************************************************************************
uint32_t SysCtl_getAuxClock(uint32_t clockInHz)
{
uint32_t temp;
uint32_t oscSource;
uint32_t clockOut;
oscSource = HWREG(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) &
(uint32_t)SYSCTL_CLKSRCCTL2_AUXOSCCLKSRCSEL_M;
//
// If one of the internal oscillators is being used, start from the
// known default frequency. Otherwise, use clockInHz parameter.
//
if(oscSource == (SYSCTL_AUXPLL_OSCSRC_OSC2 >> SYSCTL_OSCSRC_S))
{
//
// 10MHz Internal Clock
//
clockOut = SYSCTL_DEFAULT_OSC_FREQ;
}
else
{
clockOut = clockInHz;
}
//
// If the PLL is enabled calculate its effect on the clock
//
if((HWREG(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) &
(SYSCTL_AUXPLLCTL1_PLLEN | SYSCTL_AUXPLLCTL1_PLLCLKEN)) == 3U)
{
//
// Calculate portion from fractional multiplier
//
temp = (clockInHz * ((HWREG(CLKCFG_BASE + SYSCTL_O_AUXPLLMULT) &
SYSCTL_AUXPLLMULT_FMULT_M) >>
SYSCTL_AUXPLLMULT_FMULT_S)) / 4U;
//
// Calculate integer multiplier
//
clockOut = clockOut * ((HWREG(CLKCFG_BASE + SYSCTL_O_AUXPLLMULT) &
SYSCTL_AUXPLLMULT_IMULT_M) >>
SYSCTL_AUXPLLMULT_IMULT_S);
//
// Add in fractional portion
//
clockOut += temp;
}
clockOut /= (1U << (HWREG(CLKCFG_BASE + SYSCTL_O_AUXCLKDIVSEL) &
SYSCTL_AUXCLKDIVSEL_AUXPLLDIV_M));
return(clockOut);
}
//*****************************************************************************
//
// SysCtl_setClock()
//
//*****************************************************************************
bool
SysCtl_setClock(uint32_t config)
{
uint16_t divSel;
uint16_t iMult = 0U, fMult = 0U, pllMult = 0U, div;
bool status, sysclkInvalidFreq = true;
uint16_t i, tempSCSR, tempWDCR, tempWDWCR, intStatus;
uint16_t t1TCR, t1TPR, t1TPRH, t2TCR, t2TPR, t2TPRH, t2CLKCTL;
uint32_t t1PRD, t2PRD, ctr1;
float32_t sysclkToInClkError, mult;
//
// Check the arguments.
//
ASSERT((config & SYSCTL_OSCSRC_M) != SYSCTL_OSCSRC_M); // 3 is not valid
//
// Don't proceed to the PLL initialization if an MCD failure is detected.
//
if(SysCtl_isMCDClockFailureDetected())
{
//
// OSCCLKSRC2 failure detected. Returning false. You'll need to clear
// the MCD error.
//
status = false;
}
else
{
//
// Configure oscillator source
//
SysCtl_selectOscSource(config & SYSCTL_OSCSRC_M);
//
// Bypass PLL
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLCTL1) &=
~SYSCTL_SYSPLLCTL1_PLLCLKEN;
EDIS;
//
// Delay of at least 120 OSCCLK cycles required post PLL bypass
//
SysCtl_delay(23U);
//
// Configure PLL if enabled
//
EALLOW;
if((config & SYSCTL_PLL_ENABLE) == SYSCTL_PLL_ENABLE)
{
if((HWREGH(DEVCFG_BASE + SYSCTL_O_SYSDBGCTL) &
SYSCTL_SYSDBGCTL_BIT_0) != 0U)
{
//
// The user can optionally insert handler code here. This will
// only be executed if a watchdog reset occurred after a failed
// system PLL initialization. See your device user's guide for
// more information.
//
// If the application has a watchdog reset handler, this bit
// should be checked to determine if the watchdog reset
// occurred because of the PLL.
//
// No action here will continue with retrying the PLL as
// normal.
//
}
//
// Set dividers to /1
//
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) = 0U;
//
// Get the PLL multiplier settings from config
//
iMult |= (uint16_t)(config & SYSCTL_IMULT_M);
fMult |= (uint16_t)((config & SYSCTL_FMULT_M) >> SYSCTL_FMULT_S);
pllMult |= (iMult << SYSCTL_SYSPLLMULT_IMULT_S) |
(fMult << SYSCTL_SYSPLLMULT_FMULT_S);
//
// Lock the PLL five times. This helps ensure a successful start.
// Five is the minimum recommended number. The user can increase
// this number according to allotted system initialization time.
//
for(i = 0U; i < 5U; i++)
{
//
// Turn off PLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLCTL1) &=
~SYSCTL_SYSPLLCTL1_PLLEN;
asm(" RPT #60 || NOP");
//
// Write multiplier, which automatically turns on the PLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLMULT) = pllMult;
//
// Wait for the SYSPLL lock counter
//
while((HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLSTS) &
SYSCTL_SYSPLLSTS_LOCKS) == 0U)
{
//
// Consider to servicing the watchdog using
// SysCtl_serviceWatchdog()
//
}
}
}
//
// Configure Dividers. Set divider to produce slower output frequency
// to limit current increase.
//
divSel = (uint16_t)(config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S;
if(divSel != (126U / 2U))
{
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) &
~(uint16_t)SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M) | (divSel + 1U);
}
else
{
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) &
~(uint16_t)SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M) | divSel;
}
//
// *CAUTION*
// It is recommended to use the following watchdog code to monitor the
// PLLstartup sequence. If your application has already cleared the
// watchdog SCRS[WDOVERRIDE] bit this cannot be done. It is recommended
// not to clear this bit until after the PLL has been initiated.
//
//
// Backup User Watchdog
//
tempSCSR = HWREGH(WD_BASE + SYSCTL_O_SCSR);
tempWDCR = HWREGH(WD_BASE + SYSCTL_O_WDCR);
tempWDWCR = HWREGH(WD_BASE + SYSCTL_O_WDWCR);
//
// Disable windowed functionality, reset counter
//
HWREGH(WD_BASE + SYSCTL_O_WDWCR) = 0x0U;
SysCtl_serviceWatchdog();
//
// Disable global interrupts
//
intStatus = __disable_interrupts();
//
// Configure for watchdog reset and to run at max frequency
//
EALLOW;
HWREGH(WD_BASE + SYSCTL_O_SCSR) = 0x0U;
HWREGH(WD_BASE + SYSCTL_O_WDCR) = SYSCTL_WD_CHKBITS;
//
// This bit is reset only by power-on-reset (POR) and will not be
// cleared by a WD reset
//
HWREGH(DEVCFG_BASE + SYSCTL_O_SYSDBGCTL) |= SYSCTL_SYSDBGCTL_BIT_0;
//
// Enable PLLSYSCLK is fed from system PLL clock
//
HWREGH(CLKCFG_BASE +
SYSCTL_O_SYSPLLCTL1) |= SYSCTL_SYSPLLCTL1_PLLCLKEN;
EDIS;
//
// Delay to ensure system is clocking from PLL prior to clearing
// status bit
//
SysCtl_delay(3U);
//
// Slip Bit Monitor and SYSCLK Frequency Check using timers
// Re-lock routine for SLIP condition or if SYSCLK and CLKSRC timer
// counts are off by +/- 10%. At a minimum, SYSCLK check is performed.
// Re-lock attempt is carried out if SLIPS bit is set.
// This while loop is monitored by watchdog.
// In the event that the PLL does not successfully lock, the loop will
// be aborted by watchdog reset.
//
while(((config & SYSCTL_PLL_ENABLE) == SYSCTL_PLL_ENABLE) &&
(sysclkInvalidFreq == true))
{
EALLOW;
//
// Perform PLL re-lock only if SLIPS bit is set, otherwise monitor
// SYSCLK frequency with timers
//
if((HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLSTS) &
SYSCTL_SYSPLLSTS_SLIPS) == 1U)
{
//
// Bypass PLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLCTL1) &=
~SYSCTL_SYSPLLCTL1_PLLCLKEN;
//
// Delay of at least 120 OSCCLK cycles required post PLL bypass
//
SysCtl_delay(23U);
//
// Turn off PLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLCTL1) &=
~SYSCTL_SYSPLLCTL1_PLLEN;
SysCtl_delay(3U);
//
// Write multiplier, which automatically turns on the PLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLMULT) |= pllMult;
//
// Wait for the SYSPLL lock counter
//
while((HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLSTS) &
SYSCTL_SYSPLLSTS_LOCKS) == 0U)
{
;
}
//
// Enable PLLSYSCLK is fed from system PLL clock
//
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSPLLCTL1) |=
SYSCTL_SYSPLLCTL1_PLLCLKEN;
//
// Delay to ensure system is clocking from PLL prior to
// clearing status bit
//
SysCtl_delay(3U);
}
//
// Backup timer1 and timer2 settings
//
t1TCR = HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR);
t1PRD = HWREG(CPUTIMER1_BASE + CPUTIMER_O_PRD);
t1TPR = HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TPR);
t1TPRH = HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TPRH);
t2CLKCTL = HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL);
t2TCR = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR);
t2PRD = HWREG(CPUTIMER2_BASE + CPUTIMER_O_PRD);
t2TPR = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPR);
t2TPRH = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPRH);
//
// Set up timers 1 and 2
// Configure timer1 to count SYSCLK cycles
//
//
// Stop timer 1
// Seed timer1 counter
// Set sysclock divider
// Reload timer with value in PRD
// Clear interrupt flag
// Enable interrupt
//
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TSS;
HWREG(CPUTIMER1_BASE + CPUTIMER_O_PRD) = (uint32_t)TMR1SYSCLKCTR;
HWREG(CPUTIMER1_BASE + CPUTIMER_O_TPR) = 0U;
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TRB;
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TIF;
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TIE;
//
// Configure timer2 to count Input clock cycles
//
switch (config & SYSCTL_OSCSRC_M)
{
case SYSCTL_OSCSRC_OSC1:
//
// Clk Src = INT_OSC1
//
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) &=
~SYSCTL_TMR2CLKCTL_TMR2CLKSRCSEL_M;
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) |= 1U;
break;
case SYSCTL_OSCSRC_OSC2:
//
// Clk Src = INT_OSC2
//
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) &=
~SYSCTL_TMR2CLKCTL_TMR2CLKSRCSEL_M;
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) |= 2U;
break;
case SYSCTL_OSCSRC_XTAL:
//
// Clk Src = XTAL
//
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) &=
~SYSCTL_TMR2CLKCTL_TMR2CLKSRCSEL_M;
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) |= 3U;
break;
default:
//
// Do nothing. Not a valid clock source value.
//
break;
}
//
// Clear interrupt flag
// Enable interrupt
// Stop timer 2
// Seed timer2 counter
// Set sysclock divider
// Reload timer with value in PRD
//
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TIF;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TIE;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TSS;
HWREG(CPUTIMER2_BASE + CPUTIMER_O_PRD) = (uint32_t)TMR2INPCLKCTR;
HWREG(CPUTIMER2_BASE + CPUTIMER_O_TPR) = 0U;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TRB;
//
// Stop/Start timer counters
//
//
// Stop timer 1
// Stop timer 2
// Reload timer1 with value in PRD
// Reload timer2 with value in PRD
// Clear timer2 interrupt flag
// Start timer2
// Start timer1
//
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TSS;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TSS;
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TRB;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TRB;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TIF;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) &= ~CPUTIMER_TCR_TSS;
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) &= ~CPUTIMER_TCR_TSS;
//
// Wait for Timers - Stop if either timer overflows
//
while(((HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) &
CPUTIMER_TCR_TIF) == 0U) &&
((HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) &
CPUTIMER_TCR_TIF) == 0U))
{
;
}
//
// Stop timer 1 and 2
//
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TSS;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TSS;
//
// Calculate elapsed counts on timer1
//
ctr1 = (uint32_t)TMR1SYSCLKCTR - HWREG(CPUTIMER1_BASE +
CPUTIMER_O_TIM);
//
// Restore timer settings
//
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) = t1TCR;
HWREG(CPUTIMER1_BASE + CPUTIMER_O_PRD) = t1PRD;
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TPR) = t1TPR;
HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TPRH) = t1TPRH;
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) = t2CLKCTL;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) = t2TCR;
HWREG(CPUTIMER2_BASE + CPUTIMER_O_PRD) = t2PRD;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPR) = t2TPR;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPRH) = t2TPRH;
//
// Calculate Clock Error:
// Error = (mult/div) - (timer1 count/timer2 count)
//
mult = (float32_t)iMult + ((float32_t)fMult / 4.0F);
if((HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) & 0x3FU) == 0U)
{
div = 1U;
}
else
{
div = (HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) &
0x3FU) << 1;
}
sysclkToInClkError = (mult / (float32_t)div) -
((float32_t)ctr1 / (float32_t)TMR2INPCLKCTR);
//
// sysclkInvalidFreq will be set to true if sysclkToInClkError is
// off by 10%
//
sysclkInvalidFreq = ((sysclkToInClkError > 0.10F) ||
(sysclkToInClkError < -0.10F));
EDIS;
}
//
// Clear bit
//
EALLOW;
HWREGH(DEVCFG_BASE + SYSCTL_O_SYSDBGCTL) &= ~SYSCTL_SYSDBGCTL_BIT_0;
EDIS;
//
// Restore user watchdog, first resetting counter
//
SysCtl_serviceWatchdog();
//
// Set the KEY bits and make sure not to set the WDOVERRIDE bit
//
EALLOW;
HWREGH(WD_BASE + SYSCTL_O_WDCR) = tempWDCR | SYSCTL_WD_CHKBITS;
HWREGH(WD_BASE + SYSCTL_O_WDWCR) = tempWDWCR;
HWREGH(WD_BASE + SYSCTL_O_SCSR) = tempSCSR & ~SYSCTL_SCSR_WDOVERRIDE;
EDIS;
//
// Restore state of ST1[INTM]. This was set by the
// __disable_interrupts() intrinsic previously.
//
if((intStatus & 0x1U) == 0U)
{
EINT;
}
//
// Restore state of ST1[DBGM]. This was set by the
// __disable_interrupts() intrinsic previously.
//
if((intStatus & 0x2U) == 0U)
{
SYSCTL_CLRC_DBGM;
}
//
// ~200 PLLSYSCLK delay to allow voltage regulator to stabilize prior
// to increasing entire system clock frequency.
//
SysCtl_delay(40U);
//
// Set the divider to user value
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) &
~SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M) | divSel;
EDIS;
status = true;
}
return(status);
}
//*****************************************************************************
//
// SysCtl_setAuxClock()
//
//*****************************************************************************
void SysCtl_setAuxClock(uint32_t config)
{
uint16_t pllMult = 0U;
uint16_t counter = 0U, started = 0U, attempts = 0U;
uint16_t mult;
uint16_t i, t2TCR, t2TPR, t2TPRH, t2CLKCTL;
uint32_t t2PRD;
//
// Check the arguments
//
ASSERT((config & SYSCTL_OSCSRC_M) != SYSCTL_OSCSRC_M); // 3 is not valid
//
// Bypass PLL
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) &= ~SYSCTL_AUXPLLCTL1_PLLCLKEN;
EDIS;
//
// Delay of at least 120 OSCCLK cycles required post PLL bypass
//
SysCtl_delay(23U);
//
// Configure oscillator source
//
SysCtl_selectOscSourceAuxPLL(config & SYSCTL_OSCSRC_M);
//
// Get the PLL multiplier settings from config
//
pllMult |= (uint16_t)((config & SYSCTL_IMULT_M) <<
SYSCTL_AUXPLLMULT_IMULT_S);
pllMult |= (uint16_t)(((config & SYSCTL_FMULT_M) >> SYSCTL_FMULT_S) <<
SYSCTL_AUXPLLMULT_FMULT_S);
//
// Get the PLL multipliers currently programmed
//
mult = (uint16_t)((HWREG(CLKCFG_BASE + SYSCTL_O_AUXPLLMULT) &
(uint32_t)SYSCTL_AUXPLLMULT_IMULT_M) >>
(uint32_t)SYSCTL_AUXPLLMULT_IMULT_S);
mult |= (uint16_t)(HWREG(CLKCFG_BASE + SYSCTL_O_AUXPLLMULT) &
SYSCTL_AUXPLLMULT_FMULT_M);
//
// Lock PLL only if the multipliers need update
//
if(mult != pllMult)
{
//
// Configure PLL if enabled
//
if((config & SYSCTL_AUXPLL_ENABLE) == SYSCTL_AUXPLL_ENABLE)
{
//
// Backup Timer 2 settings
//
t2CLKCTL = HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL);
t2TCR = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR);
t2PRD = HWREG(CPUTIMER2_BASE + CPUTIMER_O_PRD);
t2TPR = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPR);
t2TPRH = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPRH);
//
// Configure Timer 2 for AUXPLL as source in known configuration
// - Clock source to AUXPLL
// - Clock divider to divide by 1
// - Small period to detect overflow
// - Interrupt disabled
//
EALLOW;
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) = 6U;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TSS;
HWREG(CPUTIMER2_BASE + CPUTIMER_O_PRD) = 10U;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPR) = 0U;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPRH) = 0U;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) &= ~CPUTIMER_TCR_TIE;
//
// Set AUX Divide by 8 to ensure that AUXPLLCLK <= SYSCLK / 2
// while using Timer 2
//
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXCLKDIVSEL) = 0x3U;
EDIS;
//
// Lock the PLL up to five times.
//CPU Timer 2 will monitor a successful
// lock and break out of the loop earlier if detected.
//
while((counter < 5U) && (started == 0U))
{
EALLOW;
//
// Turn off AUXPLL and delay for it to power down.
//
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) &=
~SYSCTL_AUXPLLCTL1_PLLEN;
SysCtl_delay(3U);
//
// Set integer and fractional multiplier, which automatically
// turns on the PLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLMULT) |= pllMult;
//
// Enable AUXPLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) |=
SYSCTL_AUXPLLCTL1_PLLEN;
EDIS;
//
// Wait for the AUXPLL lock counter
//
while((HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLSTS) &
SYSCTL_AUXPLLSTS_LOCKS) != 1U)
{
//
// Consider to servicing the watchdog using
// SysCtl_serviceWatchdog()
//
}
//
// Enable AUXPLLCLK to be fed from AUXPLL
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) |=
SYSCTL_AUXPLLCTL1_PLLCLKEN;
SysCtl_delay(3U);
//
// CPU Timer 2 will now be setup to be clocked from AUXPLLCLK.
// This is used to test that the PLL has successfully started.
//
// Reload and start the timer
//
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TRB;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) &= ~CPUTIMER_TCR_TSS;
//
// Check to see timer is counting properly
//
for(i = 0U; i < 1000U; i++)
{
//
// Check overflow flag
//
if((HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) &
CPUTIMER_TCR_TIF) != 0U)
{
//
// Clear overflow flag
//
HWREGH(CPUTIMER2_BASE +
CPUTIMER_O_TCR) |= CPUTIMER_TCR_TIF;
//
// Set flag to indicate PLL started and break out of
// for-loop
//
started = 1U;
break;
}
}
//
// Stop timer
//
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TSS;
counter++;
EDIS;
}
if(started == 0U)
{
//
// AUX PLL may not have started. Reset multiplier to 0 (bypass
// PLL).
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLMULT) = 0U;
EDIS;
//
// The user should put some handler code here based on how
// this condition should be handled in their application.
//
ESTOP0;
}
//
// Restore Timer 2 configuration
//
EALLOW;
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) = t2CLKCTL;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) = t2TCR;
HWREG(CPUTIMER2_BASE + CPUTIMER_O_PRD) = t2PRD;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPR) = t2TPR;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPRH) = t2TPRH;
//
// Reload period value
//
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TRB;
EDIS;
}
}
else
{
//
// Enable AUXPLLCLK to be fed from AUXPLL
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) |= SYSCTL_AUXPLLCTL1_PLLCLKEN;
SysCtl_delay(3U);
EDIS;
}
//
// Slip Bit Monitor
// Re-lock routine for SLIP condition
//
while(((HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLSTS) &
SYSCTL_AUXPLLSTS_SLIPS) != 0U) && (attempts < 10U) &&
((config & SYSCTL_AUXPLL_ENABLE) == SYSCTL_AUXPLL_ENABLE))
{
EALLOW;
//
// Bypass AUXPLL
//
HWREGH(CLKCFG_BASE +
SYSCTL_O_AUXPLLCTL1) &= ~SYSCTL_AUXPLLCTL1_PLLCLKEN;
//
// Delay of at least 120 OSCCLK cycles required post PLL bypass
//
SysCtl_delay(23U);
//
// Turn off AUXPLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) &= ~SYSCTL_AUXPLLCTL1_PLLEN;
SysCtl_delay(3U);
//
// Set integer and fractional multiplier, which automatically turns
// on the PLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLMULT) |= pllMult;
//
// Enable AUXPLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) |= SYSCTL_AUXPLLCTL1_PLLEN;
//
// Wait for the AUXPLL lock counter
//
while((HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLSTS) &
SYSCTL_AUXPLLSTS_LOCKS) != 1U)
{
//
// Consider to servicing the watchdog using
// SysCtl_serviceWatchdog()
//
}
//
// Enable AUXPLLCLK to be fed from AUXPLL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) |= SYSCTL_AUXPLLCTL1_PLLCLKEN;
SysCtl_delay(3U);
attempts++;
EDIS;
}
//
// Set divider to desired value
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXCLKDIVSEL) =
(uint16_t)(config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S;
EDIS;
}
//*****************************************************************************
//
// SysCtl_selectXTAL()
//
//*****************************************************************************
void
SysCtl_selectXTAL(void)
{
uint16_t t2TCR, t2TPR, t2TPRH, t2CLKCTL;
uint32_t t2PRD;
//
// Backup CPU timer2 settings
//
t2CLKCTL = HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL);
t2TCR = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR);
t2PRD = HWREG(CPUTIMER2_BASE + CPUTIMER_O_PRD);
t2TPR = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPR);
t2TPRH = HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPRH);
//
// Backup AUX clock settings
//
uint16_t clksrcctl2 = HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2);
uint16_t auxpllctl1 = HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1);
uint16_t auxclkdivsel = HWREGH(CLKCFG_BASE + SYSCTL_O_AUXCLKDIVSEL);
//
// Set AUX clock source to XTAL, bypass mode.
// AUXCLK is used as the CPUTimer Clock source. SYSCLK frequency must be
// atleast twice the frequency of AUXCLK. SYSCLK = INTOSC2(10MHz)
// Set the AUX divider to 8. The above condition will be met for XTAL
// frequencies up to 40MHz
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) &
~(SYSCTL_CLKSRCCTL2_AUXOSCCLKSRCSEL_M)) |
(1U << SYSCTL_CLKSRCCTL2_AUXOSCCLKSRCSEL_S);
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) = 0x0U;
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXCLKDIVSEL) = SYSCTL_AUXPLLCLK_DIV_8;
//
// Disable cpu timer 2 interrupt
//
CPUTimer_disableInterrupt(CPUTIMER2_BASE);
//
// Stop cpu timer 2 if running
//
CPUTimer_stopTimer(CPUTIMER2_BASE);
//
// Initialize cpu timer 2 period
//
CPUTimer_setPeriod(CPUTIMER2_BASE, XTAL_CPUTIMER_PERIOD);
//
// Set cpu timer 2 clock source to XTAL
//
CPUTimer_selectClockSource(CPUTIMER2_BASE, CPUTIMER_CLOCK_SOURCE_AUX,
CPUTIMER_CLOCK_PRESCALER_1);
//
// Clear cpu timer 2 overflow flag
//
CPUTimer_clearOverflowFlag(CPUTIMER2_BASE);
//
// Start cpu timer 2
//
CPUTimer_startTimer(CPUTIMER2_BASE);
EALLOW;
//
// Turn on XTAL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &= ~SYSCTL_CLKSRCCTL1_XTALOFF;
EDIS;
//
// Wait for the X1 clock to overflow cpu timer 2
//
SysCtl_pollCpuTimer();
//
// Select XTAL as the oscillator source
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) =
((HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &
(~SYSCTL_CLKSRCCTL1_OSCCLKSRCSEL_M)) |
(SYSCTL_OSCSRC_XTAL >> SYSCTL_OSCSRC_S));
EDIS;
//
// If a missing clock failure was detected, try waiting for the cpu timer 2
// to overflow again.
//
while(SysCtl_isMCDClockFailureDetected())
{
//
// Clear the MCD failure
//
SysCtl_resetMCD();
//
// Wait for the X1 clock to overflow cpu timer 2
//
SysCtl_pollCpuTimer();
//
// Select XTAL as the oscillator source
//
EALLOW;
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) =
((HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &
(~SYSCTL_CLKSRCCTL1_OSCCLKSRCSEL_M)) |
(SYSCTL_OSCSRC_XTAL >> SYSCTL_OSCSRC_S));
EDIS;
}
//
// Stop cpu timer 2
//
CPUTimer_stopTimer(CPUTIMER2_BASE);
//
// Restore Timer 2 configuration
//
EALLOW;
HWREGH(CPUSYS_BASE + SYSCTL_O_TMR2CLKCTL) = t2CLKCTL;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) = t2TCR;
HWREG(CPUTIMER2_BASE + CPUTIMER_O_PRD) = t2PRD;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPR) = t2TPR;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TPRH) = t2TPRH;
HWREGH(CPUTIMER2_BASE + CPUTIMER_O_TCR) |= CPUTIMER_TCR_TRB;
//
// Restore AUX clock settings
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) = clksrcctl2;
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXPLLCTL1) = auxpllctl1;
HWREGH(CLKCFG_BASE + SYSCTL_O_AUXCLKDIVSEL) = auxclkdivsel;
EDIS;
EDIS;
}
//*****************************************************************************
//
// SysCtl_selectOscSource()
//
//*****************************************************************************
void
SysCtl_selectOscSource(uint32_t oscSource)
{
ASSERT((oscSource == SYSCTL_OSCSRC_OSC1) ||
(oscSource == SYSCTL_OSCSRC_OSC2) ||
(oscSource == SYSCTL_OSCSRC_XTAL));
//
// Select the specified source.
//
EALLOW;
switch(oscSource)
{
case SYSCTL_OSCSRC_OSC2:
//
// Turn on INTOSC2
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &=
~SYSCTL_CLKSRCCTL1_INTOSC2OFF;
SYSCTL_CLKSRCCTL1_DELAY;
//
// Clk Src = INTOSC2
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &=
~SYSCTL_CLKSRCCTL1_OSCCLKSRCSEL_M;
SYSCTL_CLKSRCCTL1_DELAY;
//
// Turn off XTALOSC
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) |=
SYSCTL_CLKSRCCTL1_XTALOFF;
break;
case SYSCTL_OSCSRC_XTAL:
//
// Select XTAL in crystal mode and wait for it to power up
//
SysCtl_selectXTAL();
break;
case SYSCTL_OSCSRC_OSC1:
//
// Clk Src = INTOSC1
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &
~SYSCTL_CLKSRCCTL1_OSCCLKSRCSEL_M) |
(SYSCTL_OSCSRC_OSC1 >> SYSCTL_OSCSRC_S);
SYSCTL_CLKSRCCTL1_DELAY;
//
//Turn off XTALOSC
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) |=
SYSCTL_CLKSRCCTL1_XTALOFF;
break;
default:
//
// Do nothing. Not a valid oscSource value.
//
break;
}
EDIS;
}
//*****************************************************************************
//
// SysCtl_selectOscSourceAuxPLL()
//
//*****************************************************************************
void
SysCtl_selectOscSourceAuxPLL(uint32_t oscSource)
{
bool status = false;
EALLOW;
switch(oscSource)
{
case SYSCTL_AUXPLL_OSCSRC_OSC2:
//
// Turn on INTOSC2
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &=
~(SYSCTL_CLKSRCCTL1_INTOSC2OFF);
//
// Clk Src = INTOSC2
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) &=
~(SYSCTL_CLKSRCCTL2_AUXOSCCLKSRCSEL_M);
break;
case SYSCTL_AUXPLL_OSCSRC_XTAL:
//
// Turn on XTALOSC
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &=
~(SYSCTL_CLKSRCCTL1_XTALOFF);
//
// Clk Src = XTAL
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) &
~(SYSCTL_CLKSRCCTL2_AUXOSCCLKSRCSEL_M)) |
(1U << SYSCTL_CLKSRCCTL2_AUXOSCCLKSRCSEL_S);
break;
case SYSCTL_AUXPLL_OSCSRC_AUXCLKIN:
//
// Clk Src = AUXCLKIN
//
HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) &
~(SYSCTL_CLKSRCCTL2_AUXOSCCLKSRCSEL_M)) |
(2U << SYSCTL_CLKSRCCTL2_AUXOSCCLKSRCSEL_S);
break;
default:
//
// Do nothing. Not a valid clock source value.
//
break;
}
EDIS;
}
//*****************************************************************************
//
// SysCtl_getLowSpeedClock()
//
//*****************************************************************************
uint32_t
SysCtl_getLowSpeedClock(uint32_t clockInHz)
{
uint32_t clockOut;
//
// Get the main system clock
//
clockOut = SysCtl_getClock(clockInHz);
//
// Apply the divider to the main clock
//
if((HWREG(CLKCFG_BASE + SYSCTL_O_LOSPCP) &
SYSCTL_LOSPCP_LSPCLKDIV_M) != 0U)
{
clockOut /= (2U * (HWREG(CLKCFG_BASE + SYSCTL_O_LOSPCP) &
SYSCTL_LOSPCP_LSPCLKDIV_M));
}
return(clockOut);
}
//*****************************************************************************
//
// SysCtl_getDeviceParametric()
//
//*****************************************************************************
uint16_t
SysCtl_getDeviceParametric(SysCtl_DeviceParametric parametric)
{
uint32_t value;
//
// Get requested parametric value
//
switch(parametric)
{
case SYSCTL_DEVICE_QUAL:
//
// Qualification Status
//
value = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDL) &
SYSCTL_PARTIDL_QUAL_M) >> SYSCTL_PARTIDL_QUAL_S);
break;
case SYSCTL_DEVICE_PINCOUNT:
//
// Pin Count
//
value = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDL) &
SYSCTL_PARTIDL_PIN_COUNT_M) >>
SYSCTL_PARTIDL_PIN_COUNT_S);
break;
case SYSCTL_DEVICE_INSTASPIN:
//
// InstaSPIN Feature Set
//
value = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDL) &
SYSCTL_PARTIDL_INSTASPIN_M) >>
SYSCTL_PARTIDL_INSTASPIN_S);
break;
case SYSCTL_DEVICE_FLASH:
//
// Flash Size (KB)
//
value = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDL) &
SYSCTL_PARTIDL_FLASH_SIZE_M) >>
SYSCTL_PARTIDL_FLASH_SIZE_S);
break;
case SYSCTL_DEVICE_PARTID:
//
// PARTID Format Revision
//
value = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDL) &
SYSCTL_PARTIDL_PARTID_FORMAT_REVISION_M) >>
SYSCTL_PARTIDL_PARTID_FORMAT_REVISION_S);
break;
case SYSCTL_DEVICE_FAMILY:
//
// Device Family
//
value = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDH) &
SYSCTL_PARTIDH_FAMILY_M) >> SYSCTL_PARTIDH_FAMILY_S);
break;
case SYSCTL_DEVICE_PARTNO:
//
// Part Number
//
value = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDH) &
SYSCTL_PARTIDH_PARTNO_M) >> SYSCTL_PARTIDH_PARTNO_S);
break;
case SYSCTL_DEVICE_CLASSID:
//
// Class ID
//
value = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDH) &
SYSCTL_PARTIDH_DEVICE_CLASS_ID_M) >>
SYSCTL_PARTIDH_DEVICE_CLASS_ID_S);
break;
default:
//
// Not a valid value for PARTID register
//
value = 0U;
break;
}
return((uint16_t)value);
}