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.

CC2640R2F: multi ADC channel

Part Number: CC2640R2F
Other Parts Discussed in Thread: CC2640,

Hi, I am little confused about ADCbuf.

What is ADCBuf peropheral and how it works?

If I want to convert ADC1, should I change the code like this?

ADCBuf_Handle adcBuf;
ADCBuf_Params adcBufParams;
ADCBuf_Conversion continuousConversion,continuousConversion2;

/* Call driver init functions */
ADCBuf_init();

/* 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(Board_ADCBUF0, &adcBufParams);

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

if (adcBuf == NULL){
/* ADCBuf failed to open. */
while(1);
}

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

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

/* Start converting. */
if (ADCBuf_convert(adcBuf, &continuousConversion2, 1) !=
ADCBuf_STATUS_SUCCESS) {
/* Did not start conversion process correctly. */
while(1);
}

I was little confused because Board_ADCBUF0 is declared like below. the comment says Enum of ADCs. So this means that CC2640R2_LAUNCHXL_ADCBUF0 is named as ADC0?

So if I want to convert ADC1, do I have to add CC2640R2_LAUNCHXL_ADCBUF1 here?

/*!
* @def CC2640R2_LAUNCHXL_ADCBufName
* @brief Enum of ADCs
*/
typedef enum CC2640R2_LAUNCHXL_ADCBufName {
CC2640R2_LAUNCHXL_ADCBUF0 = 0,

CC2640R2_LAUNCHXL_ADCBUFCOUNT
} CC2640R2_LAUNCHXL_ADCBufName;

  • Hi Hynag,

    I recommend reading up on the documentation for the ADCBuf driver, as well as checking out the adcbufcontinuous example in the CC2640R2 SDK. That should give you a good example on how the ADCBuf driver works and how to use it.

    ADCBuf driver: dev.ti.com/.../_a_d_c_buf_8h.html
  • Yes I did it all but it did not work.
    IfI understand correctly, I set up ADCBuf peripheral one more and then convert ADC0 from Board_ADCBUF0CHANNEL0 of the first ADCBuf peripheral and convert ADC1 from Board_ADCBUF0CHANNEL1 from the second ADCBUF.

    I already looked up all example but all of them convert only one channel. I have trouble in converting multi channel.
    Since cc2640 does not support simultaneous multiple channels, I have no idea what to do.

    Could you give me some example code for multichannel using adcbuf?

  • So the CC2640R2F has one ADC with 8 channels. This is true for both the ADC driver and the ADCBuf driver. It's just that the naming is slightly different for the two drivers.

    To start a continuous reading of multiple channels simply start two conversions with the opened ADCBuf handle on two different ADC channels. Note that you have to supply two different buffers for both conversions. It seems like in the code snippet you provided you are using the same buffers on both conversion, which of course won't work.
  • Is this code like what you suggested? but only ADC0 is converted.

    ADCBuf_Handle adcBuf;
    ADCBuf_Params adcBufParams;
    ADCBuf_Conversion continuousConversion,continuousConversion2;

    /* Call driver init functions */
    ADCBuf_init();

    /* 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(Board_ADCBUF0, &adcBufParams);

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

    if (adcBuf == NULL){
    /* ADCBuf failed to open. */
    while(1);
    }

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

    /* Configure the conversion struct */
    continuousConversion2.arg = NULL;
    continuousConversion2.adcChannel = Board_ADCBUF0CHANNEL1;
    continuousConversion2.sampleBuffer = sampleBufferOne2;
    continuousConversion2.sampleBufferTwo = sampleBufferTwo2;
    continuousConversion2.samplesRequestedCount = ADCBUFFERSIZE;

    /* Start converting. */
    if (ADCBuf_convert(adcBuf, &continuousConversion2, 1) !=
    ADCBuf_STATUS_SUCCESS) {
    /* Did not start conversion process correctly. */
    while(1);
    }
  • Hi Hynag,

    The ADCBuf driver does not support time-multiplexing. This means you can only have one active conversion at a given time. If you abort the CHANNEL0 conversion, are you able to get the CHANNEL1 to work?
  • Yes Channel 1 is working. is it because  adcbuf keeps sampling til buffer is filled? The reason I want to use adcbuf is that I want to make the other thread work while adc sampling and when adc sampling is done, come back to adc thread and start convert. When I see adcbuf, there is while loop with comment that forethread runs til buffer is filled.

  • ADCBuf will in any mode fill up the buffer with the number of conversions requested. In your case you set it to read continuously between callbacks which means you can not perform readings on another channels before you stop the first reading.

    Is your ADCBuf implementation running in it's own thread? If that case you should be able to use blocking mode as it would yield to other threads while being blocked. In that case, you could do single conversions (ADCBuf_RECURRENCE_MODE_ONE_SHOT ) and perform channel 0 and 1 conversions in series with each other.
  • Thank you for your kind answer.
    I will try this and ask again later.
    And could you tell me what is recurrence mode exactly and why it can't use when block mode is used?
  • Hi,

    Recurrence mode means that it will continue to sample additional buffers even after the callback is received. For example if you need continuous sampling you can achieve this by using this mode. For example, you would get a callback when the first buffer is full, another when the second buffer is full and then again when the third(actually the same as the first buffer) buffer is full and so on. Basically, it will ping-pong between the two buffers and keep sampling data until you tell it to stop.

    This also means you can not use it in blocking mode as it would mean you never return unless you tell the driver to stop and you would not be able to get the sampled data out as the it never returns.
  • Thank you for your help. Now I can convert all channels.