MSP40F5529/Exercise 3 - UCS
From Teknologisk videncenter
/**************************************************************************
Abstract: Device drivers for UCS - Unified Clock System for MSP430F5529
Platform: TI MSP430F5529 LaunchPad
Purpose.: The purpose this module is control over UCS - setting operating
speed to desired clock rates.
***************************************************************************
Author..: Henrik Thomsen <heth@mercantec.dk>
Company.: Mercantec ( http://www.mercantec.dk )
date....: Oct 2023
***************************************************************************
ToDo....: Description of problems and future extensions (TODO's)
Could use a cleanup and better comments
***************************************************************************
Modification log:
***************************************************************************
License: Free open software but WITHOUT ANY WARRANTY.
Terms..: see http://www.gnu.org/licenses
***************************************************************************/
//#include <msp430.h>
#include "io430.h"
// Prototypes
int ucs_mode1( void );
static void SetVcoreUp (unsigned int level);
//ucs_init - Initialize unified clock system
// MCLK - Master Clock - used by the CPU and system
// SMCLK - Subsystem Master Clock - Selectable by peripheral modules
// ACLK - Auxiliary Clock - Selectable by peripheral modules
// Hardware:
// MCU: MSP430F5529
// XT1: 32768 Hz
// XT2: 4 MHz
//Mode 1:
// MCLK = 25 MHz
// ACLK = 32K768
// SMCLK = 1 MHz
int ucs_init(int mode) {
int result;
switch ( mode ) {
case 1: result = ucs_mode1();
break;
default: result = 1; // Mode not existing error
}
return( result );
}
static int ucs_mode1( void ) {
volatile unsigned int i;
// Increase Vcore setting to level3 to support fsystem=25MHz
// NOTE: Change core voltage one level at a time..
SetVcoreUp (0x01);
SetVcoreUp (0x02);
SetVcoreUp (0x03);
//HeTh
// XT2 on with 4 MHz X-tal.
// Set SMCLK = 1 MHz
P5SEL = 0x3 << 2; // P5.[2-3] set to XT2
UCSCTL6 &= ~(0x3 << 14); //XT2DRIVE = 0: 4-8 MHz osc
UCSCTL6 &= ~(0x1 << 8); // XT2 on
UCSCTL5 |= 0x2 << 4; // SMCLK prescaler / 4 = 1 MHz
__delay_cycles(1000); // XT2 settle time
UCSCTL4 |= 0x5 << 4; // SMCLK = XT2
// XT1 on - low freq. mode 32K768
P5SEL |= 0x3 << 4; // P5.[4-5] set to XT1
UCSCTL6 &= ~0x1; // XT1 on
__delay_cycles(1000000);
UCSCTL4 &= ~( 0x7 << 0x8); // ACLK = XT1CLK
// UCSCTL3: FLLREFDIV=4 -> 4 Mhz / 4 =1 MHz and SELREF=XT2CLK
UCSCTL3 = 0x52;
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation
UCSCTL2 = 25-1; // Divide by 25 (24+1)
__bic_SR_register(SCG0); // Enable the FLL control loop
// Worst-case settling time for the DCO when the DCO range bits have been
// changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
// UG for optimization.
// 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle
__delay_cycles(782000);
// Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG);
return(0);
}
static void SetVcoreUp (unsigned int level)
{
// Open PMM registers for write
PMMCTL0_H = PMMPW_H;
// Set SVS/SVM high side new level
SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
// Set SVM low side to new level
SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
// Wait till SVM is settled
while ((PMMIFG & SVSMLDLYIFG) == 0);
// Clear already set flags
PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
// Set VCore to new level
PMMCTL0_L = PMMCOREV0 * level;
// Wait till new level reached
if ((PMMIFG & SVMLIFG))
while ((PMMIFG & SVMLVLRIFG) == 0);
// Set SVS/SVM low side to new level
SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
// Lock PMM registers for write access
PMMCTL0_H = 0x00;
}