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(¶ms);Error_init(&eb);/* Create semaphore instance */rxDoneSem = Semaphore_create(0, ¶ms, &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:
刚刚按照你描述的方法做了测试,也可以解决我的问题,感谢~!