Hi team,
When using EasyLink_transmit CcaAsync to send a message, if another device at the same frequency is sending the message to interfere with it, when the callback function of EasyLink_transmit CcaAsync feedback the error code of EasyLink_Status_Busy_Error, it basically cannot enter into low power consumption, which is kept at around 1.23 mA, please see the figure below:
This issue no longer shows when turning off the random number generator: (the red line means when remove the line in red box, the problem no longer remain)
And the testing code are as follows:
/* 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);
}
Could you help check this case? Thanks.
Best Regards,
Cherry