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.

CCS/MSP430I2041: What is the correct method of selecting DCO operation in external resistor mode?

Part Number: MSP430I2041
Other Parts Discussed in Thread: MSP-TS430RHB32A, , MSP430I2040

Tool/software: Code Composer Studio

I am using the MSP430i2041 installed in a MSP-TS430RHB32A - 32-pin Target Development Board, and i would like to use the DCO in external resistor mode.

I am working with the blink program for test purposes.

I have added the file "low_level_init.c" in the project file list of my CCS V7-3 workspace (see attached image)

i have inserted the line "CSCTL0 = DCOR;"  into the "low_level_init.c" file as follows:

        /* Calibrate DCO */
        CSIRFCAL = *(TLV_address_for_parse + TLV_CAL_CSIRFCAL);
        CSIRTCAL = *(TLV_address_for_parse + TLV_CAL_CSIRTCAL);
        CSCTL0 = DCOR;
        CSERFCAL = *(TLV_address_for_parse + TLV_CAL_CSERFCAL);
        CSERTCAL = *(TLV_address_for_parse + TLV_CAL_CSERTCAL);

my two specific questions are:

1) is the above code snippet sufficient to program the MSP430 to use the external DCO resistor, or do i need additional code?

2) will the CCS compiler-linker build automatically create .obj and  include my modified "low_level_init.c", or do i need to flag this in an option panel somewhere?

thanks

Jack

  • Hi Jack,

    1) yes, "CSCTL0=DCOR" will switch your DCO to use the external resistor and leave the other CSCTL0 bits on their default values. Have a look at MSP430i2xx Family User's Guide section 4.2.1.2 for all details.

    2) I'm not sure I fully understood this question. You'd need to insert your DCO code snippet into a function (which is properly declared and defined) and then do a function call in your blink.c (which I assume contains your main(), right?). Does this answer your question?

    Please let me know if this answered your questions or if I misunderstood them.

    Best regards,

    Britta

  • Britta, thanks for the prompt reply. I still have doubts about the Clock and "low_level_init.c" linking.

    I will provide more context to clarify my questions:

    Q1) Prior to posting, I had searched this forum and also studied the I20xx User's Guide section 4.2.1.2. to try and answer my own questions.

    However it is actually the following section of the user guide which I found more confusing than helpful:

    4.2.4.2 Use Case 2: DCO Operation With External Resistor – No Fault

    Description

    1. After BOR, the DCO starts in internal resistor mode.

    2. The DCO produces a clock signal at an uncalibrated frequency after the specified DCO startup time.

    3. User code loads the internal resistor frequency calibration value from TLV table in flash information

    memory into the CSIRFCAL register.

    NOTE: Steps 3 through 5 make sure that the 16.384-MHz calibrated clock is available in the internal

    resistor mode during fail-safe operation.

    4. The clock is stopped and the calibration process is initiated within the DCO when CSIRFCAL is written.

    5. When calibration is complete, the DCO produces a calibrated 16.384-MHz clock with the internal

    resistor.

    6. User code selects external resistor mode by setting the DCOR bit.

    7. DCO fault signal is asserted immediately, which sets the DCOF and OFIFG bits.

    8. Clock is stopped and fault detection circuitry is turned on within the DCO.

    9. The DCO performs a health check of the resistor that is connected to the ROSC pin.

    In this use case, assume that the recommended resistor is connected properly on the ROSC pin.

    10. After the DCO startup delay (tdcoon), the DCO produces an uncalibrated clock in the external resistor

    mode.

    11. The DCO fault signal is deasserted by the DCO, which clears the DCOF bit. The OFIFG bit remains

    set until cleared by software.

    12. User code checks the DCOF bit and proceeds to load external resistor frequency calibration value

    from TLV table in flash information memory into the CSERFCAL register.

    13. Clock is stopped and calibration process is initiated in the DCO when CSERFCAL is written.

    14. When the calibration is complete, the DCO produces an 16.384-MHz clock with the external resistor.

    SLAU335–

     I understand that my user code is responsible for setting the DCOR bit,

    however Steps 6-14 involve a lot of other procedures, including  stopped clocks, fault checks, startup delays, fault flags, bits set by processor, etc.

    I don't know how much of this is magically performed by the msp430i2041, and which parts I am supposed to code, or account for.

    Q 1a) do i need to add a delay loop in my code after setting CSCTL0=DCOR to wait for steps 9, 10 and 11 to compete?

    Q 1b) or does the boot procedure on the silicon halt the processor execution until the peripheral self checks are completed?

    Q 1c) do i really need to perform step 12 (DCOF bit check) before loading CSERFCAL register? (what would I do with the answer anyway?)

    Q 1d) how do i confirm that the external resistor is being used for the clock system? i cant just use a scope to look at the clock signal on an I/O pin because the clock frequency is the same regardless of using internal vs external resistors.

    My second question relates to how the mysterious low_level_init.c routine is linked by CCS into the executable.

    When a new project code example is created using resource manager inside of CCS, (such as blink), only the main.c is created.

    When a code example is taken from ti slac676f, then both main.c and  low_level_init.c are available.

    the comment section of  low_level_init.c states:

    //******************************************************************************
    // MSP430i20xx Initialization Routines - low_level_init.c
    //
    // This function is called by the start-up code before "main" is called, and
    // before data segment initialization is performed. The function affects the
    // following modules:
    //  - JTAG - JTAG is disabled
    //  - TLV - A TLV checksum is performed
    //  - PMM - The shared reference is calibrated to 1.16V
    //  - Clock System - The DCO is calibrated to 16.384MHz
    //  - SD24 - The SD24 reference voltage trimming is calibrated
    //
    // The return value of this function controls if data segment initialization
    // should take place. If 0 is returned, it is bypassed.
    //
    // Any code example or application written for the MSP430i20xx which takes
    // advantage of any of the affected modules is suggested to include this
    // function to ensure full calibration of the application.
    //
    // Additionally, this initialization routine is suggested for small, short
    // code examples to ensure the JTAG will be unlocked. The i20xx series of
    // devices requires execution of 64 MCLK cycles before the JTAG can be unlocked.
    // If a device does not execute 64 MCLK cycles, it cannot be accessed via JTAG.
    //******************************************************************************

    the blink example comments state:

    //  MSP430i20xx Demo - Blink LED Example
    //
    //  Description: Blink LED in software.
    //
    //  ACLK = 32kHz, MCLK = SMCLK = Calibrated DCO = 16.384MHz
    //  * Ensure low_level_init.c is included when building/running this example *

    Q2a) so apparently I don't need to call the routine from inside my main, because it is called by the start up code, whatever or wherever that is, maybe on the silicon, or maybe generated by the compiler?

    Q2b) when a  project code example is created using resource manager inside of CCS, low_level_init.c is not present in the project, but the linker does not complain, it appears that a version of the
    low_level_init.ojb is available in one of the .h files, or one of the library's, or somewhere else?

    Q2c) when I create an empty project in CCS, and then copy both blink.c and  low_level_init.c from  slac676f, does the CCS build operation automatically use my local project version of the low_level_init.c to make an .obj and then link it properly, or does it use one of the pre-existing library versions, and how do i tell which?

    sorry if this question should be in the CCS forum, but low_level_init.c seems to be specific to msp430I20xx family. The user guide does not seem to discuss this aspect of the i20xx.

    sorry for the novice questions, but CCS is a very "feature rich" program, which is a euphemism for "incredibly complicated", and much of what happens during build is a mystery to me.

    thanks again for the prompt reply.

    Jack

     

     

    User code selects external resistor mode by setting the DCOR bit.

  • Hi Jack,

    please excuse the delay in my response, it took me a while to work through your questions.
    Regarding your second question:
    Q2c) If I understood you right, you want to make changes in the low_level_init.c and make sure, CCS uses your local file. Before building, CCS should check if there's a low_level_init.c in your project and, if so, use that file. This is in fact not MSP430I20xx specific but true for MSP430.

    I am still investigating all details of your Question 1 to give you the best answer, hopefully within this week. Again, please apologize for the delayed response.

    Best regards,
    Britta
  • Hi Britta,

    thanks for the answer to the low_level_init.c question. that makes sense.

    I also have been researching over the weekend and found some example code (msp430i20xx_cs_03.c) in  the ti slac676f, code examples download

    this shows exactly how to properly select the external resistor.

    as it turns out the statement     CSCTL0  =  DCOR; should be placed in the main routine, just after watchdog timer disable see code below.

    so i will mark this post as answered, thanks again.

    Also, as a post script, i looked at the low_level_init.c code, and I have one recommendation for anyone who might be using this processor.

    I commented out  the following line:

        //    SYSJTAGDIS = JTAGDISKEY; (see below)

    this avoids the problem of jtag lock out (which happened to me during testing/debugging)

    this statement might be useful for production code, but its too dangerous to use during testing.

    thanks again for the help

    Jack

    ------------------

    //***************************** msp430i20xx_cs_03.c *************************************************
    //  MSP430i20xx Demo - Basic Clock, MCLK = DCO/2, SMCLK = DCO/4, External Resistor
    //
    //  Description: Buffer MCLK(DCO/2) on P1.0 and SMCLK(DCO/4) on P1.1. For
    //    external resistor mode, it is suggested that a 20kOhm resistor be connected
    //    to ROSC pin.
    //
    //  ACLK = 32kHz, MCLK = DCO/2 = 8.192MHz, SMCLK = DCO/4 = 4.096MHz
    //  * Ensure low_level_init.c is included when building/running this example *
    //
    //               MSP430i20xx
    //             -----------------
    //         /|\|                |
    //          | |            ROSC|--\/\/\--AVSS
    //          --|RST             |  20kOhm
    //            |                |
    //            |            P1.1|-->SMCLK = DCO/4
    //            |            P1.0|-->MCLK  = DCO/2
    //
    //  T. Witt
    //  Texas Instruments, Inc
    //  September 2013
    //  Built with Code Composer Studio v5.5
    //******************************************************************************
    #include "msp430.h"

    void main(void) {
        WDTCTL = WDTPW | WDTHOLD;       // Stop Watchdog Timer

        CSCTL0  =  DCOR;                // External Resistor
        CSCTL1 |=  DIVM__2 | DIVS__4;   // MCLK = DCO/2, SMCLK = DCO/4

        P1DIR  |=   BIT0 | BIT1;        // P1.0, P1.1 Output
        P1SEL1 |=   BIT0 | BIT1;        // MCLK, SMCLK Pin Function
        P1SEL0 &= ~(BIT0 | BIT1);

        while(1);
    }

    ----------------  how to avoid bricking your msp430 ---------

    low_level_init code snippet:

        /* Check JTAG password locations and disable JTAG if passwords don't match.
         * Else the JTAG will be enabled in the 64th cycle after reset.
         */
        if ((*jtagPwd != 0x00000000) && (*jtagPwd != 0xFFFFFFFF))
        {
            /* Disable JTAG */
        //    SYSJTAGDIS = JTAGDISKEY; commented out to avoid accidental bricking of processor
        }


  • Hi John, apparently i have bricked a MSP430i2041 , do you know how to enable jtag again? i have been reading about BSL but i could not find documents refering to this family , thanks for your advice to avoid bricking the msp430, i will consider it in the future.
  • Fidel, so sorry to hear you disabled your JTAG access, I empathize, as I know EXACTLY how you feel.

    When it happened to me, I also looked through the msp430i20xx documentation and these forums, and only found references to the BSL, mass erase commands for other msp430 families (which required serial communication and special codes during restart). So i was unable to make any attempt to revive my chip, and resorted to replacing the device, luckily the ti dev board has a simple ZIF socket. I have designed, and populated, my own circuit board for the msp430i2040, so if i brick one of those, it will require soldering to replace, hence my commenting out the code in the startup routine.

    sorry i'm not much help, but if it's any consolation, the msp430i2041 chips make very, very small bricks.

    Jack

  • Hi Jhon,

    thanks for you quick reply, fortunately im working with the ti dev board and im just going to replace the MSP, now i am having some troubles using the modified low_level_init, i placed it inside my project and included it in the main file but i get errors about redefinitions, could you give me some guidance on how to use my modified low_level_init file, sorry if this is a newbie question, im new using CCS and MSP.

    Fidel

  • Hi Fidel,

    I don't recall ever getting redefinition errors (?) myself. can you use the snipping tool to screen grab the errors and post them here.

    One suggestion:

    Ensure your main program does not contain a call to l low_level_init, because that happens auto-magically,

    the compiler linker generates the call, so you don't have to.

    If you continue to have the problem: you might consider starting a new thread with a detailed description of the error, and your screen grabs.

    New threads get wider attention.

    Jack

  • Hi Jack,

    I have re-read all this post again, and it seems that i just need to place the low_level_init .c file inside the project and CCS automatically is going to use it, i don't even need to include it or make a call to it, am i right ? or am i missing something? , if i understood correctly this solves my problem, thanks for your help.

    Fidel
  • Quote: "i just need to place the low_level_init .c file inside the project and CCS automatically is going to use it, i don't even need to include it or make a call to it, am i right ?"
    A: Yes
    that is all you need to do normally.
    Jack

**Attention** This is a public forum