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.

[参考译文] CC1312R:无法进入低功耗状态

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

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1059953/cc1312r-cannot-enter-low-power-consumption

器件型号:CC1312R

大家好、

当使用 EasyLink_transmit Cca异 步发送消息时、如果同一频率的另一个器件发送消息以干扰消息、当 EasyLink_transmit Cca异 步的回调函数反馈 EasyLink_Status_Busy_Error 的错误代码时 、它基本上无法进入低功耗状态、 保持在1.23mA 左右、请参见下图:

关闭随机数生成器时不再显示此问题:(红线表示删除红色框中的行时、问题不再存在)

测试代码如下:

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/Assert.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Clock.h>

#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART.h>

/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>

#include <stdio.h>

#include <ti/drivers/TRNG.h>
#include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>

/* Board Header files */
#include "ti_drivers_config.h"

/* EasyLink API Header files */
#include "easylink/EasyLink.h"

/***** Defines *****/

/* Undefine to remove async mode */
#define RFEASYLINKRX_ASYNC

#define RFEASYLINKRX_TASK_STACK_SIZE    1024
#define RFEASYLINKRX_TASK_PRIORITY      2

// Wireless base frequency 433.1592MHZ
#define RF_FREQ_BASE        433159200UL
// The wireless channel bandwidth 50KHZ
#define RF_FREQ_BANDWIDTH   50000
// Supports up to 20 channels, each occupying 2 channels 
#define MAX_RF_CHANNEL      20

/* Pin driver handle */
static PIN_Handle ledPinHandle;
static PIN_State ledPinState;

/*
 * Application LED pin configuration table:
 *   - All LEDs board LEDs are off.
 */
//PIN_Config pinTable[] = {
//    CONFIG_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
//    CONFIG_PIN_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
//    PIN_TERMINATE
//};

/***** Variable declarations *****/
static Task_Params rxTaskParams;
Task_Struct rxTask;    /* not static so you can see in ROV */
static uint8_t rxTaskStack[RFEASYLINKRX_TASK_STACK_SIZE];

/* The RX Output struct contains statistics about the RX operation of the radio */
PIN_Handle pinHandle;

#ifdef RFEASYLINKRX_ASYNC
static Semaphore_Handle rxDoneSem;
#endif

static EasyLink_RxPacket rxPkg;

static uint32_t rf_freq = 0;
static EasyLink_Status g_rx_status = 0;
static uint8_t g_tx_status = 0;

/***** Function definitions *****/
#ifdef RFEASYLINKRX_ASYNC
void echoTxDoneCb(EasyLink_Status status)
{
    if (status == EasyLink_Status_Success)
    {
//        /* Toggle GLED to indicate TX */
//        PIN_setOutputValue(pinHandle, CONFIG_PIN_GLED,!PIN_getOutputValue(CONFIG_PIN_GLED));
//        /* Turn RLED off, in case there was a prior error */
//        PIN_setOutputValue(pinHandle, CONFIG_PIN_RLED, 0);

        g_tx_status = 1;
    }
    else if (status == EasyLink_Status_Busy_Error)
    {
        g_tx_status = 2;
    }
    else
    {
//        /* Set both GLED and RLED to indicate error */
//        PIN_setOutputValue(pinHandle, CONFIG_PIN_GLED, 1);
//        PIN_setOutputValue(pinHandle, CONFIG_PIN_RLED, 1);

        g_tx_status = 3;
    }

    Semaphore_post(rxDoneSem);
}

void rxDoneCb(EasyLink_RxPacket * rxPacket, EasyLink_Status status)
{
    g_rx_status = status;

    if (status == EasyLink_Status_Success)
    {
        memcpy(&rxPkg, rxPacket, sizeof(EasyLink_RxPacket));
        /* Toggle RLED to indicate RX */
//        PIN_setOutputValue(pinHandle, CONFIG_PIN_RLED,!PIN_getOutputValue(CONFIG_PIN_RLED));


    }
    else if(status == EasyLink_Status_Aborted)
    {
        /* Toggle GLED to indicate command aborted */
//        PIN_setOutputValue(pinHandle, CONFIG_PIN_GLED,!PIN_getOutputValue(CONFIG_PIN_GLED));
    }
    else
    {
        /* Toggle GLED and RLED to indicate error */
//        PIN_setOutputValue(pinHandle, CONFIG_PIN_GLED,!PIN_getOutputValue(CONFIG_PIN_GLED));
//        PIN_setOutputValue(pinHandle, CONFIG_PIN_RLED,!PIN_getOutputValue(CONFIG_PIN_RLED));
    }

    Semaphore_post(rxDoneSem);
}
#endif

unsigned char check_sum(unsigned char *dat, unsigned char len)
{
    unsigned char  i   = 0;
    unsigned short sum = 0;

    for (i=0; i<len; ++i)
    {
        sum += dat[i];
    }

    return (unsigned char)sum;
}

int rf_set_frequency(uint8_t channel_rx)
{
    if (channel_rx > 20)
    {
        return -1;
    }

    rf_freq = (uint32_t)RF_FREQ_BASE + (uint32_t)channel_rx*(uint32_t)RF_FREQ_BANDWIDTH;

    return 0;
}

void drv_low_power_io_init()
{
    GPIO_setConfig(PERIPHERAL_POWER, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    GPIO_setConfig(BMA400_SPI_MOSI, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(BMA400_SPI_SCK, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(BMA400_SPI_MISO, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(BMA400_SPI_CS, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

   GPIO_setConfig(BMA400_PWR, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

   GPIO_setConfig(BMA400_INT1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
   GPIO_setConfig(BMA400_INT2, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    GPIO_setConfig(LED_RED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
    GPIO_setConfig(LED_GREEN, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);

    GPIO_setConfig(FLASH_CS, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(FLASH_SCK, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(FLASH_MOSI, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(FLASH_MISO, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    GPIO_setConfig(ADC_PWR, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    GPIO_write(PERIPHERAL_POWER, 0);

    GPIO_write(BMA400_SPI_MOSI, 0);
    GPIO_write(BMA400_SPI_SCK, 0);
    GPIO_write(BMA400_SPI_MISO, 0);
    GPIO_write(BMA400_SPI_CS, 0);

   GPIO_write(BMA400_PWR, 0);
   GPIO_write(BMA400_INT1, 0);
   GPIO_write(BMA400_INT2, 0);

    GPIO_write(LED_RED, 1);
    GPIO_write(LED_GREEN, 1);

    GPIO_write(FLASH_CS, 0);
    GPIO_write(FLASH_SCK, 0);
    GPIO_write(FLASH_MOSI, 0);
    GPIO_write(FLASH_MISO, 0);

    GPIO_write(ADC_PWR, 0);
}

void close_peripheral(void)
{
    GPIO_setConfig(PERIPHERAL_POWER, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_write(PERIPHERAL_POWER, 0);

    GPIO_setConfig(ADC_PWR, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_write(ADC_PWR, 0);

    GPIO_setConfig(LED_GREEN, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
    GPIO_write(LED_GREEN, 1);

    GPIO_setConfig(LED_RED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
    GPIO_write(LED_RED, 1);

    GPIO_setConfig(FLASH_CS,   GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(FLASH_SCK,  GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(FLASH_MOSI, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(FLASH_MISO, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    GPIO_write(FLASH_CS, 0);
    GPIO_write(FLASH_SCK, 0);
    GPIO_write(FLASH_MOSI, 0);
    GPIO_write(FLASH_MISO, 0);

    drv_low_power_io_init();
}

#define KEY_LENGTH_BYTES                    (4U)
#define MAX_TRNG_RETRIES                    (2U) // Max attempts to generate a random number

/* TRNG driver handle */
static TRNG_Handle trngHandle;

/* Crypto Key driver variables */
static CryptoKey entropyKey;
uint8_t entropyBuffer[KEY_LENGTH_BYTES];

UART_Handle uart;

int drv_random_init(void)
{
    /* Initialize the TRNG driver and a blank crypto key */
    TRNG_init();
    TRNG_Params trngParams;
    TRNG_Params_init(&trngParams);
    trngParams.returnBehavior = TRNG_RETURN_BEHAVIOR_POLLING;
    trngHandle = TRNG_open(CONFIG_TRNG_EASYLINK, &trngParams);
    if(NULL == trngHandle)
    {
        UART_write(uart, "Failed to init TRNG driver\r\n", strlen("Failed to init TRNG driver\r\n"));
//        System_abort("Failed to init TRNG driver");
        return -1;
    }
    int_fast16_t result = CryptoKeyPlaintext_initBlankKey(&entropyKey, entropyBuffer, KEY_LENGTH_BYTES);
    if(CryptoKey_STATUS_SUCCESS != result)
    {
        UART_write(uart, "Unable to create a blank crypto key\r\n", strlen("Unable to create a blank crypto key\r\n"));
//        System_abort("Unable to create a blank crypto key");
        return -2;
    }

    return 0;
}

uint32_t drv_random_get( void )
{
    int_fast16_t result = TRNG_STATUS_ERROR;
    uint8_t breakCounter = MAX_TRNG_RETRIES;
    char buf[128] = {0};

    do
    {
        if(0U == breakCounter--)
        {
            UART_write(uart, "gen random numer err\r\n", strlen("gen random numer err\r\n"));
//            System_abort("Unable to generate a random value");
        }
        else
        {
            result = TRNG_generateEntropy(trngHandle, &entropyKey);
        }
    }while(TRNG_STATUS_SUCCESS != result);

    sprintf(buf, "random gen result:%d\r\n", result);
    UART_write(uart, buf, strlen(buf));

    return(*((uint32_t *)entropyBuffer));
}

static void rfEasyLinkRxFnx(UArg arg0, UArg arg1)
{
    EasyLink_Status statusFreq;

    UART_Params uartParams;
    int i = 0;
    char buf[128] = {0};
    uint8_t temp[36] = {0};
    uint32_t tx_count = 0, rx_count = 0;
    uint32_t channel = 0;

//#ifndef RFEASYLINKRX_ASYNC
    EasyLink_TxPacket txPacket = {0};
//#endif

//    GPIO_setConfig(RFID_POWER, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
//    GPIO_write(RFID_POWER, 0);

#ifdef RFEASYLINKRX_ASYNC
    /* Create a semaphore for Async*/
    Semaphore_Params params;
    Error_Block eb;

    /* Init params */
    Semaphore_Params_init(&params);
    Error_init(&eb);

    /* Create semaphore instance */
    rxDoneSem = Semaphore_create(0, &params, &eb);
    if(rxDoneSem == NULL)
    {
        System_abort("Semaphore creation failed");
    }

#endif //RFEASYLINKRX_ASYNC

    // Initialize the EasyLink parameters to their default values
    EasyLink_Params easyLink_params;

    drv_random_init();

    EasyLink_Params_init(&easyLink_params);

    easyLink_params.pGrnFxn = (EasyLink_GetRandomNumber)drv_random_get;

    /*
     * Initialize EasyLink with the settings found in ti_easylink_config.h
     * Modify EASYLINK_PARAM_CONFIG in ti_easylink_config.h to change the default
     * PHY
     */
    if(EasyLink_init(&easyLink_params) != EasyLink_Status_Success)
    {
        System_abort("EasyLink_init failed");
    }

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;
//    uartParams.dataLength = UART_LEN_8;
//    uartParams.stopBits = UART_STOP_ONE;
//    uartParams.parityType = UART_PAR_NONE;
    uart = UART_open(CONFIG_UART_0, &uartParams);

    if (uart == NULL) {
        /* UART_open() failed */
        while (1);
    }

    /*
     * If you wish to use a frequency other than the default, use
     * the following API:
     * EasyLink_setFrequency(868000000);
     */

    channel = 4;

    rf_set_frequency(channel);
    statusFreq = EasyLink_setFrequency(rf_freq);

    Task_sleep(1000 * 1000 / Clock_tickPeriod);

    memset(buf, 0, sizeof(buf));
    sprintf(buf, "SnifferTool,Channel:%lu, SetFre:%lu, GetFre:%lu\r\n", channel, EasyLink_getFrequency(), rf_freq);
    UART_write(uart, buf, strlen(buf));

    drv_low_power_io_init();

//    while (1)
//    {
////        task_comm_network_register(&rcv_flag, &timeout);
//
//        Task_sleep(36000 * 1000 / Clock_tickPeriod); // 延时200ms
//    }

    while(1) {
        Task_sleep(3000 * 1000 / Clock_tickPeriod);
#ifdef RFEASYLINKRX_ASYNC
        memset(&txPacket, 0, sizeof(txPacket));
        // F5 70 0A 00 12 0A 00 01 00 91 00 21 98 6F 00 0A 00 3C 00 1E 00 00 00 A9
        memcpy(txPacket.payload, "\xF5\x70\x0A\x00\x12\x0A\x00\x01\x00\x91\x00\x21\x98\x6F\x00\x0A\x00\x3C\x00\x1E\x00\x00\x00\xA9", 24);
        txPacket.len = 24;

//        txPacket.payload[0] = channel;

        memset(buf, 0, sizeof(buf));
        sprintf(buf, "[%lu]Send:", tx_count);
        UART_write(uart, buf, strlen(buf));
        for (i=0; i<txPacket.len; ++i)
        {
            sprintf(temp, "%02X ", txPacket.payload[i]);
            UART_write(uart, temp, strlen(temp));
        }
        UART_write(uart, "\r\n", 2);

//        statusFreq = EasyLink_setFrequency(433209200);
        rf_set_frequency(channel);
        statusFreq = EasyLink_setFrequency(rf_freq);

//        EasyLink_transmitAsync(&txPacket, echoTxDoneCb);
        EasyLink_transmitCcaAsync(&txPacket, echoTxDoneCb);

        /* Wait for Tx to complete. A Successful TX will cause the echoTxDoneCb
         * to be called and the echoDoneSem to be released, so we must
         * consume the echoDoneSem
         */
        Semaphore_pend(rxDoneSem, BIOS_WAIT_FOREVER);

        tx_count++;

        memset(buf, 0, sizeof(buf));
        sprintf(buf, ">>>>>Send result:%d", g_tx_status);
        UART_write(uart, buf, strlen(buf));
        if (2 == g_tx_status)
        {
//            Task_sleep(50 * 1000 / Clock_tickPeriod);
            continue;
        }

//        memset(&rxPkg, 0, sizeof(EasyLink_RxPacket));
//
////        statusFreq = EasyLink_setFrequency(433159200);
//        rf_set_frequency(channel+1);
//        statusFreq = EasyLink_setFrequency(rf_freq);
//
//        EasyLink_setCtrl(EasyLink_Ctrl_AsyncRx_TimeOut, EasyLink_ms_To_RadioTime(500));
//        EasyLink_receiveAsync(rxDoneCb, 0);
//
//        /* Wait 300ms for Rx */
//        if(Semaphore_pend(rxDoneSem, (1000*1000 / Clock_tickPeriod)) == FALSE)
//        {
//            /* RX timed out abort */
//            if(EasyLink_abort() == EasyLink_Status_Success)
//            {
//               /* Wait for the abort */
//               Semaphore_pend(rxDoneSem, BIOS_WAIT_FOREVER);
//            }
//
//            continue;
//        }
//
//        if (EasyLink_Status_Success != g_rx_status)
//        {
//            uint8_t temp[16] = {0};
//
//            memset(temp, 0, sizeof(temp));
//            sprintf(temp, "rx err:%d", g_rx_status);
//            UART_write(uart, temp, strlen(temp));
//        }
//
//        if (channel == rxPkg.payload[0] && rxPkg.len==txPacket.len)
//        {
//            rx_count++;
//        }
//
//        //if (rxPkg.payload[0]==0xF5 && rxPkg.payload[1]==0x70 && memcmp(rxPkg.payload+8, "\x00\x00\x00\x00", 4)!=0)
//        {
//            uint16_t i = 0;
//            uint8_t temp[16] = {0};
//
//            memset(buf, 0, sizeof(buf));
//            sprintf(buf, "[%lu]Recv:", rx_count);
//            UART_write(uart, buf, strlen(buf));
//
//            for (i=0; i<rxPkg.len; ++i)
//            {
//                sprintf(temp, "%02X ", rxPkg.payload[i]);
//                UART_write(uart, temp, strlen(temp));
//            }
//
//            UART_write(uart, "\r\n", 2);
//
//            sprintf(temp, "Rssi:%d\r\n", rxPkg.rssi);
//            UART_write(uart, temp, strlen(temp));
//        }

//        drv_low_power_io_init();

        Task_sleep(2000 * 1000 / Clock_tickPeriod);

#else
        rxPacket.absTime = 0;
        EasyLink_Status result = EasyLink_receive(&rxPacket);

        if (result == EasyLink_Status_Success)
        {
            /* Toggle RLED to indicate RX */
            PIN_setOutputValue(pinHandle, CONFIG_PIN_RLED,!PIN_getOutputValue(CONFIG_PIN_RLED));
        }
        else
        {
            /* Toggle GLED and RLED to indicate error */
            PIN_setOutputValue(pinHandle, CONFIG_PIN_GLED,!PIN_getOutputValue(CONFIG_PIN_GLED));
            PIN_setOutputValue(pinHandle, CONFIG_PIN_RLED,!PIN_getOutputValue(CONFIG_PIN_RLED));
        }

        //statusFreq = EasyLink_setFrequency(433150000);

        EasyLink_Status result = EasyLink_transmit(&rxPacket);

        if (result == EasyLink_Status_Success)
        {
            /* Toggle GLED to indicate TX */
            PIN_setOutputValue(pinHandle, CONFIG_PIN_GLED,!PIN_getOutputValue(CONFIG_PIN_GLED));
            /* Turn RLED off, in case there was a prior error */
            PIN_setOutputValue(pinHandle, CONFIG_PIN_RLED, 0);
        }
        else
        {
            /* Set both GLED and RLED to indicate error */
            PIN_setOutputValue(pinHandle, CONFIG_PIN_GLED, 1);
            PIN_setOutputValue(pinHandle, CONFIG_PIN_RLED, 1);
        }

        //statusFreq = EasyLink_setFrequency(433050000);

#endif //RX_ASYNC
    }
}

void rxTask_init(PIN_Handle ledPinHandle) {
    pinHandle = ledPinHandle;

    Task_Params_init(&rxTaskParams);
    rxTaskParams.stackSize = RFEASYLINKRX_TASK_STACK_SIZE;
    rxTaskParams.priority = RFEASYLINKRX_TASK_PRIORITY;
    rxTaskParams.stack = &rxTaskStack;
    rxTaskParams.arg0 = (UInt)1000000;

    Task_construct(&rxTask, rfEasyLinkRxFnx, &rxTaskParams, NULL);
}

/*
 *  ======== main ========
 */
int main(void)
{
    /* Call driver init functions */
    Board_initGeneral();

    /* Open LED pins */
//    ledPinHandle = PIN_open(&ledPinState, pinTable);
//    Assert_isTrue(ledPinHandle != NULL, NULL);

    /* Clear LED pins */
//    PIN_setOutputValue(ledPinHandle, CONFIG_PIN_GLED, 0);
//    PIN_setOutputValue(ledPinHandle, CONFIG_PIN_RLED, 0);

    GPIO_init();
    UART_init();

    rxTask_init(ledPinHandle);

    /* Start BIOS */
    BIOS_start();

    return (0);
}

您可以帮助检查此案例吗? 谢谢。

此致、

樱桃

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

    当您执行 drv_random_init 时、您会调用 TRNG_open。 打开驱动程序将阻止器件进入待机状态。  

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

    您好!

    感谢您的支持!

    当执行 EasyLink_Transmit Cca异 步时、它可以在 EasyLink_Status_Busy_Error 发生之前进入待机状态。 当出现 EasyLink_Status_Busy_Error 时、TNG 模块不会被释放、因此无法进入低功耗状态。

    那么、配置是否有任何问题或其他问题?

    谢谢、此致、

    樱桃

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

    您必须在使用后关闭驱动程序。  

    对 EasyLink 不太熟悉、您为什么在此处使用 TRNG?  

    这种情况:

    指示您可以使用 rand。 您是否尝试过此操作?