TI中文支持网
TI专业的中文技术问题搜集分享网站

CC1312R: 使用CCA发送时,检测到空中处于BUSY状态时,因为TNG导致无法进入低功耗,长期保持1mA左右

Part Number:CC1312R

在使用EasyLink_transmitCcaAsync发送报文时,如果使用一个同频率的其它设备一直发送报文干扰他,在EasyLink_transmitCcaAsync的回调函数反馈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_SIZE1024
#define RFEASYLINKRX_TASK_PRIORITY2

// 无线基础频率433.1592MHZ
#define RF_FREQ_BASE433159200UL
// 无线信道频宽50KHZ
#define RF_FREQ_BANDWIDTH50000
// 最大支持20个信道,每个设备占用2个信道
#define MAX_RF_CHANNEL20

/* 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_ASYNCEasyLink_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 valuesEasyLink_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_ASYNCmemset(&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 A9memcpy(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);

#elserxPacket.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);
}

希望得到解决方案

Cherry Zhou:

您好,我们已收到您的问题并升级到英文论坛,如有答复将尽快回复您。谢谢!

,

user5959626:

感谢!

,

Cherry Zhou:

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

,

user5959626:

在执行EasyLink_transmitCcaAsync出现EasyLink_Status_Busy_Error之前是可以进入待机状态的。在发生EasyLink_Status_Busy_Error状态时,看起来TNG模块没有释放,所以导致无法进入低功耗,我该怎样操作呢?我看到官方的例子也是这样使用的,是不是有什么配置我有遗漏?

,

Cherry Zhou:

您好,使用后需要关闭驱动程序。工程师对easylink不太熟悉,请问下您为什么在这里用TRNG?

以及根据以上图片,您是可以用rand的,您有没有尝试过以上图片中的方法?

,

user5959626:

刚刚按照你描述的方法做了测试,也可以解决我的问题,感谢~!

赞(0)
未经允许不得转载:TI中文支持网 » CC1312R: 使用CCA发送时,检测到空中处于BUSY状态时,因为TNG导致无法进入低功耗,长期保持1mA左右
分享到: 更多 (0)