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.

MSP430FR4133: Avoid while loop flag check.

Anonymous
Anonymous
Part Number: MSP430FR4133


Hi, I would like to know if there is any other way to do the next one:

while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0));

Although this kind of while loop flag check is quite common for MSP430 C coding, I would like to avoid this since I want to reduce the power consumption to the minimum possible. 

I attach the code below. This code allows you to get the best DCOFTRIM value and I found from here https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/590909?MSP430FR2533-Looking-for-any-examples-of-how-to-correctly-set-the-DCO. Thanks.


static void CS_softwareTrim() { unsigned int oldDcoTap = 0xffff; unsigned int newDcoTap = 0xffff; unsigned int newDcoDelta = 0xffff; unsigned int bestDcoDelta = 0xffff; unsigned int csCtl0Copy = 0; unsigned int csCtl1Copy = 0; unsigned int csCtl0Read = 0; unsigned int csCtl1Read = 0; unsigned int dcoFreqTrim = 3; unsigned char endLoop = 0; do { CSCTL0 = 0x100; // DCO Tap = 256 do { CSCTL7 &= ~DCOFFG; // Clear DCO fault flag }while (CSCTL7 & DCOFFG); // Test DCO fault flag //__delay_cycles((unsigned int)3000 * MCLK_FREQ_MHZ); // Wait FLL lock status (FLLUNLOCK) to be stable // Suggest to wait 24 cycles of divided FLL reference clock delay_ms(3); // Wait FLL lock status (FLLUNLOCK) to be stable // Suggest to wait 24 cycles of divided FLL reference clock while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0)); csCtl0Read = CSCTL0; // Read CSCTL0 csCtl1Read = CSCTL1; // Read CSCTL1 oldDcoTap = newDcoTap; // Record DCOTAP value of last time newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time dcoFreqTrim = (csCtl1Read & 0x0070)>>4; // Get DCOFTRIM value if(newDcoTap < 256) // DCOTAP < 256 { newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256 if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256 endLoop = 1; // Stop while loop else { dcoFreqTrim--; CSCTL1 = (csCtl1Read & (~DCOFTRIM_3)) | (dcoFreqTrim<<4); } } else // DCOTAP >= 256 { newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256 if(oldDcoTap < 256) // DCOTAP cross 256 endLoop = 1; // Stop while loop else { dcoFreqTrim++; CSCTL1 = (csCtl1Read & (~DCOFTRIM_3)) | (dcoFreqTrim<<4); } } if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256 { csCtl0Copy = csCtl0Read; csCtl1Copy = csCtl1Read; bestDcoDelta = newDcoDelta; } }while(endLoop == 0); // Poll until endLoop == 1 CSCTL0 = csCtl0Copy; // Reload locked DCOTAP CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked } //***************************************************************************** void CS_clockConfig() { __bis_SR_register(SCG0); // Disable FLL CSCTL3 = SELREF__REFOCLK; // Set REFO as FLL reference source CSCTL0 = 0; // clear DCO and MOD registers CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first CSCTL1 |= DCOFTRIMEN | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3; // DCOFTRIM=3, DCO Range = 8MHz CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz __delay_cycles(3); __bic_SR_register(SCG0); // Enable FLL CS_softwareTrim(); // Software Trim to get the best DCOFTRIM value CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz // default DCODIV as MCLK and SMCLK source*/ }

  • Hi, 

    Since CSCTL7.DCOFFG has been cleared before checking the FLL locked status, you can ignore it for the FLL lock status check. 

    • while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1));
    • or
    • while(CSCTL7 & 0x300);

    Thanks, 

    Lixin 

  • In open (startup) code, I would say you could leave out the lock loop. Your CPU will be running at some frequency not far from your target, and will step towards your target frequency over the next few milliseconds. If you don't need strict timing during startup (not uncommon), you can just continue and let it settle in the background..

    The loop in Software_Trim is different, since it waits for the lock then reads out the results the FLL calculated during the locking sequence. For that you really have to wait.

  • Anonymous
    0 Anonymous in reply to Lixin Chen1

    Thanks for your answer. I will fix this.

  • Anonymous
    0 Anonymous in reply to Bruce McKenney

    Thanks for your answer. Now I understand.

  • I'll just throw this in here:  User Guide (SLAU445I) Sec 3.2.11.2 suggests saving the DCOFTRIM value (3 bits) computed by Software_Trim in FRAM (e.g. Information FRAM) and re-using it on subsequent restarts.

    That tells me you don't need to run Software_Trim every time you start up. Rather, you only need to run it once (ever) for each physical device you have.

  • Anonymous
    0 Anonymous in reply to Bruce McKenney

    Ok, I will take it into account. Thanks again.

**Attention** This is a public forum