Jump to content
43oh

Use a 12MHZ external square wave as MCLK


Recommended Posts

I've been looking for a way to run the msp430 with accurate MHZ speeds. In talking

with NatureTM on IRC, he mentioned that he had used a crystal oscillator ( ECS-100A-160 ) successfully

with his msp430g2231. He didn't have the exact code he used but he helped me recreate this snippet.

 

I didn't have a crystal oscillator but I did have an ATTiny84 lying around that I put on a breadboard.

I reprogrammed the ATTiny84 fuses so its CLKOUT fuse bit was enabled. The ATTiny is using an external

12MHZ crystal. This is fairly accurate, when you enable the CLKOUT fuse, avr outputs the

CPU clock on that pin as a square wave. I connected that pin to the XIN on my msp430g2231

and left XOUT unconnected.

 

I'm not sure if this is going to damage my g2231 as the specs say you should only feed it low

frequency external square waves from 10k - 50k. So don't expect this to actually work. I'm

just passing along what I've discovered.

 

https://gist.github.com/954778

 

-rick

 

//***********************************************************
// runfast.c - Using 12MHZ external square wave clock as LFXTCLK
//             source MCLK/SMCLK from 12MHZ wave and blink led
//             at 60Hz
//
// Use an external clock ( I'm using an attiny running at 12.00 MHZ
// with the CLKOUT fuse enabled ) as the MCLK/SMCLK for the MSP430.
// I've been told you could also use an external oscillator like an
// ECS-100A-160. I ordered some of these to verify.
//
// LFXT1 oscillator logic level square wave input frequency, LF mode
//
// XIN - external clock in from attiny CLKOUT pin ( set avr fuse to get clock )
// XOUT - NC
// P1.0 - led on until OSCFault cleared
// P1.4 - SMCLK frequency, measuer with multimeter/oscope
// P1.6 - 60Hz led flash, measure with multimeter/oscope
//
//***********************************************************

#include 

void main(void) {
   WDTCTL = WDTPW + WDTHOLD;	// Stop watchdog timer

   P1DIR = BIT0 | BIT6 | BIT4;	// P1.0 and P1.6 output, P1.4 SMCLK frequency
   P1SEL = BIT4;               // P1.4 output SMCLK on P1.4, measure with multi meter
   P1OUT = BIT0;              	// red LED on until OSCFault is cleared

   DCOCTL = 0x00;

   BCSCTL2 = SELM_3 + DIVM_0 + SELS + DIVS_0;	// MCLK Source Select 3: LFXTCLK
   						// MCLK/1 SMCLK/1 SMCLK LFXTCLK
   BCSCTL1 |= XTS;				// XTS
   BCSCTL3 = LFXT1S_3 | XCAP_0;		// LFXT1 = 12MHZ crystal, No Capacitor

   // not sure if this is needed
   while(IFG1 & OFIFG) {
       IFG1 &= ~OFIFG;               // Clear OSCFault flag
       _delay_cycles(10000);  	      // delay for flag and visibility
   }

   P1OUT = 0;			      // red LED off

   __bis_SR_register(SCG0);          // Stop DCO, we just use the LFXT1 which is
   				      // actually running at 12MHZ

   while(1) {
       P1OUT ^= BIT6; 		      	   // green LED on, measure this, it should be 60Hz
       _delay_cycles((12000000/60/2)-35); // 12MHZ, 60/2, 35 overhead clocks
   }
}

Link to post
Share on other sites
  • 11 months later...

I've made also some experimentations about clocking the G2231 with an external clock 16MHz.

 

Before reading your code, I experimented a solution near yours, but with a little change: the ACLK is driven with an external clock and the MCLK is driven with the internal DCO. I will explain it far.

 

First I tried your code. It works. See below my code test:

void main (void)
{
WDTCTL = WDTPW + WDTHOLD;	// Stop watchdog timer

BCSCTL3 = LFXT1S_3 | XCAP_0;	// Digital external 0.4- to 16-MHz clock source

// Drive ACLK, MCLK & SMCLK with digital external clock source on XIN pin...
// LFXT1CLK = Digital external clock = Quartz Pierce Oscillator = 16MHz
// ACLK = LFXT1CLK/8 = 2MHz
// MCLK = SMCLK = 16MHz
DCOCTL = 0x00;					// Select lowest DCO and RMOD settings
BCSCTL1 |= DIVA_3;				// ACLK/8
BCSCTL2 = SELM_3 | DIVM_0 | SELS*1 | DIVS_0; // LFXT1CLK or VLOCLK
BCSCTL3 = LFXT1S_3 | XCAP_0;	// Digital external 0.4- to 16-MHz clock source
//
// (Not sure if this is needed?) Yes, it's needed!
 while(IFG1 & OFIFG) {
	IFG1 &= ~OFIFG;			// Clear OSCFault flag
//		_delay_cycles(10000);	// Delay for flag and visibility (perhaps it's needed)
}
//
__bis_SR_register(SCG0);	// Stop DCO. We just use LFXT1CLK which is actually 
							// running with digital external clock source

Comments:

1/ The code

while(IFG1 & OFIFG) {...}

before

__bis_SR_register(SCG0)

seams to be necessary else it's like if an internal PLL takes a lot of time to synchronize with the external clock. I've observed that because the 1rst task (not described here) of my

main(){...}

procedure is to send a signature on the TXD pin, and some characters was wrong.

2/ The code

_delay_cycles(10000)

doesn't seam to be necessary running with a 16MHz extrernal clock. Not sure if it's same running at other frequencies.

3/ In my example, ACLK runs at 2MHz (LFXT1CLK/8).

4/ I haven't found a TI documentation about

__bis_SR_register(SCG0)

to stop the internal VLO and take the external clock instead.

5/ It seams that set XTS to "1" in the BCSCTL1 is not necessary. It's "0" in my example.

 

So OK, it works like that.

 

But here is another idea: Is it necessary to run MCLK with a precise frequency ?

I answer NO and I can simplify the code with the 2 ideas:

1/ Drive ACLK with a precise quartz external clock to clock the timer.

2/ Drive MCLK with DCOCLK running at high frequency to clock the processor.

 

My proposed code:

void main (void)
{
WDTCTL = WDTPW + WDTHOLD;	// Stop watchdog timer

// Clock after Reset, SMCLK = MCLK = ACLK = DCOCLK = ~1.1MHz:
// DCOCTL:	0x60 (DCO_3, RMOD_0)
// BCSCTL1:	0x87 (XT2OFF*1, XTS*0, DIVA_0, RSEL_7)
// BCSCTL2:	0x00 (SELM_0, DIVM_0, SELS*0, DIVS_0)
// BCSCTL3:	0x05 (XT2S_0, LFXT1S_0, XT2OF*0, LFXT1OF*1)
// SR:	0x0003 (V*0, SCG1*0, SCG0*0, OSCOFF*0, CPUOFF*0, GIE*0, N*0, Z*1, C*1)
// My MSP430G2331 has calibrated values:
// CALDCO_1MHZ:	0xA8 (DCO_5, RMOD_8)
// CALBC1_1MHZ:	0x86 (XT2OFF*1, XTS*0, DIVA_0, RSEL_6)

// Set DCOCLK to calibrated 1MHz...
//	DCOCTL = 0x00;					// Select lowest DCO and RMOD settings
//	BCSCTL1 = CALBC1_1MHZ;			// Set range
//	DCOCTL = CALDCO_1MHZ;			// Set DCO step + modulation

// Set DCOCLK ~16MHz...
DCOCTL = 0x00;					// Select lowest DCO and RMOD settings
BCSCTL1 = XT2OFF*1 | XTS*0 | DIVA_0 | 14; //RSEL_0;	// Set range
DCOCTL = DCO0*3 | 0; //DCO_3 | RMOD_0;	// Set DCO step + modulation

// Drive ACLK with digital external clock source on XIN pin...
// LFXT1CLK = Digital external clock = Quartz Pierce Oscillator = 16MHz
// ACLK = LFXT1CLK/8 = 2MHz
// MCLK = SMCLK = DCOCLK = ~16MHz
BCSCTL1 |= DIVA_3;				// ACLK/8
BCSCTL2 = SELM_0 | DIVM_0 | SELS*0 | DIVS_0; // DCOCLK 2x
BCSCTL3 = LFXT1S_3 | XCAP_0;	// Digital external 0.4- to 16-MHz clock source

Benefits are:

1/ Smaller code.

2/ Processor clocked immediately at high frequency and ready to use.

 

jmP

Link to post
Share on other sites

But here is another idea: Is it necessary to run MCLK with a precise frequency ?

I answer NO and I can simplify the code with the 2 ideas:

1/ Drive ACLK with a precise quartz external clock to clock the timer.

2/ Drive MCLK with DCOCLK running at high frequency to clock the processor.

jmP

 

Interesting...

 

I guess last year when I posted this I had about 2 weeks playing with the msp430 G series. Since that time

I've learned a lot about the right way to do this. I agree that it is probably better to use the DCO clock for

the SMCLK. However, I'd suggest for getting a more accurate Timer clock it makes sense to drive the Timer

with an external clock instead of the driving the LFXT1 oscillator logic level.

 

The data sheet say the external clock for the LFXT should be 10-50kHz. It also says that it is perfectly

within spec to run the TimerA using an external clock up to 16MHz. It might be better to source the TimerA

clock with an external signal and then retain the ACLK for use with the VLO for power savings.

Driving the ACLK at 16MHz isn't really legal. Driving the TimerA clock is.

 

Check out this page http://www.ti.com/lit/ds/symlink/msp430 ... df#page=25 and look at TimerA and TACLK.

 

-rick

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...