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.

RTOS/CC1310: ADCBuf driver

Part Number: CC1310

Tool/software: TI-RTOS

Hi,

I am trying to use the ADCBuf driver, but I am having problems to run it in my application.

To validate the driver in my application, I made a very simple adc.c file based in the adcbufcontinuous_CC1310_LAUNCHXL_TI example. I basicly removed the UART part from the example.

That is what I am using:

#define ADCBUFFERSIZE    (10)

uint16_t sampleBufferOne[ADCBUFFERSIZE];
uint16_t sampleBufferTwo[ADCBUFFERSIZE];
uint32_t microVoltBuffer[ADCBUFFERSIZE];
uint32_t buffersCompletedCounter = 0;

void adcBufCallback(ADCBuf_Handle handle, ADCBuf_Conversion *conversion,
    void *completedADCBuffer, uint32_t completedChannel) {

    /* Adjust raw adc values and convert them to microvolts */
    ADCBuf_adjustRawValues(handle, completedADCBuffer, ADCBUFFERSIZE,
        completedChannel);
    ADCBuf_convertAdjustedToMicroVolts(handle, completedChannel,
        completedADCBuffer, microVoltBuffer, ADCBUFFERSIZE);
}

void adc_init(void)
{
    ADCBuf_Handle adcBuf;
    ADCBuf_Params adcBufParams;
    ADCBuf_Conversion continuousConversion;

    /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */
    ADCBuf_Params_init(&adcBufParams);
    adcBufParams.callbackFxn = adcBufCallback;
    adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_CONTINUOUS;
    adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
    adcBufParams.samplingFrequency = 200;
    adcBuf = ADCBuf_open(CC1310_LAUNCHXL_ADCBuf0, &adcBufParams); // <==== Hwi_excHandler() AFTER CALLING THIS

    /* Configure the conversion struct */
    continuousConversion.arg = NULL;
    continuousConversion.adcChannel = 0;
    continuousConversion.sampleBuffer = sampleBufferOne;
    continuousConversion.sampleBufferTwo = sampleBufferTwo;
    continuousConversion.samplesRequestedCount = ADCBUFFERSIZE;

    if (!adcBuf){
        System_abort("adcBuf did not open correctly\n");
    }

    /* Start converting. */
    if (ADCBuf_convert(adcBuf, &continuousConversion, 1) !=
        ADCBuf_STATUS_SUCCESS) {
        System_abort("Did not start conversion process correctly\n");
    }
}

But after call ADCBuf_open the application goes to:

/*
 *  ======== Hwi_excHandler ========
 */
Void Hwi_excHandler(UInt *excStack, UInt lr)
{
    Hwi_module->excActive[0] = TRUE;

    /* spin here if no exception handler is plugged */
    while (Hwi_excHandlerFunc == NULL) {
	;
    }

    Hwi_excHandlerFunc(excStack, lr);
}

The ADCBuf config wasn't changed:

/*!
 *  @def    CC1310_LAUNCHXL_ADCBufName
 *  @brief  Enum of ADCBufs
 */
typedef enum CC1310_LAUNCHXL_ADCBufName {
    CC1310_LAUNCHXL_ADCBuf0 = 0,
    CC1310_LAUNCHXL_ADCBufCOUNT
} CC1310_LAUNCHXL_ADCBufName;


/*
 *  ========================== ADCBuf begin =========================================
 */
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(ADCBuf_config, ".const:ADCBuf_config")
#pragma DATA_SECTION(adcBufCC26xxHWAttrs, ".const:adcBufCC26xxHWAttrs")
#pragma DATA_SECTION(ADCBufCC26XX_adcChannelLut, ".const:ADCBufCC26XX_adcChannelLut")
#endif

/* Include drivers */
#include <ti/drivers/ADCBuf.h>
#include <ti/drivers/adcbuf/ADCBufCC26XX.h>

/* ADC objects */
ADCBufCC26XX_Object adcBufCC26xxObjects[CC1310_LAUNCHXL_ADCBufCOUNT];

/*
 *  This table converts a virtual adc channel into a dio and internal analogue input signal.
 *  This table is necessary for the functioning of the adc and adcBuf drivers.
 *  Comment out unused entries.
 *  Dio and internal signal pairs are hardwired. Do not remap them in the table.
 *  The mapping of dio and internal signals is package dependent. Make sure you copied the
 *  correct table from an example board file.
 */
const ADCBufCC26XX_AdcChannelLutEntry ADCBufCC26XX_adcChannelLut[] = {
    {PIN_UNASSIGNED, ADC_COMPB_IN_VDDS},
    {PIN_UNASSIGNED, ADC_COMPB_IN_DCOUPL},
    {PIN_UNASSIGNED, ADC_COMPB_IN_VSS},
    {ANALOG0, ADC_COMPB_IN_AUXIO7},
    {ANALOG1, ADC_COMPB_IN_AUXIO6},
    {ANALOG2, ADC_COMPB_IN_AUXIO5},
    {ANALOG3, ADC_COMPB_IN_AUXIO4},
    {ANALOG4, ADC_COMPB_IN_AUXIO3},
    {ANALOG5, ADC_COMPB_IN_AUXIO2},
    {ANALOG6, ADC_COMPB_IN_AUXIO1},
    {ANALOG7, ADC_COMPB_IN_AUXIO0},
};

const ADCBufCC26XX_HWAttrs adcBufCC26xxHWAttrs[CC1310_LAUNCHXL_ADCBufCOUNT] = {
    {
        .intPriority = ~0,
        .swiPriority = 0,
        .adcChannelLut = ADCBufCC26XX_adcChannelLut,
        .gpTimerUnit = CC1310_LAUNCHXL_GPTIMER0A,
        .gptDMAChannelMask = 1 << UDMA_CHAN_TIMER0_A,
    }
};

const ADCBuf_Config ADCBuf_config[] = {
    {&ADCBufCC26XX_fxnTable, &adcBufCC26xxObjects[0], &adcBufCC26xxHWAttrs[0]},
    {NULL, NULL, NULL},
};
/*
 *  ========================== ADCBuf end =========================================


I was suspicious of the task stack size, but I added 512 to it and the problem remains.

  • More info:

    I put a breakpoint inside ADCBuf_open().

    The wierd part is that I can't see the handle in the debbuger.

    Is it related to the problem?

  • I also tried the example presented in ADCBUFCC26XX.h and it doesn't work either.

    The example is:

    #define SIZE 5
    
        ADCBuf_Handle adcBufHandle;
        ADCBuf_Params adcBufParams;
        ADCBuf_Conversion blockingConversion;
        uint16_t sampleBufferOne[SIZE];
    
        ADCBuf_Params_init(&adcBufParams);
        adcBufHandle = ADCBuf_open(CC1310_LAUNCHXL_ADCBuf0, &adcBufParams); // <=== FAILS HERE!
    
        blockingConversion.arg = NULL;
        blockingConversion.adcChannel = 0;
        blockingConversion.sampleBuffer = sampleBufferOne;
        blockingConversion.sampleBufferTwo = NULL;
        blockingConversion.samplesRequestedCount = SIZE;
    
        if (adcBufHandle) {
        if (!ADCBuf_convert(adcBufHandle, &blockingConversion, 1)) {
        // handle error
        }
        else {
        ADCBuf_close(adcBufHandle);
        }
        }
        else {
        // handle error
        }

    Can someone give me a clue?

  • I found the problem.

    The ADCBuf driver uses that timer: CC1310_LAUNCHXL_GPTIMER0A.

    const ADCBufCC26XX_HWAttrs adcBufCC26xxHWAttrs[CC1310_LAUNCHXL_ADCBufCOUNT] = {
        {
            .intPriority = ~0,
            .swiPriority = 0,
            .adcChannelLut = ADCBufCC26XX_adcChannelLut,
            .gpTimerUnit = CC1310_LAUNCHXL_GPTIMER0A,
            .gptDMAChannelMask = 1 << UDMA_CHAN_TIMER0_A,
        }
    };

    I was using the same timer to generate a PWM output.

    I changed the PWM output to timer CC1310_LAUNCHXL_GPTIMER0B and the ADCBuf started working.

  • The ADCBuf driver is working now.

    But I have a question about the sampling frequency.

    I am configuring the driver as follows:

       ADCBuf_Params_init(&adcBufParams);
       adcBufParams.callbackFxn = adcBufCallback;
       adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_CONTINUOUS;
       adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
       adcBufParams.samplingFrequency = 1;
       adcBuf = ADCBuf_open(CC1310_LAUNCHXL_ADCBuf0, &adcBufParams);
    
        /* Configure the conversion struct */
        continuousConversion.arg = NULL;
        continuousConversion.adcChannel = 3;
        continuousConversion.sampleBuffer = sampleBufferOne;
        continuousConversion.sampleBufferTwo = sampleBufferTwo;
        continuousConversion.samplesRequestedCount = ADCBUFFERSIZE;

    ADCBUFFERSIZE is 10.

    I was expecting to get one sample each second (adcBufParams.samplingFrequency = 1). As my buffer is 10, the complete conversion should end in 10 seconds.
    But the callback is being called approximately each 2 seconds.

    Can someone explain how it should work?