Skip to content

CC430 DriverLib Usage

Brenton Salmi edited this page Feb 3, 2018 · 1 revision

It is desired to use the TI DriverLib library as much as possible to standardize and maintain an organized firmware development. These tools also allow better functionality with less work of development. The CC430F6137 is compatible with the MSP430F5xx_6xx platform.

Creating A New DriverLib Based Project

After installing MSP430ware in code composer the standard method to create a new project (mostly to setup and configure the compiler/linker correctly) is to import the "Empty Project" and rename it to the desired filename.

Note that the User's Guide is wrong and the Empty Project should be used as a base, there is no "new file template". https://e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/517229

Example

Below is a quick example of ADC temperature sensing (provided from TI) using DriverLib. Notice that the programming style is much more API centric. Also note the method used in the #pragma references to support both TI and GNU compilers.

#include "driverlib.h"

long temp;
volatile long IntDegF;
volatile long IntDegC;

void main (void)
{
    //Stop Watchdog Timer
    WDT_A_hold(WDT_A_BASE);

    //Initialize the ADC12_A Module
    /*
     * Base Address of ADC12_A Module
     * Use internal ADC12_A bit as sample/hold signal to start conversion
     * USE MODOSC 5MHZ Digital Oscillator as clock source
     * Use default clock divider of 1
     */
    ADC12_A_init(ADC12_A_BASE,
        ADC12_A_SAMPLEHOLDSOURCE_SC,
        ADC12_A_CLOCKSOURCE_ADC12OSC,
        ADC12_A_CLOCKDIVIDER_1);

    ADC12_A_enable(ADC12_A_BASE);

        ADC12_A_enable(ADC12_A_BASE);

    /*
     * Base Address of ADC12_A Module
     * For memory buffers 0-7 sample/hold for 768 clock cycles
     * For memory buffers 8-15 sample/hold for 4 clock cycles (default)
     * Disable Multiple Sampling
     *
     * Note: ADC12_A may have a minimum sample rate of 30us or 100us.
     * This example uses a sample time of ~154us to ensure it works.
     * 256 cycles (51.2us) or 512 cycles (100.4us) may be used, but
     * resulting readings may be less accurate.
     */
    ADC12_A_setupSamplingTimer(ADC12_A_BASE,
        ADC12_A_CYCLEHOLD_768_CYCLES,
        ADC12_A_CYCLEHOLD_4_CYCLES,
        ADC12_A_MULTIPLESAMPLESDISABLE);

    //Configure Memory Buffer
    /*
     * Base Addres of ADC12_A Module
     * Configure memory buffer 0
     * Map temp sensor to memory buffer 0
     * Vref+ = Vref+ (int)
     * Vref- = AVss
     * Memory buffer 0 is not the end of a sequence
     */
    ADC12_A_configureMemoryParam param = {0};
    param.memoryBufferControlIndex = ADC12_A_MEMORY_0;
    param.inputSourceSelect = ADC12_A_INPUT_TEMPSENSOR;
    param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_INT;
    param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
    param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;
    ADC12_A_configureMemory(ADC12_A_BASE ,&param);

    //Enable memory buffer 0 interrupt
    ADC12_A_clearInterrupt(ADC12_A_BASE,
        ADC12IFG0);
    ADC12_A_enableInterrupt(ADC12_A_BASE,
        ADC12IE0);

    //Configure internal reference
    //If ref generator busy, WAIT
    while ( REF_ACTIVE == Ref_isRefGenBusy(REF_BASE) ) ;
    //Select internal ref = 1.5V
    Ref_setReferenceVoltage(REF_BASE,
        REF_VREF1_5V);
    //Internal Reference ON
    Ref_enableReferenceVoltage(REF_BASE);

    //Delay (~75us) for Ref to settle
    __delay_cycles(75);

    while (1)
    {
        //Enable/Start first sampling and conversion cycle
        /*
         * Base address of ADC12_A Module
         * Start the conversion into memory buffer 0
         * Use the repeated sequence of channels
         */
        ADC12_A_startConversion(ADC12_A_BASE,
            ADC12_A_MEMORY_0,
            ADC12_A_SEQOFCHANNELS);

        //LPM4 with interrupts enabled
        __bis_SR_register(LPM4_bits + GIE);
        __no_operation();

        //Temperature in Celsius
        //((A10/4096*1500mV) - 680mV)*(1/2.25mV) = (A10/4096*667) - 302
        //= (A10 - 1855) * (667 / 4096)
        IntDegC = ((temp - 1855) * 667) / 4096;

        //Temperature in Fahrenheit
        //((A10/4096*1500mV) - 640mV)*(1/1.25mV) = (A10/4096*1200) - 512
        //= (A10 - 1748) * (1200 / 4096)
        IntDegF = ((temp - 1748) * 1200) / 4096;

        //SET BREAKPOINT HERE and watch IntDegC and IntDegF
        __no_operation();
    }
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC12_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(ADC12_VECTOR)))
#endif
void ADC12ISR (void)
{
    switch (__even_in_range(ADC12IV,34)){
        case  0: break;   //Vector  0:  No interrupt
        case  2: break;   //Vector  2:  ADC overflow
        case  4: break;   //Vector  4:  ADC timing overflow
        case  6:          //Vector  6:  ADC12IFG0
            //Move results, IFG is cleared
            temp = ADC12_A_getResults(ADC12_A_BASE,
            ADC12_A_MEMORY_0);

            //Exit active CPU
            __bic_SR_register_on_exit(LPM4_bits);
            break;
        case  8: break;   //Vector  8:  ADC12IFG1
        case 10: break;   //Vector 10:  ADC12IFG2
        case 12: break;   //Vector 12:  ADC12IFG3
        case 14: break;   //Vector 14:  ADC12IFG4
        case 16: break;   //Vector 16:  ADC12IFG5
        case 18: break;   //Vector 18:  ADC12IFG6
        case 20: break;   //Vector 20:  ADC12IFG7
        case 22: break;   //Vector 22:  ADC12IFG8
        case 24: break;   //Vector 24:  ADC12IFG9
        case 26: break;   //Vector 26:  ADC12IFG10
        case 28: break;   //Vector 28:  ADC12IFG11
        case 30: break;   //Vector 30:  ADC12IFG12
        case 32: break;   //Vector 32:  ADC12IFG13
        case 34: break;   //Vector 34:  ADC12IFG14
        default: break;
    }
}

This code compile, programs, and runs on Faraday hardware!

Clone this wiki locally