大家好、
当使用 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(¶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 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); }
您可以帮助检查此案例吗? 谢谢。
此致、
樱桃