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: CCS/MSP430i2041

Part Number: MSP430I2041


Tool/software: Code Composer Studio

Dear all,

So, I botched up two example codes, and here it is:

#include "driverlib.h"

uint16_t results[4];                       // SD24 Conversion and Temp Results
                                                // results[0] = raw SD24 results
                                                // results[1] = temp in K
                                                // results[2] = temp in C
                                                // results[3] = temp in F
uint8_t Flag_1 = 0;                        //Flag 1 for ADC
unsigned int Flag_2 = 0;                        //Flag 2 for Timer


#define TIMER_PERIOD 10
unsigned int TIMER_PERIOD_PERIOD = 0;

void main(void) {
    // Stop WDT
    WDT_hold(WDT_BASE);

    // Internal ref
    SD24_init(SD24_BASE, SD24_REF_INTERNAL);

    //Ch0 single mode, internal temp sensor
    SD24_initConverterAdvancedParam param = {0};
    param.converter = SD24_CONVERTER_0;
    param.conversionMode = SD24_SINGLE_MODE;
    param.groupEnable = SD24_NOT_GROUPED;
    param.inputChannel = SD24_INPUT_CH_TEMPERATURE;
    param.dataFormat = SD24_DATA_FORMAT_2COMPLEMENT;
    param.interruptDelay = SD24_FOURTH_SAMPLE_INTERRUPT;
    param.oversampleRatio = SD24_OVERSAMPLE_256;
    param.gain = SD24_GAIN_1;
    SD24_initConverterAdvanced(SD24_BASE, &param);
    SD24_enableInterrupt(SD24_BASE, SD24_CONVERTER_0, SD24_CONVERTER_INTERRUPT);

    // Delay ~200us for 1.2V ref to settle
    __delay_cycles(3200);

    // Set P2.1 as output pin to drive the LED
    GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);

    // Timer_A Setup
    Timer_A_initUpModeParam upModeConfig =
    {
          TIMER_A_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
          TIMER_A_CLOCKSOURCE_DIVIDER_1,      // SMCLK/8 = 256kHz
          TIMER_PERIOD,                       // 250ms
          TIMER_A_TAIE_INTERRUPT_DISABLE,     // Disable Overflow ISR
          TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE, // Enable CCR0 interrupt
          TIMER_A_DO_CLEAR                    // Clear Counter
      };

    while(1) {
        // Start conversion
        SD24_startConverterConversion(SD24_BASE, SD24_CONVERTER_0);
        // Enter LPM0 w/ interrupts
        //__bis_SR_register(LPM0_bits | GIE);
        // For debugger    
        __no_operation();
        if (Flag_1 == 1)// the Interrupt routine is complete
        {

            Flag_2 = 1;
            GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);// Turn on LED
            // Configure the timer to use ACLK and interrupt when timer reaches CCR0
            Timer_A_initUpMode(TIMER_A0_BASE, &upModeConfig);
            Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);
            // Calculate Temperatures in different scales
            results[1] = ((unsigned long)results[0] * 1200)/70711;
            results[2] = results[1] - 273;
            results[3] = (results[2] * 9/5) + 32;
            Flag_2 = 0;

            __delay_cycles(1000);
            __no_operation();
            TIMER_PERIOD_PERIOD = 0;
            GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1); // Turn Off LED
            Flag_1 = 0;
            //Flag_2 = 0;

        }
        __bis_SR_register(LPM0_bits | GIE);
        //GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
        // Calculate Temperatures in different scales
        //results[1] = ((unsigned long)results[0] * 1200)/70711;
        //results[2] = results[1] - 273;
        //results[3] = (results[2] * 9/5) + 32;

        __no_operation();                       // SET BREAKPOINT HERE


    }
}
//----------------------------------------------------------------------------------------------------------------
//Interrupt Functions
//---------------------------------------------------------------------------------------------------------------
//ADC
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=SD24_VECTOR
__interrupt void SD24_ISR(void) {
#elif defined(__GNUC__)
void __attribute__ ((interrupt(SD24_VECTOR))) SD24_ISR (void)
{
#else
#error Compiler not supported!
#endif
    switch (__even_in_range(SD24IV,SD24IV_SD24MEM3))
    {
        case SD24IV_NONE: break;
        case SD24IV_SD24OVIFG: break;
        case SD24IV_SD24MEM0:
                   // Save CH0 results (clears IFG)
                   results[0] = SD24_getHighWordResults(SD24_BASE, SD24_CONVERTER_0);
                   break;
        case SD24IV_SD24MEM1: break;
        case SD24IV_SD24MEM2: break;
        case SD24IV_SD24MEM3: break;
        default: break;
    }
    Flag_1 = 1;
   // __bic_SR_register_on_exit(LPM0_bits);       // Wake up from LPM0

}

//Timer_A---------------------------------------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER0_A0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(TIMER0_A0_VECTOR)))
#endif
void TA0_ISR(void) {
    // TIMER0_A0_VECTOR only contains CCR0 interrupt
    // No need to check/clear interrupt flags, toggle LED to show ISR reached
    //GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN4);
    if (Flag_2 == 1)
    {
        TIMER_PERIOD_PERIOD = TIMER_PERIOD_PERIOD +1;
    }

}

The idea is to time the calculation operation of converting the unsigned long into Kelvin, Celcius, and Fahrenheit, over and over again (For consistency). 

The Flag_1, checks if a new ADC data is available.

The Flag_2 is to stop the TIMER_PERIOD_PERIOD counter.

Thus the time taken should be = 61.04(ns) * 10(TIMER_PERIOD) * TIMER_PERIOD_PERIOD.

I am pretty sure, this is the wrong way to approach this, so any help would be appreciated, and where do I put the breakpoint to read the TIMER_PERIOD_PERIOD value?

Thank you.

Regards,

Neal

  • I suggest a more direct approach:

    Run TIMER_A0 in Continuous mode since that will make your arithmetic simpler.

    Then bracket the sequence you want to time with something like:
    > uint16_t start, stop, ticks;
    > start = Timer_A_getCounterValue(TIMER_A0_BASE); // TA0R before
    [ the stuff you want to time]
    > stop = Timer_A_getCounterValue(TIMER_A0_BASE); // TA0R after
    > ticks = stop - start; // Execution time in timer ticks (1.024MHz)

    If the counter register overflows to 0 in the meantime (not unlikely), unsigned subtraction will take care of that.

    If what you want to time takes longer than 65536/1.024=64 milliseconds (I don't think it will), the timer will cycle and you will get odd results. If that happens, increase the clock divider, e.g. TIMER_A_CLOCKSOURCE_DIVIDER_2.

    [Edit: In case you're wondering: you don't need the timer ISR in this case.]

  • Dear Bruce,

    Thanks a ton mate, it worked like a charm.  Correct me if I am wrong, but the Timer counter doesn't use the CPU core, rather is it own supplementary thing?

    This is the final code:



    #include "driverlib.h"
    
    uint16_t results[4];                       // SD24 Conversion and Temp Results
                                                    // results[0] = raw SD24 results
                                                    // results[1] = temp in K
                                                    // results[2] = temp in C
                                                    // results[3] = temp in F
    uint8_t Flag_1 = 0;                        //Flag 1 for ADC
    uint16_t start, stop, ticks;
    
    
    
    void main(void) {
        // Stop WDT
        WDT_hold(WDT_BASE);
    
        // Internal ref
        SD24_init(SD24_BASE, SD24_REF_INTERNAL);
    
        //Ch0 single mode, internal temp sensor
        SD24_initConverterAdvancedParam param = {0};
        param.converter = SD24_CONVERTER_0;
        param.conversionMode = SD24_SINGLE_MODE;
        param.groupEnable = SD24_NOT_GROUPED;
        param.inputChannel = SD24_INPUT_CH_TEMPERATURE;
        param.dataFormat = SD24_DATA_FORMAT_2COMPLEMENT;
        param.interruptDelay = SD24_FOURTH_SAMPLE_INTERRUPT;
        param.oversampleRatio = SD24_OVERSAMPLE_256;
        param.gain = SD24_GAIN_1;
        SD24_initConverterAdvanced(SD24_BASE, &param);
        SD24_enableInterrupt(SD24_BASE, SD24_CONVERTER_0, SD24_CONVERTER_INTERRUPT);
    
        // Delay ~200us for 1.2V ref to settle
        __delay_cycles(3200);
    
        // Set P2.1 as output pin to drive the LED
        GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);
    
        // Timer_A Setup
        Timer_A_initContinuousModeParam continuousModeConfig =
        {
              TIMER_A_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
              TIMER_A_CLOCKSOURCE_DIVIDER_1,      // SMCLK/8 = 256kHz
              //TIMER_PERIOD,                       // 250ms
              TIMER_A_TAIE_INTERRUPT_DISABLE,     // Disable Overflow ISR
              TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE, // Enable CCR0 interrupt
              TIMER_A_DO_CLEAR                    // Clear Counter
          };
    
        Timer_A_initContinuousMode(TIMER_A0_BASE, &continuousModeConfig);
    
        while(1)
        {
            // Start conversion
            SD24_startConverterConversion(SD24_BASE, SD24_CONVERTER_0);
    
            // For debugger    
            __no_operation();
            if (Flag_1 == 1)// the Interrupt routine is complete
            {
                GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);// Turn on LED
                //
                start = Timer_A_getCounterValue(TIMER_A0_BASE); // TA0R before the stuff
                // Calculate Temperatures in different scales
                results[1] = ((unsigned long)results[0] * 1200)/70711;
                results[2] = results[1] - 273;
                results[3] = (results[2] * 9/5) + 32;
                stop = Timer_A_getCounterValue(TIMER_A0_BASE); // TA0R after the stuff
                ticks = stop - start; // Execution time in timer ticks (1.024MHz)
    
    
                __delay_cycles(1000);
                __no_operation();
                GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1); // Turn Off LED
                Flag_1 = 0;
    
            }
            __bis_SR_register(LPM0_bits | GIE);
    
    
            __no_operation();                       // SET BREAKPOINT HERE
    
    
        }
    }
    //----------------------------------------------------------------------------------------------------------------
    //Interrupt Functions
    //---------------------------------------------------------------------------------------------------------------
    //ADC
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=SD24_VECTOR
    __interrupt void SD24_ISR(void) {
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(SD24_VECTOR))) SD24_ISR (void)
    {
    #else
    #error Compiler not supported!
    #endif
        switch (__even_in_range(SD24IV,SD24IV_SD24MEM3))
        {
            case SD24IV_NONE: break;
            case SD24IV_SD24OVIFG: break;
            case SD24IV_SD24MEM0:
                       // Save CH0 results (clears IFG)
                       results[0] = SD24_getHighWordResults(SD24_BASE, SD24_CONVERTER_0);
                       break;
            case SD24IV_SD24MEM1: break;
            case SD24IV_SD24MEM2: break;
            case SD24IV_SD24MEM3: break;
            default: break;
        }
        Flag_1 = 1;
        __bic_SR_register_on_exit(LPM0_bits);       // Wake up from LPM0
    
    }
    
    

    Regards,

    Neal

  • The timer isn't part of the CPU proper, but SMCLK and MCLK come from the same base clock, so they're in sync. If they have the same divisors (yours do), an SMCLK is equal to a CPU clock (MCLK).

    I mis-remembered how the clocks were set at startup. The MCLK/SMCLK dividers are /1 (not /16 as I remembered), so the timer counts 1/16.384MHz, and its span is 4ms. [Ref User Guide (SLAU335) sec. 4.2.1.1]

  • Dear Bruce,

    Thanks again. Yeah the clocks, I thought as much, anyway, I just multiply my ticks count with 61.04ns, and I reckon that does the trick.

    Thanks again, if I haven't before.

    Regards,
    Neal
  • Hi Neal,

    I'm glad to hear that Bruce already solved your issue!
    Happy coding,
    Britta

**Attention** This is a public forum