NatureTM 100 Posted December 2, 2010 Share Posted December 2, 2010 EDIT: Here's another really nice DCO calibration program. It's part of TinyOS-msp430. http://code.google.com/p/tinyos-msp430/ It's the file called calibrate-dco. As gordon, who discovered it said, "[it] appears to be a quite beefed-up DCO calibration app, with goodies on the side (taking silicon errata into account for various devices when calibrating)." It looks like it's built to be solid and reliable. I skimmed over the code and didn't see anything for calculating SegA checksum, but that usually isn't an issue for most non-critical applications. EDIT: maxpenna shared another version of the DCO calibration program. This is the one to use if you need a correct SegmentA checksum. It uses the C calibration function. You can get it here http://www.43oh.com/forum/download/file.php?id=292 WARNING: Some of the programs in this thread will erase Segment A and only put back the DCO calibrations. They should not be used with chips that have an ADC12, as this process will destroy the ADC12 calibrations. Some of the programs do not calculate the Segment A checksum, so the integrity of Segment A cannot be verified during runtime after calibration. Still, I've been using it without any problems. There's been a bit of a discussion in another thread about an idea simpleavr had for adding the dco calibration constants to flash for the Value Line series. I've cobbled together some pieces of TI code and have it working. It seems to work great. Here's how I did it with CCS. I think the people on linux should be able to reproduce the result with a little adaptation. This requires the TI DCO library I modified in another thread and an external LF crystal like the one with Launchpad. http://naturetm.com/files/Launchpad%20setDCO%20lib.rar First, run this to calibrate the constants and write them to flash: EDIT: 43oh member zeke has made some changes to the code for finer tuning. Check page 2 for his code. //****************************************************************************** // MSP430F20xx Demo - DCO Calibration Constants Programmer // // NOTE: THIS CODE REPLACES THE TI FACTORY-PROGRAMMED DCO CALIBRATION // CONSTANTS LOCATED IN INFOA WITH NEW VALUES. USE ONLY IF THE ORIGINAL // CONSTANTS ACCIDENTALLY GOT CORRUPTED OR ERASED. // // Description: This code re-programs the F2xx DCO calibration constants. // A software FLL mechanism is used to set the DCO based on an external // 32kHz reference clock. After each calibration, the values from the // clock system are read out and stored in a temporary variable. The final // frequency the DCO is set to is 1MHz, and this frequency is also used // during Flash programming of the constants. The program end is indicated // by the blinking LED. // ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO // //* External watch crystal installed on XIN XOUT is required for ACLK *// // // MSP430F20xx // --------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | P1.0|--> LED // | P1.4|--> SMLCK = target DCO // // A. Dannenberg // Texas Instruments Inc. // May 2007 // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.42A //****************************************************************************** #include "msp430x20x1.h" #include "DCO_Library.h" unsigned char CAL_DATA[8]; // Temp. storage for constants volatile unsigned int i; int j; char *Flash_ptrA; // Segment A pointer void Set_DCO(unsigned int setting); void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT for (i = 0; i < 0xfffe; i++); // Delay for XTAL stabilization P1OUT = 0x01; // Red LED on P1SEL = 0x10; // P1.4 SMCLK output P1DIR = 0x51; // P1.0,4,6 output j = 0; // Reset pointer Set_DCO(TI_DCO_16MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(TI_DCO_12MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(TI_DCO_8MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(TI_DCO_1MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Flash_ptrA = (char *)0x10C0; // Point to beginning of seg A FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits *Flash_ptrA = 0x00; // Dummy write to erase Flash seg A FCTL1 = FWKEY + WRT; // Set WRT bit for write operation Flash_ptrA = (char *)0x10F8; // Point to beginning of cal consts for (j = 0; j < 8; j++) *Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration data FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit P1OUT = 0; while (1) { P1OUT ^= BIT6; // Toggle green LED for (i = 0; i < 0x4000; i++); // SW Delay } } void Set_DCO(unsigned int setting){ volatile unsigned int I; // P1DIR |= BIT0; // P1.0 output BCSCTL1 &= ~XTS; // external source is LF; BCSCTL3 &= ~(LFXT1S0 + LFXT1S1); // watch crystal mode BCSCTL3 |= XCAP0 + XCAP1; // ~12.5 pf cap on the watch crystal as recommended for( I = 0; I < 0xFFFF; I++){} // delay for ACLK startup if(TI_SetDCO(setting) == TI_DCO_NO_ERROR) // if setting the clock was successful, P1OUT |= BIT0; // bring P1.0 high (Launchpad red LED) else while(1); // trap if setting the clock isn't successful } The green light should start blinking in a few seconds, indicating success. Now we need to modify some linker and header files so CCS knows about the new calibrations. I'm using the MSP430G2231, so I duplicated the file C:\Program Files (x86)\Texas Instruments\ccsv4\msp430\include\msp430g2231.cmd in that directory, and renamed the duplicate as msp430g2231_mod.cmd. Now I can edit it without affecting the original. Edit msp430g2231_mod.cmd and change the calibration section at the bottom to this: /************************************************************ * Calibration Data in Info Mem ************************************************************/ CALDCO_16MHZ = 0x10F8; CALBC1_16MHZ = 0x10F9; CALDCO_12MHZ = 0x10FA; CALBC1_12MHZ = 0x10FB; CALDCO_8MHZ = 0x10FC; CALBC1_8MHZ = 0x10FD; CALDCO_1MHZ = 0x10FE; CALBC1_1MHZ = 0x10FF; Now the linker knows we have calibration data in that section when we use the modified file. When we create a new project in CCS or modify an existing one, CCS will want to use the default linking file, and the default header. Here's an example about how to configure a project to use the new constants. First create a new project. Within the project, there should be a file called something like lnk_msp430g2231.cmd. The last line of that file should be something like -l msp430g2231.cmd. Open it, and change the last line to reflect the new linker file so it reads -l msp430g2231_mod.cmd. Next, add the appropriate header file to the project. Right-click the project folder in the left pane of CCS and click "Add files to project..." In this example, I'm using C:\Program Files (x86)\Texas Instruments\ccsv4\msp430\include\msp430g2231.h. Now we have a copy of the file in the project we can safely edit. Edit the file so the calibration section looks like this: /************************************************************ * Calibration Data in Info Mem ************************************************************/ #ifndef __DisableCalData SFR_8BIT(CALDCO_16MHZ); /* DCOCTL Calibration Data for 16MHz */ SFR_8BIT(CALBC1_16MHZ); /* BCSCTL1 Calibration Data for 16MHz */ SFR_8BIT(CALDCO_12MHZ); /* DCOCTL Calibration Data for 12MHz */ SFR_8BIT(CALBC1_12MHZ); /* BCSCTL1 Calibration Data for 12MHz */ SFR_8BIT(CALDCO_8MHZ); /* DCOCTL Calibration Data for 8MHz */ SFR_8BIT(CALBC1_8MHZ); /* BCSCTL1 Calibration Data for 8MHz */ SFR_8BIT(CALDCO_1MHZ); /* DCOCTL Calibration Data for 1MHz */ SFR_8BIT(CALBC1_1MHZ); /* BCSCTL1 Calibration Data for 1MHz */ #endif /* #ifndef __DisableCalData */ Now you can begin using the new calibration data in your program. When you #include the msp430g2231.h file, put it in quotes instead of <> to ensure it's loading the modified header local to the project directory. I tested the constants with a cheap oscilloscope and they seemed correct. My scope doesn't have great accuracy at high frequencies so they might be a little off, but nothing I can detect. It works with my composite video prog, so that's a pretty good sign. EDIT: Oops! I had an incorrectly named file in these instructions. Corrected. artifus, ROFLhoff, P!-Ro and 6 others 9 Quote Link to post Share on other sites
bluehash 1,581 Posted December 3, 2010 Share Posted December 3, 2010 Thanks for testing and sharing this. Now I can finally get a 1us timer on the 2231. ( simpleAVR, thanks to you too) Quote Link to post Share on other sites
NatureTM 100 Posted December 3, 2010 Author Share Posted December 3, 2010 I submitted this to HaD too. It's not as flashy as the TV out I just submitted, but I know HaD readers who use Launchpad would find it useful. It will also be good press for 43oh, right? bluehash 1 Quote Link to post Share on other sites
bluehash 1,581 Posted December 3, 2010 Share Posted December 3, 2010 It will also be good press for 43oh, right? No doubt about that. Quote Link to post Share on other sites
jbremnant 17 Posted December 3, 2010 Share Posted December 3, 2010 One HaD post that really got me interested in msp430 was this one: http://hackaday.com/2010/08/11/how-to-launchpad-programming-with-linux/ @NatureTM You are right, we need more press on msp430. I hope your stuff gets published. Quote Link to post Share on other sites
simpleavr 399 Posted December 4, 2010 Share Posted December 4, 2010 There's been a bit of a discussion in another thread about an idea simpleavr had for adding the dco calibration constants to flash for the Value Line series. I've cobbled together some pieces of TI code and have it working. It seems to work great. Here's how I did it with CCS. I think the people on linux should be able to reproduce the result with a little adaptation. it's not really my idea though, i was trying to run all the ti examples in slau80 which was intent for F2xxx series and the fact that since the G series is new, we have to "pretend" they are F series devices for development under linux. the G2231 is close to the F2012 in my view but there are also some minor differences, the pre-calibrated values is one of them. i was like jbremnant trying to use a 8Mhz pre-calibrated clock setting and found that it was not set. so i spent some time reading the header files and understand the why and how. i played w/ the 'c' calibration example and it was not working, so i hand calibrated my project and had forgot about it when NatureTM's thread had success w/ the assembly calibration code. so i make some effort and get it work as is at this stage. i guess it would be a handy thing (calibration) for a lot of people using the launchpad and NatureTM is nice enough to organize it into an user friend thread. i would doubt HaD would use it though, it's really something tiny and specific to a smaller crowd. NatureTM's TVOut will have a lot better chance. People will "wow" on a 14pin mcu driving a 50inch TV (i did, ), but it's hard to explain the benefit a pre-calibrated clock setting to the general audience. Quote Link to post Share on other sites
bluehash 1,581 Posted December 4, 2010 Share Posted December 4, 2010 i would doubt HaD would use it though, it's really something tiny and specific to a smaller crowd. NatureTM's TVOut will have a lot better chance. People will "wow" on a 14pin mcu driving a 50inch TV (i did, ), but it's hard to explain the benefit a pre-calibrated clock setting to the general audience. Never hurts to submit. In any case, it will be featured here at the Blog. Quote Link to post Share on other sites
GeekDoc 226 Posted December 4, 2010 Share Posted December 4, 2010 Yeah, it's big news to us, but not so much to the HaD crowd. Quote Link to post Share on other sites
nobody 47 Posted January 2, 2011 Share Posted January 2, 2011 IMHO it's not good idea, erase full segment A. There is probably stored more device-depended constants, not only DCO calibration. (Look at page 644 in slau144.pdf - "SegmentA structure"). Better idea is simply write those 3 missing constants (for 8, 12 and 16MHz) into the empty space (empty space contains 0xFFFF, is writable...). And more important info: You thinking about data integrity in segment A? Write the correct info into 0x10F6 (TAG_DCO_30 and length of DCO table)? Recalculate (and write) new checksum for segment A? For those, who want correctly change DCO constants: - Save full contents from segment A into RAM. - Change (in RAM) what You want, compute new checksum, etc... - And then write full block into erased segment A. I suggest You: look at page 649 and 650 in slau144.pdf. btw: the last version is slau144f.pdf NatureTM, DrMag and bluehash 3 Quote Link to post Share on other sites
simpleavr 399 Posted January 2, 2011 Share Posted January 2, 2011 IMHO it's not good idea, erase full segment A. There is probably stored more device-depended constants, not only DCO calibration. (Look at page 644 in slau144.pdf - "SegmentA structure"). Better idea is simply write those 3 missing constants (for 8, 12 and 16MHz) into the empty space (empty space contains 0xFFFF, is writable...). And more important info: You thinking about data integrity in segment A? Write the correct info into 0x10F6 (TAG_DCO_30 and length of DCO table)? Recalculate (and write) new checksum for segment A? For those, who want correctly change DCO constants: - Save full contents from segment A into RAM. - Change (in RAM) what You want, compute new checksum, etc... - And then write full block into erased segment A. thanks nobody, i agree it is safer to transfer seg A to ram before writing back w/ calibrated values (and re-calc checksum). i did messed up dco values when trying this initially. but i would prefer to write it to seg A instead of other segments just to be in-line w/ the TI conventions (i.e. common header files for msp430f2xxxx). there is probably no need to mess w/ seg A if u got everything calibrated at factory. unfortunately the G series only come up w/ 1Mhz calibrated and it will be convenience to have the other values. in my experience it's safe for the G devices as there's no 12bitADC (or thereof calibrate values of that) and i can't think of other applications that may use the checksum and other device tags (i don't think G series supports BSL). this is good advice to all those want to do calibration and understand the potential risks and decide. it's also probably good to always save the original seg A content in a file. NatureTM 1 Quote Link to post Share on other sites
zeke 693 Posted January 27, 2011 Share Posted January 27, 2011 Hi Guys, I wanted to tack on my calibration code that I successfully used to calibrate my G2231 device. It's almost exactly like naturetm's code. The only difference is the setDCO() function has a little more fine tuning in it. Take a look and notice that the setDCO() function is slightly different. I stole the idea from a post aBUGSworstnightmare made on the ti.com website. Here's the link. //****************************************************************************** // MSP430F20xx Demo - DCO Calibration Constants Programmer // // NOTE: THIS CODE REPLACES THE TI FACTORY-PROGRAMMED DCO CALIBRATION // CONSTANTS LOCATED IN INFOA WITH NEW VALUES. USE ONLY IF THE ORIGINAL // CONSTANTS ACCIDENTALLY GOT CORRUPTED OR ERASED. // // Description: This code re-programs the F2xx DCO calibration constants. // A software FLL mechanism is used to set the DCO based on an external // 32kHz reference clock. After each calibration, the values from the // clock system are read out and stored in a temporary variable. The final // frequency the DCO is set to is 1MHz, and this frequency is also used // during Flash programming of the constants. The program end is indicated // by the blinking LED. // ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO // //* External watch crystal installed on XIN XOUT is required for ACLK *// // // MSP430F20xx // --------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | P1.0|--> LED // | P1.4|--> SMLCK = target DCO // // A. Dannenberg // Texas Instruments Inc. // May 2007 // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.42A //****************************************************************************** //#include "msp430x20x1.h" // do not forget to change this according to the device you're using #include #define DELTA_1MHZ 244 // 244 x 4096Hz = 999.4Hz #define DELTA_8MHZ 1953 // 1953 x 4096Hz = 7.99MHz #define DELTA_12MHZ 2930 // 2930 x 4096Hz = 12.00MHz #define DELTA_16MHZ 3906 // 3906 x 4096Hz = 15.99MHz unsigned char CAL_DATA[8]; // Temp. storage for constants volatile unsigned int i; int j; char *Flash_ptrA; // Segment A pointer void Set_DCO(unsigned int Delta); void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL3 |= XCAP_3; // Launchpad watch crystals need ~12.5 pF for (i = 0; i < 0xfffe; i++); // Delay for XTAL stabilization P1OUT = 0x00; // Clear P1 output latches P1SEL = 0x10; // P1.4 SMCLK output P1DIR = 0x11; // P1.0,4 output j = 0; // Reset pointer Set_DCO(DELTA_16MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_12MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_8MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_1MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Flash_ptrA = (char *)0x10C0; // Point to beginning of seg A FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits *Flash_ptrA = 0x00; // Dummy write to erase Flash seg A FCTL1 = FWKEY + WRT; // Set WRT bit for write operation Flash_ptrA = (char *)0x10F8; // Point to beginning of cal consts for (j = 0; j < 8; j++) *Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration data FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit while (1) { P1OUT ^= 0x01; // Toggle LED for (i = 0; i < 0x4000; i++); // SW Delay } } void Set_DCO(unsigned int Delta) // Set DCO to selected frequency { unsigned int Compare, Oldcapture = 0; BCSCTL1 |= DIVA_3; // ACLK = LFXT1CLK/8 TACCTL0 = CM_1 + CCIS_1 + CAP; // CAP, ACLK TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear while (1) { while (!(CCIFG & TACCTL0)); // Wait until capture occured TACCTL0 &= ~CCIFG; // Capture occured, clear flag Compare = TACCR0; // Get current captured SMCLK Compare = Compare - Oldcapture; // SMCLK difference Oldcapture = TACCR0; // Save current captured SMCLK if (Delta == Compare) break; // If equal, leave "while(1)" else if (Delta < Compare) { DCOCTL--; // DCO is too fast, slow it down if (DCOCTL == 0xFF) // Did DCO roll under? if (BCSCTL1 & 0x0f) BCSCTL1--; // Select lower RSEL } else { DCOCTL++; // DCO is too slow, speed it up if (DCOCTL == 0x00) // Did DCO roll over? if ((BCSCTL1 & 0x0f) != 0x0f) BCSCTL1++; // Sel higher RSEL } } TACCTL0 = 0; // Stop TACCR0 TACTL = 0; // Stop Timer_A BCSCTL1 &= ~DIVA_3; // ACLK = LFXT1CLK } Concerning the mods that were made to the cmd file, I just threw them into the default files because I know that I'm going to forget to made the project edits that are suggested in the first post above. Just calibrate the g2231 first then use the code after. P!-Ro, GeekDoc, touch and 1 other 4 Quote Link to post Share on other sites
GeekDoc 226 Posted January 27, 2011 Share Posted January 27, 2011 Concerning the mods that were made to the cmd file, I just threw them into the default files because I know that I'm going to forget to made the project edits that are suggested in the first post above. Just calibrate the g2231 first then use the code after. I agree. I think calibration should be the first thing I do with new chips. That way, I always have the same platform. NatureTM and zeke, your contributions have expanded possibilities for all of us. Thank you. IgnorsHor 1 Quote Link to post Share on other sites
Mac 67 Posted January 29, 2011 Share Posted January 29, 2011 Hey guys, has anyone checked to see if the calibration data are already in the MSP430G2231 flash? Perhaps the only problem is the missing entries in the support files? I admit I know very little at this stage but I'm eager to learn. Cheerful regards, Mike Quote Link to post Share on other sites
NatureTM 100 Posted January 30, 2011 Author Share Posted January 30, 2011 Hey guys, has anyone checked to see if the calibration data are already in the MSP430G2231 flash? I thought someone did, but you made me a little nervous there for a second. I checked back over to this thread: http://www.43oh.com/forum/viewtopic.php?f=10&t=234 and sure enough, simpleavr had dumped the flash and confirmed that they were missing. Quote Link to post Share on other sites
Mac 67 Posted January 30, 2011 Share Posted January 30, 2011 I appreciate you checking. Thank you... Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.