I am interested in using the DCO for MCLK and SMCLK with a 32 KHz crystal generating an interrupt on TIMERB . How much software overhead is needed to maintain lock for the DCO with the 32 KHz interrupt? Ideally, the DCO will be off most of the time so how time consuming is the re-synchronization effort? We are planning on using the DCO clock to do precise timing measurements using TIMERA so effective DCO operation is important. I'd like to hear of your experiences in this area.
MSP430 DCO operation
Started by ●August 28, 2002
Reply by ●August 28, 20022002-08-28
Here's my experience with the DCO.
It's not wuite the same as what you're doing, but it may
help.
I began by reading TI's app note SLAA116,
which is available on their web site. It is an app note on building a PWM, but
it contains a cal routine for the DCO. I then adapted this for my
use.
I am busy in the development stage with this,
so I can't answer a lot of questions, at least right now. However, I have
had *good* results (apparently, so far) with my app using the DCO; I need
relatively little accuracy, I am maintaining a second counter for the
user's display, and 1/8 and 1/512 second interrupts within. I am
timing the duration of a charge or discharge cycle of a pack of NimH cells.
I calibrate the DCO every 1/8
second.
****Here is where I initialize TIMER_B
(partial):
// TB6 capture mode
selected,
// connect TB6 capture module to ACLK,
// capture on rising edge.
// Object is to capture # of timer B counts in 1/8 second.
// Then, DCO can be calibrated
TBCCTL6 |= CAP | CCIS_1 | CM_1;
// connect TB6 capture module to ACLK,
// capture on rising edge.
// Object is to capture # of timer B counts in 1/8 second.
// Then, DCO can be calibrated
TBCCTL6 |= CAP | CCIS_1 | CM_1;
****Here is my TIMER_B interrupt service
function:
You can see I'm using the timer for
multiple stuff, but the applicable code
is in case 0x0a: No attempt has been made
to optimize this, because my
application works fine with what you see
here.
/****************************************************
* Handles TIMER_B interrupts for module 1 through 6 *
****************************************************/
interrupt[TIMERB1_VECTOR] void IntTimerB(void)
{
switch (TBIV) {
case 0x02:
break;
case 0x04:
// load next compare value.
// Handles 10KHz squarewave output
TBCCR2 += RLD_TMRB_2;
TBCCR2 &= 0xfff;
break;
case 0x06:
break;
case 0x08:
break;
case 0x0a:
break;
// here for DCO cal interrupt
case 0x0c:
CalDco();
break;
case 0x0e:
break;
default:
break;
}
}
* Handles TIMER_B interrupts for module 1 through 6 *
****************************************************/
interrupt[TIMERB1_VECTOR] void IntTimerB(void)
{
switch (TBIV) {
case 0x02:
break;
case 0x04:
// load next compare value.
// Handles 10KHz squarewave output
TBCCR2 += RLD_TMRB_2;
TBCCR2 &= 0xfff;
break;
case 0x06:
break;
case 0x08:
break;
case 0x0a:
break;
// here for DCO cal interrupt
case 0x0c:
CalDco();
break;
case 0x0e:
break;
default:
break;
}
}
****Here is my CalDco function, which is
called periodically fromthe TIMER_B interrupt:
This is called 8 times/second. Again, no
attempt to optimize.
/***************************************************************
* Periodically recalibrates DCO for maximum accuracy over time *
* Uses TB6 module capture register *
* TB6 capture triggered by ACLK rising edge, so TB6 captures *
* the number of SMCLK's in a ACLK *
***************************************************************/
void CalDco(void)
{
static unsigned int LastCap; // holds last capture value
// guaranteed initialization = 0 K&R p. 85
unsigned int delta; // holds calc'ed dif between last cap and current cap values
// get TBCCR6 value immediately before it changes.
delta = TBCCR6;
// first time, so just save capture value for next time
if (LastCap == 0)
LastCap = delta;
// not first time, so we have something to compare.
else {
TBCCTL6 &= ~CCIE; // disable capture interrupt
// at each interrupt, DCOCTL will be adjusted 1 count.
delta -= LastCap;
delta &= 0xfff;
if ((delta < TARGET_DCO_COUNT) && (DCOCTL < DCOCTL_MAX))
DCOCTL++;
else if ((delta > TARGET_DCO_COUNT) && (DCOCTL > DCOCTL_MIN))
DCOCTL--;
LastCap = 0; // set up for next correction
}
}
* Periodically recalibrates DCO for maximum accuracy over time *
* Uses TB6 module capture register *
* TB6 capture triggered by ACLK rising edge, so TB6 captures *
* the number of SMCLK's in a ACLK *
***************************************************************/
void CalDco(void)
{
static unsigned int LastCap; // holds last capture value
// guaranteed initialization = 0 K&R p. 85
unsigned int delta; // holds calc'ed dif between last cap and current cap values
// get TBCCR6 value immediately before it changes.
delta = TBCCR6;
// first time, so just save capture value for next time
if (LastCap == 0)
LastCap = delta;
// not first time, so we have something to compare.
else {
TBCCTL6 &= ~CCIE; // disable capture interrupt
// at each interrupt, DCOCTL will be adjusted 1 count.
delta -= LastCap;
delta &= 0xfff;
if ((delta < TARGET_DCO_COUNT) && (DCOCTL < DCOCTL_MAX))
DCOCTL++;
else if ((delta > TARGET_DCO_COUNT) && (DCOCTL > DCOCTL_MIN))
DCOCTL--;
LastCap = 0; // set up for next correction
}
}
----- Original Message -----
From: "mjruley" <mjruley@yahoo.com>
To: <msp430@yahoogroups.com>
Sent: Wednesday, August 28, 2002 8:01
AM
Subject: [msp430] MSP430 DCO
operation
> crystal generating an interrupt on TIMERB . How much software
> overhead is needed to maintain lock for the DCO with the 32 KHz
> interrupt? Ideally, the DCO will be off most of the time so how time
> consuming is the re-synchronization effort? We are planning on using
> the DCO clock to do precise timing measurements using TIMERA so
> effective DCO operation is important.
>
> I'd like to hear of your experiences in this area.
>
>
> ------------------------ Yahoo! Groups Sponsor ---------------------~-->
> 4 DVDs Free +s&p Join Now
> http://us.click.yahoo.com/pt6YBB/NXiEAA/MVfIAA/CFFolB/TM
> ---------------------------------~->
>
> ">msp430-unsubscribe@egroups.com
>
>
>
> ">http://docs.yahoo.com/info/terms/
>
>
Reply by ●August 29, 20022002-08-29
I really don't think you need to calibrate the DCO every 1/8th
second! It will drift due to ambient temp changes but unless your
environment's going all over the place, it should be pretty stable once you
calibrate. Every minute or so even seems conservative.
Bruce
-----Original Message-----
From: Mark Skeels [mailto:meskeels@earthlink.net]
Sent: Wednesday, August 28, 2002 7:37 AM
To: msp430@yahoogroups.com
Subject: Re: [msp430] MSP430 DCO operationHere's my experience with the DCO. It's not wuite the same as what you're doing, but it may help.I began by reading TI's app note SLAA116, which is available on their web site. It is an app note on building a PWM, but it contains a cal routine for the DCO. I then adapted this for my use.I am busy in the development stage with this, so I can't answer a lot of questions, at least right now. However, I have had *good* results (apparently, so far) with my app using the DCO; I need relatively little accuracy, I am maintaining a second counter for the user's display, and 1/8 and 1/512 second interrupts within. I am timing the duration of a charge or discharge cycle of a pack of NimH cells.I calibrate the DCO every 1/8 second.****Here is where I initialize TIMER_B (partial):// TB6 capture mode selected,
// connect TB6 capture module to ACLK,
// capture on rising edge.
// Object is to capture # of timer B counts in 1/8 second.
// Then, DCO can be calibrated
TBCCTL6 |= CAP | CCIS_1 | CM_1;****Here is my TIMER_B interrupt service function:You can see I'm using the timer for multiple stuff, but the applicable codeis in case 0x0a: No attempt has been made to optimize this, because myapplication works fine with what you see here./****************************************************
* Handles TIMER_B interrupts for module 1 through 6 *
****************************************************/
interrupt[TIMERB1_VECTOR] void IntTimerB(void)
{
switch (TBIV) {
case 0x02:
break;
case 0x04:
// load next compare value.
// Handles 10KHz squarewave output
TBCCR2 += RLD_TMRB_2;
TBCCR2 &= 0xfff;
break;
case 0x06:
break;
case 0x08:
break;
case 0x0a:
break;
// here for DCO cal interrupt
case 0x0c:
CalDco();
break;
case 0x0e:
break;
default:
break;
}
}****Here is my CalDco function, which is called periodically fromthe TIMER_B interrupt:This is called 8 times/second. Again, no attempt to optimize./***************************************************************
* Periodically recalibrates DCO for maximum accuracy over time *
* Uses TB6 module capture register *
* TB6 capture triggered by ACLK rising edge, so TB6 captures *
* the number of SMCLK's in a ACLK *
***************************************************************/
void CalDco(void)
{
static unsigned int LastCap; // holds last capture value
// guaranteed initialization = 0 K&R p. 85
unsigned int delta; // holds calc'ed dif between last cap and current cap values
// get TBCCR6 value immediately before it changes.
delta = TBCCR6;
// first time, so just save capture value for next time
if (LastCap == 0)
LastCap = delta;
// not first time, so we have something to compare.
else {
TBCCTL6 &= ~CCIE; // disable capture interrupt
// at each interrupt, DCOCTL will be adjusted 1 count.
delta -= LastCap;
delta &= 0xfff;
if ((delta < TARGET_DCO_COUNT) && (DCOCTL < DCOCTL_MAX))
DCOCTL++;
else if ((delta > TARGET_DCO_COUNT) && (DCOCTL > DCOCTL_MIN))
DCOCTL--;
LastCap = 0; // set up for next correction
}
}----- Original Message -----From: "mjruley" <mjruley@yahoo.com>To: <msp430@yahoogroups.com>Sent: Wednesday, August 28, 2002 8:01 AMSubject: [msp430] MSP430 DCO operation> I am interested in using the DCO for MCLK and SMCLK with a 32 KHz
> crystal generating an interrupt on TIMERB . How much software
> overhead is needed to maintain lock for the DCO with the 32 KHz
> interrupt? Ideally, the DCO will be off most of the time so how time
> consuming is the re-synchronization effort? We are planning on using
> the DCO clock to do precise timing measurements using TIMERA so
> effective DCO operation is important.
>
> I'd like to hear of your experiences in this area.
>
>
> ------------------------ Yahoo! Groups Sponsor ---------------------~-->
> 4 DVDs Free +s&p Join Now
> http://us.click.yahoo.com/pt6YBB/NXiEAA/MVfIAA/CFFolB/TM
> ---------------------------------~->
>
> ">msp430-unsubscribe@egroups.com
>
>
>
> ">http://docs.yahoo.com/info/terms/
>
>
">Yahoo! Terms of Service.
Reply by ●August 29, 20022002-08-29
Thanks, Bruce.
I actually have no idea how often the DCO needs calibration;
I had the convenience of 1/8 second interrupt, so put it in there.
Is there any downside to calibration this
often?
Mark
----- Original Message -----From: Bruce CannonTo: msp430@yahoogroups.comSent: Thursday, August 29, 2002 12:45 PMSubject: RE: [msp430] MSP430 DCO operationI really don't think you need to calibrate the DCO every 1/8th second! It will drift due to ambient temp changes but unless your environment's going all over the place, it should be pretty stable once you calibrate. Every minute or so even seems conservative.Bruce-----Original Message-----
From: Mark Skeels [mailto:meskeels@earthlink.net]
Sent: Wednesday, August 28, 2002 7:37 AM
To: msp430@yahoogroups.com
Subject: Re: [msp430] MSP430 DCO operationHere's my experience with the DCO. It's not wuite the same as what you're doing, but it may help.I began by reading TI's app note SLAA116, which is available on their web site. It is an app note on building a PWM, but it contains a cal routine for the DCO. I then adapted this for my use.I am busy in the development stage with this, so I can't answer a lot of questions, at least right now. However, I have had *good* results (apparently, so far) with my app using the DCO; I need relatively little accuracy, I am maintaining a second counter for the user's display, and 1/8 and 1/512 second interrupts within. I am timing the duration of a charge or discharge cycle of a pack of NimH cells.I calibrate the DCO every 1/8 second.****Here is where I initialize TIMER_B (partial):// TB6 capture mode selected,
// connect TB6 capture module to ACLK,
// capture on rising edge.
// Object is to capture # of timer B counts in 1/8 second.
// Then, DCO can be calibrated
TBCCTL6 |= CAP | CCIS_1 | CM_1;****Here is my TIMER_B interrupt service function:You can see I'm using the timer for multiple stuff, but the applicable codeis in case 0x0a: No attempt has been made to optimize this, because myapplication works fine with what you see here./****************************************************
* Handles TIMER_B interrupts for module 1 through 6 *
****************************************************/
interrupt[TIMERB1_VECTOR] void IntTimerB(void)
{
switch (TBIV) {
case 0x02:
break;
case 0x04:
// load next compare value.
// Handles 10KHz squarewave output
TBCCR2 += RLD_TMRB_2;
TBCCR2 &= 0xfff;
break;
case 0x06:
break;
case 0x08:
break;
case 0x0a:
break;
// here for DCO cal interrupt
case 0x0c:
CalDco();
break;
case 0x0e:
break;
default:
break;
}
}****Here is my CalDco function, which is called periodically fromthe TIMER_B interrupt:This is called 8 times/second. Again, no attempt to optimize./***************************************************************
* Periodically recalibrates DCO for maximum accuracy over time *
* Uses TB6 module capture register *
* TB6 capture triggered by ACLK rising edge, so TB6 captures *
* the number of SMCLK's in a ACLK *
***************************************************************/
void CalDco(void)
{
static unsigned int LastCap; // holds last capture value
// guaranteed initialization = 0 K&R p. 85
unsigned int delta; // holds calc'ed dif between last cap and current cap values
// get TBCCR6 value immediately before it changes.
delta = TBCCR6;
// first time, so just save capture value for next time
if (LastCap == 0)
LastCap = delta;
// not first time, so we have something to compare.
else {
TBCCTL6 &= ~CCIE; // disable capture interrupt
// at each interrupt, DCOCTL will be adjusted 1 count.
delta -= LastCap;
delta &= 0xfff;
if ((delta < TARGET_DCO_COUNT) && (DCOCTL < DCOCTL_MAX))
DCOCTL++;
else if ((delta > TARGET_DCO_COUNT) && (DCOCTL > DCOCTL_MIN))
DCOCTL--;
LastCap = 0; // set up for next correction
}
}----- Original Message -----From: "mjruley" <mjruley@yahoo.com>To: <msp430@yahoogroups.com>Sent: Wednesday, August 28, 2002 8:01 AMSubject: [msp430] MSP430 DCO operation> I am interested in using the DCO for MCLK and SMCLK with a 32 KHz
> crystal generating an interrupt on TIMERB . How much software
> overhead is needed to maintain lock for the DCO with the 32 KHz
> interrupt? Ideally, the DCO will be off most of the time so how time
> consuming is the re-synchronization effort? We are planning on using
> the DCO clock to do precise timing measurements using TIMERA so
> effective DCO operation is important.
>
> I'd like to hear of your experiences in this area.
>
>
> ------------------------ Yahoo! Groups Sponsor ---------------------~-->
> 4 DVDs Free +s&p Join Now
> http://us.click.yahoo.com/pt6YBB/NXiEAA/MVfIAA/CFFolB/TM
> ---------------------------------~->
>
> ">msp430-unsubscribe@egroups.com
>
>
>
> ">http://docs.yahoo.com/info/terms/
>
>
">Yahoo! Terms of Service.
">Yahoo! Terms of Service.
Reply by ●August 29, 20022002-08-29