This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Determining the MCLK clock in an MSP430F5342

Other Parts Discussed in Thread: MSP430F5342

Greetings I've been trying to find a nice way to determine what CPU clock is set too in a MSP430F5342 system.

I have a 32768hz crystal (20ppm)  for the RTC and I have it set up to use either the DCO (if XT2 doesn't exist) and set it too 7372800hz using the 32768 XT1 clock source.

However "in case of crystal installed" as XT2, I would like too know what to set the baud rate registers too.

I came up with "this" code however it doesn't seem to exactly come out with close to consistent (or correct) results.

uint32_t	get_base_clock(void)
{
	uint16_t 	temp;
	uint16_t	old_UCSCTL4;
	uint32_t	value;
#define	CYCLE_DELAY	64
#define	CYCLE_LOAD	4

	// get old 4 thing
	old_UCSCTL4 = UCSCTL4;
	// get the ACLK setting here
	temp = old_UCSCTL4 & SELA_7;
	// shift temp to the correct location
	temp >>= 8;
	// set CPU clock to be ACLK value
	UCSCTL4 = temp | (old_UCSCTL4 & ~SELM_7);
	// 16 bit SMCLK CONTINUOUS CLEAR /1
	TB0CTL = CNTL__16|TBCLGRP_0|TASSEL__SMCLK|TBCLR | MC__CONTINUOUS|ID__1;
	// set input clock to SMCLK
	//TB0CTL = MC__UP | TASSEL__SMCLK | ID__1;
	__delay_cycles(CYCLE_DELAY - CYCLE_LOAD);
	TB0CTL = MC__STOP;	// 2
	// CYCLE_DELAY - CYCLE_LOAD  CPU clocks have passed 
	// get tb0r value
	value = TB0R;
	// restore the clocks to old settings
	UCSCTL4 = old_UCSCTL4;
	//value = temp;
	// multiply it by the REF0 clock rate /CYCLE_DELAY
	value *= (REFO_CLK/CYCLE_DELAY);
	return	value;
}
//----------------------------------------------------------------------

Suggestions, thoughts, diatribes on bad coding practice (humor)?

SMCLK is the same as MCLK by the way in the UCS configuration thus this should work. It at least doesn't give me 0hz.

Stephen

  • Stephen,

    I think the basic idea for this is to use the timer module in capture module with the "unknown clock" as the source of counting the TACNT/TBCNT and the "known clock" as the capture signal for the timer module. 

    Looking into the MSP430F534x datasheet, you can for example source the 32 kHz ACLK signal as CCI6B input. 

    I implemented something similar like this before, please refer to the SLAA535 source: http://www.ti.com/lit/zip/slaa535, and you can find the code in LPAD_BSL_INTERFACE\Firmware\Source\lpad_bsl_int.c - function name: calibrate_vlo().

    Hope this helps.

  • Time is relative. And so is frequency, as it Is a function of time.
    To determine an absolute value, you need to compare it to a reference. To get a frequency value, you need to compare your signal to a 1Hz reference (or a known multiple or fraction of it).
    As long as you do not exceed the maximum speed for its current supply voltage, the CPU doesn’t care nor know of ‘frequency’.
    To know what frequency MCLK has, you need to compare it to a known frequency. On some MSPs, you can output MCLK to a port pin. On others, you need to configure SMCLK to have the same frequency and output SMCLK (IIRC, all MSPs have SMCLK output). And compare it to the (hopefully precise) reference of a scope, or an external timer/counter device.
    Alternatively, you can give the MSP a known frequency (e.g. a watch crystal, or a precise 1s tick or such) And let it count the number of MCLK cycles (with a timer) between two reference ticks.

    If you use DCO as clock source for MCLK/SMCLK, then you can use the FLL to adjust the DCO frequency to a value of your choice. However, it will be only an average frequency (with quite some jitter) and depending on the FLL reference, precision, it will have some error too. In case of a crystal, well you may determine the crystal frequency be one of the above mentioned methods. Taking the base error of REFO into account, if using it as reference for comparison.

    Normally, you should know what crystal you have attached, and hardcode this into the code, so the remaining question is: does the crystal run or not?

    Your code may or may not work, depending on what SMCLK is.
    The way you did it, you’ll require an SMCLK that is 1) known and 2) much higher than MCLK. If SMCLK and MCLK are form the same source, then all you can determine is the ratio between SMLCK and MCLK. And if SMCLK is slower than MCLK, you will get a very rough resolution or no result at all. (e.g. MCLK is ~1MHz and SMCLK is 32768Hz, then for 64 MCLK cycles, you’ll get a timer count value of 1 or 2 which won’t be useful).
    If SMCLK were known 10.00MHz, you’d get a value of 640 for a 1MHz MCLK, which gives you about 0.2% precision.

  • I probably needed to give  a bit more background (I think) the processor is running from the XT1 LFO (32768 20ppm in our tests it was 1ppm but that's a different matter).

    So MCLK is 32768hz (~+-1hz)

    XT2 is configured and tested if it fails (IE no crystal) the DCO is configured and the FLL is setup for 7.3728mhz  (well as close as it can come to it anyhow).

    This is not done in the 'same' section of code. Essentially it starts up and configures XT2 or the FLL to operate at some necessary clock rate.

    Anyhow determining MCLK, the idea was to use the "precise" 32768hz clock for the cpu and to run a specific number of cycles (64 or 1/512 of a second) and then use the resultant value from smclk to guesstimate what the clock is and hope the baud rate is close enough.


    I will have to see if I can rectify this "issue" someday. Not high priority but would be nice if I could get a chance at being somewhat close to the clock frequency. My suspicion lies in interrupts as I did not purposefully disable them. All I can say is thanks for the feedback. It confirms my suspicion this is a precarious means to an end at best.

    Thanks I appreciate the time you folks spent pondering my strange bit of code.


    Stephen

  • The MCLK method you described is of course a way to do it, but it is difficult to time (to get the exact number of cycles between readings etc.). Especially if you don’t know what the compiler does (and what the next compiler revision will do).

    But on almost all MSPs, you can trigger a capture interrupt by ACLK (see datasheet timer description – usually TAxCCR1 has ACLK as alternative trigger source).
    So you can run the timer with SMCLK from XT2/DCO, do a capture at one 32768Hz edge, write down the value, do a second capture (for better resolution, the 10th or even 100th capture after the first should be used, not just the next), then calculate the ratio between ALCK and SMCLK.

    Actually, a similar approach is used to restore the DCO calibration settings in 2x family if they have been erased accidentally.

**Attention** This is a public forum