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.

[参考译文] CC1352R:当在单次模式下运行时、如果 ADCBuf 驱动程序在两次使用之间断开和闭合、则会在几个周期后失败。

Guru**** 2345050 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1491825/cc1352r-adcbuf-driver-when-run-in-single-shot-mode-opened-and-closed-between-uses-fails-after-a-few-cycles

器件型号:CC1352R

工具与软件:

我将把一个设计从 SDK 6.10.0.29移植到8.30.1.01。 ADCBuf 驱动程序出现问题。

我将在单次模式下使用它、以10 kHz 的频率每20秒左右采集400个样本。 这在 SDK 6.10领域非常有用、但现在对 ADCBuf_convert 的调用在经过一到两次调用后失败、返回代码变为-1。

为了便于演示、我更改了 adcbuffcontinuous 示例、以显示相同的行为。

为了进行演示、只需加载 adcbuContinuous 示例、并将 adcBufContinuousSampling.c 中的代码替换为以下代码。

您将注意到、在几个周期内、行168处的 ADCBuf_convert 调用将起作用、但它最终将在行171处进行捕获。 我无法看出为什么会发生这种情况。 有什么想法?

/*
 * Copyright (c) 2015-2024, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 *  ======== adcBufContinuousSampling.c ========
 */
#include <stdint.h>
#include <stdio.h>
#include <mqueue.h>

/* Driver Header files */
#include <ti/drivers/ADCBuf.h>

/* Display Header files */
#include <ti/display/Display.h>

/* Driver configuration */
#include "ti_drivers_config.h"

#define ADCSAMPLESIZE              (400)
#define MAX_QUEUED_ADC_CONVERSIONS (4)
#define QUEUED_ADC_MESSAGE_SIZE    (sizeof(uint32_t) * ADCSAMPLESIZE)

uint16_t sampleBufferOne[ADCSAMPLESIZE];
uint16_t sampleBufferTwo[ADCSAMPLESIZE];
uint32_t microVoltBuffer[ADCSAMPLESIZE];
uint32_t outputBuffer[ADCSAMPLESIZE];
uint32_t buffersCompletedCounter = 0;

/* Display Driver Handle */
Display_Handle displayHandle;

/* Used to pass ADC data between callback and main task */
static mqd_t queueReceive;
static mqd_t queueSend;

/*
 * This function is called whenever an ADC buffer is full.
 * The content of the buffer is then converted into human-readable format and
 * sent to the main thread.
 */
void adcBufCallback(ADCBuf_Handle handle,
                    ADCBuf_Conversion *conversion,
                    void *completedADCBuffer,
                    uint32_t completedChannel,
                    int_fast16_t status)
{
    /* Adjust raw ADC values and convert them to microvolts */
    ADCBuf_adjustRawValues(handle, completedADCBuffer, ADCSAMPLESIZE, completedChannel);
    ADCBuf_convertAdjustedToMicroVolts(handle, completedChannel, completedADCBuffer, microVoltBuffer, ADCSAMPLESIZE);

    /* Send ADC data to main thread using message queue */
    mq_send(queueSend, (char *)microVoltBuffer, QUEUED_ADC_MESSAGE_SIZE, 0);
}

/*
 *  ======== mainThread ========
 */
void *mainThread(void *arg0)
{
    Display_Params displayParams;
    ADCBuf_Handle adcBuf;
    ADCBuf_Params adcBufParams;
    ADCBuf_Conversion continuousConversion;
    ADCBuf_Conversion Conversion;
    struct mq_attr attr;
    uint32_t average;
    uint_fast16_t i = 0;

    /* Create RTOS Queue */
    attr.mq_flags   = 0;
    attr.mq_maxmsg  = MAX_QUEUED_ADC_CONVERSIONS;
    attr.mq_msgsize = QUEUED_ADC_MESSAGE_SIZE;
    attr.mq_curmsgs = 0;

    queueReceive = mq_open("ADCBuf", O_RDWR | O_CREAT, 0664, &attr);
    queueSend    = mq_open("ADCBuf", O_RDWR | O_CREAT | O_NONBLOCK, 0664, &attr);
    if ((queueReceive == (mqd_t)-1) || (queueSend == (mqd_t)-1))
    {
        /* Failed to open message queue */
        while (1) {}
    }

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

    /* Configure & open Display driver */
    Display_Params_init(&displayParams);
    displayParams.lineClearMode = DISPLAY_CLEAR_BOTH;
    displayHandle               = Display_open(Display_Type_UART, &displayParams);
    if (displayHandle == NULL)
    {
        Display_printf(displayHandle, 0, 0, "Error creating displayHandle\n");
        while (1) {}
    }

    Display_printf(displayHandle, 0, 0, "Starting the ADCBufContinuous example");

    // /* 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 = 1000;
    // adcBuf                         = ADCBuf_open(CONFIG_ADCBUF_0, &adcBufParams);

    // /* Configure the conversion struct */
    // continuousConversion.arg                   = NULL;
    // continuousConversion.adcChannel            = CONFIG_ADCBUF_0_CHANNEL_0;
    // continuousConversion.sampleBuffer          = sampleBufferOne;
    // continuousConversion.sampleBufferTwo       = sampleBufferTwo;
    // continuousConversion.samplesRequestedCount = ADCSAMPLESIZE;
   while(1)
   {
    /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_ONE_SHOT */
    ADCBuf_Params_init(&adcBufParams);
    adcBufParams.callbackFxn       = NULL;
    adcBufParams.recurrenceMode    = ADCBuf_RECURRENCE_MODE_ONE_SHOT;
    adcBufParams.returnMode        = ADCBuf_RETURN_MODE_BLOCKING;
    adcBufParams.samplingFrequency = 10000;

    adcBuf                         = ADCBuf_open(CONFIG_ADCBUF_0, &adcBufParams);

    /* Configure the conversion struct */
    Conversion.arg                   = NULL;
    Conversion.adcChannel            = CONFIG_ADCBUF_0_CHANNEL_0;
    Conversion.sampleBuffer          = sampleBufferOne;
    Conversion.sampleBufferTwo       = NULL;
    Conversion.samplesRequestedCount = ADCSAMPLESIZE;


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

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

        /* Adjust raw ADC values and convert them to microvolts */
        ADCBuf_adjustRawValues(adcBuf, sampleBufferOne, ADCSAMPLESIZE, CONFIG_ADCBUF_0_CHANNEL_0);
        ADCBuf_convertAdjustedToMicroVolts(adcBuf, CONFIG_ADCBUF_0_CHANNEL_0, sampleBufferOne, (uint32_t*)outputBuffer, ADCSAMPLESIZE);
        ADCBuf_close(adcBuf);
   }
    /*
     * Wait for the message queue to receive ADC data from the callback
     * function. When data is received, calculate the average and print to UART
     */
    while (1)
    {
        if (mq_receive(queueReceive, (char *)outputBuffer, QUEUED_ADC_MESSAGE_SIZE, NULL) == -1)
        {
            Display_printf(displayHandle, 0, 0, "Error receiving ADC message");
            while (1) {}
        }

        Display_printf(displayHandle, 0, 0, "Buffer %u finished:", (unsigned int)buffersCompletedCounter++);

        /* Calculate average ADC data value in uV */
        average = 0;
        for (i = 0; i < ADCSAMPLESIZE; i++)
        {
            average += outputBuffer[i];
        }
        average = average / ADCSAMPLESIZE;

        /* Print average ADCBuf value */
        Display_printf(displayHandle, 0, 0, "  Average: %u uV", average);
    }
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Joshua:

    我将尝试这一个,期待明天听到我的声音。 但目前、我在两个驱动程序版本之间看到的唯一变化是代码格式。

    此致、

    Arthur

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我注意到、在很多地方、信标机制被更改为新的信标语法。 我想知道那里有什么东西弄乱了吗? 也许信标未被正确析构/重新创建?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这确实是可能的。 我还验证了它同时发生在 tirtos7和 FreeRTOS 上。 我会继续寻找。

    此致、

    Arthur

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Joshua、

    好消息! 我已经看了我们的驱动程序测试套件,并添加 adcBufParams.blockingTimeout =~0;到你的 adcBufParams 将使你的 exemple 工作.

    这是可能的解释。 请注意、我们有一个有关该行为的内部 TT、因此这可能会在将来得到解决。



    此致、

    Arthur