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/MSP430FR2633: Calibration Routine Infinite Loop

Part Number: MSP430FR2633

Tool/software: Code Composer Studio

I'm debugging an application that uses the Captivate Demo board (the 'phone' keypad) and is meant to talk to the design centre via UART. 

I've made some good progress with the code, and for the last month have had no problem with the capacitive touch. However, a couple of days ago during degbugging, suddenly the design centre is not getting messages. I tracked down the error and it seems the program is stuck in the command: 

CAPT_MANAGER_CALIBRATE_SENSOR(pApp->pSensorList[ui8SensorID]); 

There is a for loop in CAPT_Manager.c (in the sample code) that contains only this single line, but the program never progresses past it. This is a ROM command, so I can only see what it is doing if I step through the assembly code (and it's long). So, I'm wondering if anyone else has had issues with this? The issue came up as I was doing some coding on the UART to change how custom received messages are handled, so I'm not sure how I interfered with this function. Any insight would be greatly appreciated!

  • The function in question is covered in the Software Library -> How-To section of the CapTIvate Technology Guide, calibration is required for the solution to operate properly. Have you tried restarting with a fresh demo build? What if you changed to I2C communication instead of UART? It there any possibility that the hardware could have been damaged while testing/evaluating the solution?

    Regards,
    Ryan
  • HI Ryan,

    Thanks for the response. I did find a work around for the issue, but I'm very curious about the root cause. (No, hardware is definitely not the issue)

    I'm running a string of Neopixels using SPI for my application. At startup, before any of the calibration of the touchpad, I simply turn all the LED's (16) on and then off again to show the program has started. If I do this routine with all 16 I run into the problem I wrote about (the calibration routine is entered, but the code never progresses past it. Although, interrupts are still triggered). If I change the startup routine to use only 8 LEDs, the program runs as expected. Could the SPI (B0) interfere with the calibration? Or is it simply that the calibration must run before anything else is done?

  • Hi Joanna,

    Are you able to calibrate first and then turn on/off all 16 LEDs without an issue? Is there only a timing difference between starting up 8 or 16 LEDs? Calibration may need to be run before a certain amount of time after the MSP430 code has started up. e2e.ti.com/.../505564

    Regards,
    Ryan
  • Hi Ryan,

    I just tried changing the order (calibrate first, then trigger the 16 LEDs). The code doesn't work when this is the case. Again, with 8 LEDs it is fine either way. There is only a time difference between 8 and 16 LEDs, that is right. Note that because the timing of neopixels is very strict, when I update the LEDs I disable interrupts for that time. The LEDs are changed later in the code (according to a status), but it doesn't have a noticeable bad effect on the capactive touch. The only issue is toggling them at the start.

    Would the calibration need longer to run than the actual function allows? Is seems clear that my LED update is interrupting some key process of the ROM function, but without knowing what the limitations are, it is difficult to code around. The only note about this function in the design centre is:

    Calibrate a CapTIvate™ application (UI).

    This function calls the touch library calibration function on every sensor in the application.

    Parameters
    pApp is a pointer to the CapTIvate™ application to calibrate.
    Returns
    none
  • Hi Joanna,

    I would believe that disabling interrupts while updating the LEDs through SPI is probably contributing to the issue. I am currently consulting CapTIvate experts to further comment on this matter.

    Regards,
    Ryan
  • Ryan, Joanna,

    The calibration function performs a series of measurements for each element in the system, and adjusts analog tuning values until the measurement results for each element are within a target range (specified by the conversion gain and conversion count parameters in the CapTIvate Design Center). It is not time deterministic (the time spent in CAPT_calibrateSensor depends on the electrode capacitance externally as well as those conversion parameters). That being said, there is a hard limit on the function- it is not written in such a way that it can go on forever. If the conversion process fails to converge on a set of tuning values, it will complete testing all values and then set the calibration error flag. If for some reason the CapTIvate end of conversion interrupts are not being issued, then it could be possible to get stuck in this function.

    Since a series of CapTIvate measurements are being performed in CAPT_calibrateSensor, interrupts do need to be enabled for the sequence to complete (the CPU is programmed to go into LPM0/CPUOFF during the conversion in order to save power, and wake up at the end of each conversion via the CapTIvate end-of-conversion interrupt). It is perfectly fine to temporarily clear GIE, so long as it is ultimately restored so that the calibration process can complete. That being said, CAPT_calibrateUI() is called from the main thread- so it should be considered to be a blocking function from an application point of view that runs start to finish with nothing else going on unless you have set up other interrupt handlers. I don't see how you would be able to enable/disable GIE while that program was running, unless you were manipulating it via an interrupt handler. As such, GIE should be enabled when you enter the calibration function. Can you confirm that GIE is enabled before CAPT_calibrateUI() is called?

    In my experience, these kinds of issues that seem to be time and/or size related usually end up being due to something simple like a watchdog timer reset or an unintentional overwrite of memory (such as a bad pointer or a call stack overflow). Where in the code are you disabling the watchdog timer, and what method is used? There is a known bug right now with the pre-compiled watchdog timer hold DriverLib function due to a change in the device header file. Have you updated your IDE/toolchain recently? If so, it might be a watchdog issue. What is strange is that it works in the 8-LED case as you describe. I would expect that if it was a WDT problem it would not work at all.

    Regards,
    Walter
  • Walter,

    Here is the code snippet in question. Several of the functions are taken directly out of the demo code from the Captivate Design Center (including the Watchdog timer hold function). 

    void main(void)
    {
    //
    // Initialize the MCU
    // BSP_configureMCU() sets up the device IO and clocking
    // The global interrupt enable is set to allow peripherals
    // to wake the MCU.
    //
    WDT_A_hold(WDT_A_BASE);
    BSP_configureMCU();

    //
    // Initialize All LED's to turn on, then off to start
    // NOT a necessary part of the program...just a start-up signal
    //
    for(configureLEDs = (NUM_LEDS - 9); configureLEDs >= 0; configureLEDs--)
    setLEDColor(configureLEDs,0,0,0xFF);

    configureLED();

    __delay_cycles(10000000);

    for(configureLEDs = (NUM_LEDS - 9); configureLEDs >= 0; configureLEDs--)
    setLEDColor(configureLEDs,0,0,0);

    configureLED();

    __bis_SR_register(GIE);


    //
    // Start the CapTIvate application
    //
    MAP_CAPT_registerCallback(&modeKeypadSensor,&stay_Callback);
    MAP_CAPT_registerCallback(&numericKeypadSensor,&numeric_Callback);
    CAPT_appStart();


    //
    // Background Loop
    //
    while(1)
    {

    //CAPT_updateUI(&g_uiApp);
    //awsMessage = CAPT_checkForInboundPacket();

    CAPT_appHandler();

    .

    .

    .

    You can see that before the CAPT_appStart() function is called, the GIE is set. And within this function (in the CAPT_calibrateUI(&g_uiApp) function) is where the code hangs if I take out the '-9' in the configure LEDs variable. Note that later in the main, I reset the LEDs to represent state. At that point, all 16 do work. It is only at the start that they cause problems. 

    There are other interrupt handlers that are set up (interrupting on P1.1 signal level, and a UART receive), but these seem to have no effect on the calibration since the program doesn't hang on them (I assume the capTIvate interrupts have priority?)

    I am running this on a new computer, so I have CCS  Version: 7.0.0.00043

    Thank you,

    Joanna

  • Hi Joanna,


    Thank you for sharing your code.  From what I see here, nothing jumps out at me as something that would cause the application to hang.

    Let's try two things:

    1. Just to be sure that there is not the known WDT function compilation issue, can you switch out WDT_A_hold(WDT_A_BASE); with WDTCTL = WDTPW | WDTHOLD;, and re-test

    2. If #1 does not change anything, try running the CapTIvate setup (CAPT_appStart()) with the other interrupts that you mentioned disabled (GPIO and UART).  In fact, see if you can disable any other enabled interrupts.  CapTIvate itself is a low priority IRQ; GPIO and serial interfaces are higher priority.  This is because it is okay to delay reading a CapTIvate result a few milliseconds, but it may not be okay to delay reading a UART.  You can also verify that you are hitting CapTIvate interrupts by setting a breakpoint in the CapTIvate ISR (it's inside /captivate/BASE/CAPT_ISR.c).

    Walter

  • Hi Walter,

    Here are the results from your suggestions:

    1. I replaced WDT_A_hold(WDT_A_BASE); with WDTCTL = WDTPW | WDTHOLD; and reran the code (with the 16 LEDs enabled), but there was no change. Again, if I ran it with only 8 LEDs using the replaced line the program functions as expected.

    2. There are 3 non-capTIvate interrupts: The SPI which runs the LEDs, the P1 Vector interrupt, and the UART. The UART interrupt is enabled within CAPT_appStart(), so I didn't worry about disabling that one. I changed the code to the P1vector was not enabled until after the CAPT_appStart() was called. The SPI I enabled to do the flash at the start, but then disabled before calling CAPT_appStart(). Again, the same result where 8 LEDs caused no issues, but 16 did. Here is the changes to the code.

    void main(void)
    {
    //
    // Initialize the MCU
    // BSP_configureMCU() sets up the device IO and clocking
    // The global interrupt enable is set to allow peripherals
    // to wake the MCU.
    //
    //WDT_A_hold(WDT_A_BASE);
    WDTCTL = WDTPW | WDTHOLD;
    BSP_configureMCU();

    //
    // Initialize All LED's to turn on, then off to start
    // NOT a necessary part of the program...just a start-up signal
    //
    for(configureLEDs = (NUM_LEDS); configureLEDs >= 0; configureLEDs--)
    setLEDColor(configureLEDs,0,0,0xFF);

    configureLED();

    __delay_cycles(10000000);

    for(configureLEDs = (NUM_LEDS); configureLEDs >= 0; configureLEDs--)
    setLEDColor(configureLEDs,0,0,0);

    configureLED();

    __bis_SR_register(GIE);


    EUSCI_B_SPI_disable(EUSCI_B0_BASE);
    //
    // Start the CapTIvate application
    //
    MAP_CAPT_registerCallback(&modeKeypadSensor,&stay_Callback);
    MAP_CAPT_registerCallback(&numericKeypadSensor,&numeric_Callback);
    CAPT_appStart();

    P1IE |= BIT6;
    EUSCI_B_SPI_enable(EUSCI_B0_BASE);

    //
    // Background Loop
    //
    while(1)
    {
    CAPT_appHandler();

    In both cases with running 16 LEDs, I set a breakpoint n the CAPT_ISR.c. It is not tripped in either case running 16.

    I stepped through again to see what function within CAPT_appStart() was causing the program to hang, and it gets stuck at CAPT_calibrateUI(&g_uiApp); (within CAPT_App.c) in each case where the problem occurs.

    Thanks again for the help!

    Joanna

**Attention** This is a public forum