BSP430  20141115
Board Support Package for MSP430 microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Bootstrapping a New Platform: Clock Signals

If the platform is already stable, you can just build this. If you're bootstrapping a platform you might need to build this with configBSP430_CONSOLE set to 0 so that the clock signals are exposed without attempting to create a serial port (which probably won't work if the clocks aren't what you expect).

main.c

/* Include the generic platform header. This assumes that
* #BSP430_PLATFORM_EXP430FR5739 (or another marker that identifies a
* platform BSP430 supports) has been defined for the preprocessor.
* If not, you may include the platform-specific version,
* e.g. <bsp430/platform/exp430g2.h>. */
/* We want to know the nominal clock speed so we can delay. */
#include <bsp430/clock.h>
/* We're going to use LEDs so we need the interface file */
/* We're going to want to differentially compare ACLK and SMCLK if we
* can */
/* We will use a console if we can. */
#if (BSP430_CONSOLE - 0)
#endif /* BSP430_CONSOLE */
/* LPM bits are relevant when figuring out what clocks might be
* enabled */
#include <bsp430/lpm.h>
#include <stdlib.h>
void main ()
{
#if (BSP430_CONSOLE - 0)
const char * help;
unsigned long smclk_Hz;
unsigned long aclk_Hz;
#endif /* BSP430_CONSOLE */
/* First thing you do in main is configure the platform. */
/* May not have console output yet. Indicate that we got past
* initialization, then expose the clocks and indicate that we've
* done so. */
}
/* If we support a console, dump out a bunch of configuration
* information. */
#if (BSP430_CONSOLE - 0)
cputtext("\nclocks " __DATE__ " " __TIME__ "\n");
cputtext("\nBSP430_PLATFORM_BOOT_CONFIGURE_LFXT1: ");
cputtext("\nBSP430_CLOCK_LFXT1_STABILIZATION_DELAY_CYCLES: ");
cputtext("\nBSP430_PLATFORM_BOOT_LFXT1_DELAY_SEC: ");
cputtext("\nBSP430_PLATFORM_BOOT_CONFIGURE_CLOCKS: ");
#if defined(__MSP430_HAS_BC2__)
#if (configBSP430_BC2_TRIM_TO_MCLK - 0)
cputtext("\nconfigBSP430_BC2_TRIM_TO_MCLK: 1");
#else /* configBSP430_BC2_TRIM_TO_MCLK */
cputtext("\nconfigBSP430_BC2_TRIM_TO_MCLK: 0");
#endif /* configBSP430_BC2_TRIM_TO_MCLK */
#if (BSP430_BC2_TRIM_TO_MCLK - 0)
cputtext("\nBSP430_BC2_TRIM_TO_MCLK: 1");
#else /* BSP430_BC2_TRIM_TO_MCLK */
cputtext("\nBSP430_BC2_TRIM_TO_MCLK: 0");
#endif /* BSP430_BC2_TRIM_TO_MCLK */
#endif /* BC2 */
#if defined(__MSP430_HAS_UCS__) || defined(__MSP430_HAS_UCS_RF__)
#if (configBSP430_UCS_TRIM_DCOCLKDIV - 0)
cputtext("\nconfigBSP430_UCS_TRIM_DCOCLKDIV: 1");
#else /* configBSP430_UCS_TRIM_DCOCLKDIV */
cputtext("\nconfigBSP430_UCS_TRIM_DCOCLKDIV: 0");
#endif /* configBSP430_UCS_TRIM_DCOCLKDIV */
#if (BSP430_UCS_TRIM_DCOCLKDIV - 0)
cputtext("\nBSP430_UCS_TRIM_DCOCLKDIV: 1");
#else /* BSP430_UCS_TRIM_DCOCLKDIV */
cputtext("\nBSP430_UCS_TRIM_DCOCLKDIV: 0");
#endif /* BSP430_UCS_TRIM_DCOCLKDIV */
#endif /* UCS */
cputtext("\nBSP430_CLOCK_PUC_MCLK_HZ: ");
cputtext("\nBSP430_CLOCK_NOMINAL_MCLK_HZ: ");
cputtext("\nBSP430_CLOCK_LFXT1_IS_FAULTED_NI(): ");
cputtext("\nBSP430_CLOCK_NOMINAL_VLOCLK_HZ: ");
cputtext("\nBSP430_CLOCK_NOMINAL_XT1CLK_HZ: ");
#if defined(BSP430_CLOCK_NOMINAL_XT2CLK_HZ)
cputtext("\nBSP430_PLATFORM_BOOT_CONFIGURE_XT2: ");
cputtext("\nBSP430_CLOCK_XT2_IS_FAULTED_NI(): ");
cputtext("\nBSP430_CLOCK_NOMINAL_XT2CLK_HZ: ");
#endif /* BSP430_CLOCK_NOMINAL_XT2CLK_HZ */
cputtext("\nulBSP430clockMCLK_Hz_ni(): ");
cputtext("\nBSP430_PLATFORM_BOOT_SMCLK_DIVIDING_SHIFT: ");
cputtext("\nulBSP430clockSMCLK_Hz_ni(): ");
cputul(smclk_Hz, 10);
cputtext("\nBSP430_PLATFORM_BOOT_ACLK_DIVIDING_SHIFT: ");
cputtext("\nulBSP430clockACLK_Hz_ni(): ");
cputul(aclk_Hz, 10);
#if (BSP430_TIMER_CCACLK - 0)
if (1000000UL <= aclk_Hz) {
cputtext("\nUnable to use high-speed ACLK for differential timing of SMCLK");
} else {
do {
const unsigned int SAMPLE_PERIOD_ACLK = 10;
unsigned int cc_delta;
unsigned long aclk_rel_smclk_Hz;
unsigned long smclk_rel_aclk_Hz;
if (! tp) {
cputtext("\nUnable to access configured CCACLK timer");
break;
}
/* Capture the SMCLK ticks between adjacent ACLK ticks */
tp->ctl = TASSEL_2 | MC_2 | TACLR;
SAMPLE_PERIOD_ACLK);
tp->ctl = 0;
if (-1 == cc_delta) {
cputtext("\nCCACLK measurement failed");
break;
}
cputchar('\n');
cputu(SAMPLE_PERIOD_ACLK, 10);
cputtext(" ticks of ACLK produced ");
cputu(cc_delta, 10);
cputtext(" ticks of SMCLK");
cputtext("\nComparison with measured values:");
cputtext("\n SMCLK (Hz) (if measured ACLK correct): ");
smclk_rel_aclk_Hz = (cc_delta * aclk_Hz) / SAMPLE_PERIOD_ACLK;
cputul(smclk_rel_aclk_Hz, 10);
cputtext(" (error ");
cputl(smclk_rel_aclk_Hz - smclk_Hz, 10);
cputtext(" = ");
cputl(1000 * labs(smclk_rel_aclk_Hz - smclk_Hz) / smclk_Hz, 10);
cputtext(" kHz/MHz)");
cputtext("\n ACLK (Hz) (if measured SMCLK correct): ");
aclk_rel_smclk_Hz = SAMPLE_PERIOD_ACLK * smclk_Hz / cc_delta;
cputul(aclk_rel_smclk_Hz, 10);
cputtext(" (error ");
cputl(aclk_rel_smclk_Hz - aclk_Hz, 10);
cputtext(" = ");
cputl(1000 * labs(aclk_rel_smclk_Hz - aclk_Hz) / aclk_Hz, 10);
cputtext(" Hz/kHz)");
} while (0);
}
#else /* BSP430_TIMER_CCACLK */
cputtext("\nNo CCACLK timer available for ACLK/SMCLK comparison");
#endif /* BSP430_TIMER_CCACLK */
cputchar('\n');
#if defined(__MSP430_HAS_BC2__)
cputtext("\nBC2: DCO ");
cputu(DCOCTL, 16);
cputtext(" CTL1 ");
cputu(BCSCTL1, 16);
cputtext(" CTL2 ");
cputu(BCSCTL2, 16);
cputtext(" CTL3 ");
cputu(BCSCTL3, 16);
#endif
#if defined(__MSP430_HAS_FLL__) || defined(__MSP430_HAS_FLLPLUS__)
cprintf("\nFLL: SCF QCTL %02x I0 %02x I1 %02x ; CTL0 %02x CTL1 %02x CTL2 %02x\n",
SCFQCTL, SCFI0, SCFI1, FLL_CTL0, FLL_CTL1,
#if defined(FLL_CTL2_)
FLL_CTL2
#else /* FLL_CTL2 */
~0
#endif /* FLL_CTL2 */
);
#endif /* FLL/PLUS */
#if defined(__MSP430_HAS_UCS__) || defined(__MSP430_HAS_UCS_RF__)
cputtext("\nBSP430_UCS_FLL_SELREF: "
"XT2CLK"
"REFOCLK"
#else /* BSP430_UCS_FLL_SELREF */
"XT1CLK"
#endif /* BSP430_UCS_FLL_SELREF */
);
cprintf("\nUCS RSEL %d DCO %d MOD %d:"
"\n CTL0 %04x CTL1 %04x CTL2 %04x CTL3 %04x"
"\n CTL4 %04x CTL5 %04x CTL6 %04x CTL7 %04x",
0x1F & (UCSCTL1 / DCORSEL0), 0x1F & (UCSCTL0 / DCO0), 0x1F & (UCSCTL0 / MOD0),
UCSCTL0, UCSCTL1, UCSCTL2, UCSCTL3,
UCSCTL4, UCSCTL5, UCSCTL6, UCSCTL7);
#endif /* UCS */
#if defined(__MSP430_HAS_CS__) || defined(__MSP430_HAS_CS_A__)
#if (BSP430_PERIPH_CS_IS_CS4 - 0)
cprintf("\nCS FR4 : FLLD %u FLLN %u"
"\n CTL0 %04x CTL1 %04x CTL2 %04x CTL3 %04x"
"\n CTL4 %04x CTL5 %04x CTL6 %04x CTL7 %04x"
"\n CTL8 %04x",
0x07 & (CSCTL2 / FLLD0), 0x3FF & CSCTL2,
CSCTL0, CSCTL1, CSCTL2, CSCTL3,
CSCTL4, CSCTL5, CSCTL6, CSCTL7,
CSCTL8);
#else /* BSP430_PERIPH_CS_IS_CS4 */
cprintf("\nCS %s : RSEL %d DCOFSEL %d:"
"\n CTL0 %04x CTL1 %04x CTL2 %04x CTL3 %04x"
"\n CTL4 %04x CTL5 %04x CTL6 %04x",
"FR57xx"
"FR58xx"
#else
"????"
#endif
, !!(DCORSEL & CSCTL1), 0x07 & (CSCTL1 / DCOFSEL0),
CSCTL0, CSCTL1, CSCTL2, CSCTL3,
CSCTL4, CSCTL5, CSCTL6);
#endif /* BSP430_PERIPH_CS_IS_CS4 */
cprintf("\n FRCTL0 %04x", FRCTL0);
#endif /* CS */
#endif /* BSP430_CONSOLE */
#if (BSP430_CONSOLE - 0)
cputtext("\n\nClock signals exposed:\n ");
help = NULL;
#ifdef BSP430_PLATFORM_PERIPHERAL_HELP
#endif /* BSP430_PLATFORM_PERIPHERAL_HELP */
if (NULL == help) {
help = "Go look at the data sheet and source, because nobody told me where they are";
}
cputtext(help);
cputtext("\nStatus register LPM bits: ");
cputu(__read_status_register() & BSP430_CORE_LPM_SR_MASK, 16);
cputtext("\nIFG1 bits: ");
#if defined(__MSP430_HAS_MSP430XV2_CPU__)
cputu(SFRIFG1, 16);
#else /* CPUX */
cputu(IFG1, 16);
#endif /* CPUX */
cputtext(" with OFIFG ");
cputu(OFIFG, 16);
cputchar('\n');
#endif /* BSP430_CONSOLE */
/* One of the LEDs is often the signal used for one of the clocks.
* Select a different LED for the idle blinker. */
#ifndef IDLE_LED
#if (BSP430_PLATFORM_EXP430FR4133 - 0)
#define IDLE_LED BSP430_LED_GREEN
#else /* BSP430 PLATFORM */
#define IDLE_LED BSP430_LED_RED
#endif /* BSP430 PLATFORM */
#endif /* IDLE_LED */
/* Spin here with CPU active. In LPM0, MCLK is disabled. Other
* clocks get disabled at deeper sleep modes; if you fall off the
* bottom, you might end up in LPM4 with all clocks disabled. */
while (1) {
vBSP430ledSet(IDLE_LED, -1);
}
} else {
#if (BSP430_CONSOLE - 0)
cputtext("\nFailed to expose clock signals\n");
#endif /* BSP430_CONSOLE */
}
}

bsp430_config.h

/* You can test alternative configurations without modifying this
* file:
make realclean \
EXT_CPPFLAGS='-DBSP430_CLOCK_NOMINAL_MCLK_HZ=20000000' \
install
*/
/* All configuration options in this file may be overridden at compile
* time by providing an alternative definition on the compiler command
* line */
/* Application does output: support spin-for-jumper */
#ifndef configBSP430_PLATFORM_SPIN_FOR_JUMPER
#define configBSP430_PLATFORM_SPIN_FOR_JUMPER 1
#endif /* configBSP430_PLATFORM_SPIN_FOR_JUMPER */
/* Request console resources */
#ifndef configBSP430_CONSOLE
#define configBSP430_CONSOLE 1
#endif /* configBSP430_CONSOLE */
/* Allow application to tell user where things are connected */
#define configBSP430_PLATFORM_PERIPHERAL_HELP 1
/* Expose the clocks */
#ifndef configBSP430_PERIPH_EXPOSED_CLOCKS
#define configBSP430_PERIPH_EXPOSED_CLOCKS 1
#endif /* configBSP430_PERIPH_EXPOSED_CLOCKS */
/* Do not disable the FLL. */
#ifndef configBSP430_CORE_DISABLE_FLL
#define configBSP430_CORE_DISABLE_FLL 0
#endif /* configBSP430_CORE_DISABLE_FLL */
/* By default, ensure MCLK and SMCLK can be distinguished at the test
* points. */
#ifndef BSP430_PLATFORM_BOOT_SMCLK_DIVIDING_SHIFT
#define BSP430_PLATFORM_BOOT_SMCLK_DIVIDING_SHIFT 1
#endif /* BSP430_PLATFORM_BOOT_SMCLK_DIVIDING_SHIFT */
/* Request a differential timer for SMCLK/ACLK if available */
#ifndef configBSP430_TIMER_CCACLK
#define configBSP430_TIMER_CCACLK 1
#endif /* configBSP430_TIMER_CCACLK */
/* We really want the ACLK source to fall back to VLOCLK if XT1CLK is
* not stable. Otherwise those CCACLK timings will hang. */
#ifndef BSP430_PLATFORM_BOOT_ACLK_SOURCE
#if defined(__MSP430_HAS_UCS__) || defined(__MSP430_HAS_UCS_RF__)
#define BSP430_PLATFORM_BOOT_ACLK_SOURCE eBSP430clockSRC_XT1CLK_OR_REFOCLK
#else /* UCS */
#define BSP430_PLATFORM_BOOT_ACLK_SOURCE eBSP430clockSRC_XT1CLK_OR_VLOCLK
#endif /* UCS */
#endif /* BSP430_PLATFORM_BOOT_ACLK_SOURCE */

Makefile

PLATFORM ?= exp430fr5739
CFG_LFXT1=0
AUX_CPPFLAGS=-DBSP430_PLATFORM_BOOT_CONFIGURE_LFXT1=$(CFG_LFXT1)
MODULES=$(MODULES_PLATFORM) $(MODULES_TIMER) $(MODULES_CONSOLE)
SRC=main.c
include $(BSP430_ROOT)/make/Makefile.common