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/MSP432E401Y: Maximum Sampling Rate in One Shot Mode

Part Number: MSP432E401Y


Tool/software: Code Composer Studio

Hello,

I'm trying to set up the ADC on the MSP432E401Y to sample at 1 or 2 MSPS in One Shot Mode. For some reason, the code hangs when I set the sampling frequency to anything above 100 kHz. Is there some internal clock setting that I need to change to allow One Shot Mode to work at the maximum sampling rate? I'm working off of the adcbufcontinuous_MSP_EXP432E401Y_tirtos_ccs. 

Here's my setup:

 /* Call ADC driver init function */
    ADCBuf_init();

    //ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 24);

    /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */
    ADCBuf_Params_init(&adcBufParams);
    //adcBufParams.callbackFxn = adcBufCallback;
    adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_ONE_SHOT;
    //adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
    adcBufParams.returnMode = ADCBuf_RETURN_MODE_BLOCKING;
    //adcBufParams.samplingFrequency = 20E6;
    adcBufParams.samplingFrequency = 100000;
    adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);




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

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

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

        // Normalize and convert to uVolts

        /* Adjust raw ADC values and convert them to microvolts */
        ADCBuf_adjustRawValues(adcBuf, oneshotConversion.sampleBuffer, ADCSAMPLESIZE,
                               Board_ADCBUF0CHANNEL0);
        ADCBuf_convertAdjustedToMicroVolts(adcBuf, Board_ADCBUF0CHANNEL0,
                   oneshotConversion.sampleBuffer, microVoltBuffer, ADCSAMPLESIZE);

Best,

Ajay

  • Ajay,

    When operating in ADCBuf_RECURRENCE_MODE_ONE_SHOT, calls to ADCBuf_convert() will pend on a semaphore until ADCBuf_Conversion.samplesRequestedCount samples are completed or after a duration of ADCBuf_Params.blockingTimeout.

    BR,

    Seong

  • Yeah, I knew that. How do I configure the clock going to the ADC which allows it to sample at the maximum rate (1 or 2 MSPS) for my requested number of samples?

  • Hello,

    I'd really appreciate some help on this!

    Best,

    Ajay Suresh

  • Ajay,

    Blocking timeout is in system clock ticks. This value is only valid when using ADCBuf_RETURN_MODE_BLOCKING. A call to ADCBuf_convert() will block for a duration up to blockingTimeout ticks. The call to ADCBuf_convert() will return prior if the requested number of samples in ADCBuf_Conversion.samplesRequestedCount are completed. The blockingTimeout should be large enough to allow for ADCBuf_Conversion.samplesRequestedCount samples to be collected given the ADCBuf_Params.samplingFrequency.

    BR,

    Seong

  • Hello,

    Thank you for your response. I have tried setting a large blocking timeout, but it doesn't seem to change anything. Even without setting the blockingTimeout, the ADC fills the buffer completely. My issue is that it doesn't seem to sample at a large enough rate to capture the signal. I'm using CCS v9.1.0 and SimpleLink SDK (simplelink_msp432e4_sdk_3_20_00_10). 

    For this snippet of my code, 

     uint32_t w = 0;
    
        /* Call ADC driver init function */
        ADCBuf_init();
    
        //ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 24);
    
        /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */
        ADCBuf_Params_init(&adcBufParams);
        //adcBufParams.callbackFxn = adcBufCallback;
        adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_ONE_SHOT;
        //adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
        adcBufParams.returnMode = ADCBuf_RETURN_MODE_BLOCKING;
        //adcBufParams.samplingFrequency = 20E6;
        adcBufParams.samplingFrequency = 100000;
        adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
    
    
    
    
        if (adcBuf == NULL){
            /* ADCBuf failed to open. */
            while(1);
        }
    
        /* Configure the conversion struct */
        oneshotConversion.arg = NULL;
        oneshotConversion.adcChannel = Board_ADCBUF0CHANNEL0;
        oneshotConversion.sampleBuffer = sampleBufferOne;
        //continuousConversion.sampleBufferTwo = sampleBufferTwo;
        oneshotConversion.samplesRequestedCount = ADCSAMPLESIZE;
    
        while(1) {
            sem_wait(&ADCGet);
            /* Start converting. */
            if (ADCBuf_convert(adcBuf, &oneshotConversion, 1) !=
                ADCBuf_STATUS_SUCCESS) {
                /* Did not start conversion process correctly. */
                while(1);
            }
    
            // Normalize and convert to uVolts
    
            /* Adjust raw ADC values and convert them to microvolts */
            ADCBuf_adjustRawValues(adcBuf, oneshotConversion.sampleBuffer, ADCSAMPLESIZE,
                                   Board_ADCBUF0CHANNEL0);
            ADCBuf_convertAdjustedToMicroVolts(adcBuf, Board_ADCBUF0CHANNEL0,
                       oneshotConversion.sampleBuffer, microVoltBuffer, ADCSAMPLESIZE);

    When I'm running with that sampling frequency (20E6 or anything above 100,000), the code gets stuck here:

    static void dmaErrorFxn(uintptr_t arg)
    {
        int status = uDMAErrorStatusGet();
        uDMAErrorStatusClear();
    
        /* Suppress unused variable warning */
        (void)status;
    
        while (1);
    }

    It only samples without any issues at a rate of 100kHz. I need to sample it at a lot more than that though.

  • Ajay,

    I see now where the issue may be.

    The sample and hold time are critical. What is the maximum source clock frequency used in your code for the ADC? The clock frequency, ADC clock cycles, and the timer duty cycle must be considered to ensure your ADC measurements successfully complete and is ready for the next conversion.

    Although this is from the MSP432P4 SimpleLink Academy, see the Precision ADC lab's Task 8 as it explains this further.

    Also, what is the DMA error status that you get?

    BR,

    Seong

  • Hello,

    I think the DMA Error Status is "1." That's what I saw when the uDMAErrorStatusGet() was called.

    Also, I'm guessing that the maximum clock frequency used for the ADC is 16 MHz. I'm not too sure how to check or change that though. 

    How do I set up all of those parameters in my code?

    Best,

    Ajay

  • Ajay,

    I've consulted the subject matter expert and I've learned that for the E4, unlike the P4 drivers, does not provide a modifiable configuration for the timer duty cycle. Apologies for the confusion.

    The sampling frequency can be set using the samplingFrequency parameter, which you are doing correctly. The ADC clock cycles can be set using the samplingDuration value in the extended parameters. To do this, add the following code:

    ADCBufMSP432E4_ParamsExtension customParams;
    
    customParams.sampleDuration = [choices for this variable are in /source/ti/drivers/adcbuf/ADCBufMSP432E4.h];
    
    adcBufParams.custom = &customParams;


    Also, you have “oneshotConversion.sampleBufferTwo = sampleBufferTwo” commented out. Have you tried uncommenting this? Did the problem still persist?

    BR,

    Seong

  • Hello,

    Uncommenting the “oneshotConversion.sampleBufferTwo = sampleBufferTwo” worked! I'm able to sample at 1 MSPS now. Thanks! 

    Best,

    Ajay

  • Ajay,

    Glad you got it working! I'll be closing this thread. Please start a new for any other queries.

    BR,

    Seong