Hi,
I've got some problems making EasyLink work for my application. What I am basically trying is to initialize EasyLink and enter (and stay in) the asynchronous receive mode. Only when I am transmitting a packet (which is triggered by a timer) I want to disable the receive mode, send my packet and upon completion re-enter the asynchronous receive mode again.
The problem is that after calling the EasyLink_Abort()-function for aborting the receive command, the receive callback is called with the status EasyLink_Status_Aborted (as I would expect) and yet, the following call to EasyLink_transmitAsync() returns an EasyLink_Status_BusyError, suggesting that the RF Core is still in receive mode. From my understanding, EasyLink_Abort() is a blocking call, so once I call transmitAsync(), the abortion should already been done.
Below you will find my code, where I have removed the irrelevant parts in the interest of clarity.
/* * mac.c * * Created on: 14.07.2022 * Author: ---- */ #include <mac/mac.h> static macCallback_t callbackFxn = NULL; static void timerCallback(Timer_Handle myHandle, int_fast16_t status); static void timerInit(void); static void echoRxDoneCb(EasyLink_RxPacket * rxPacket, EasyLink_Status status); static void echoTxDoneCb(EasyLink_Status status); static void sendMacPdu(void); /* Timer variables */ static Timer_Handle timer0; static Timer_Params params; void macInit(macCallback_t cb) { timerInit(); callbackFxn = cb; // Initialize the EasyLink parameters to their default values EasyLink_Params easyLink_params; EasyLink_Params_init(&easyLink_params); /* * 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) { // callback for application error handling } dispHandle = Display_open(Display_Type_ANY, NULL); Display_clear(dispHandle); /* Listen for incoming packets */ enableRx(); /* Start timer that will trigger transmission */ startTimer(); } static void timerCallback(Timer_Handle myHandle, int_fast16_t status) { /* Send a Sync PDU */ sendMacPdu(); } static EasyLink_Status enableRx(void) { EasyLink_Status status; if(!bOngoingRx) { /* wait for next packet */ status = EasyLink_receiveAsync(echoRxDoneCb, 0); bOngoingRx = true; } return status; } static EasyLink_Status disableRx(void) { EasyLink_Status status; if(bOngoingRx) { /* Abort ongoing receptions */ status = EasyLink_abort(); bOngoingRx = false; } return status; } static void echoRxDoneCb(EasyLink_RxPacket * rxPacket, EasyLink_Status status) { if (status == EasyLink_Status_Success) { // handle received packet } /* only re-enable Rx if it was not aborted */ if (status != EasyLink_Status_Aborted) { status = enableRx(); } } static void echoTxDoneCb(EasyLink_Status status) { /* Transmission successfully done */ if (status == EasyLink_Status_Success) { // callbacks etc. } /* Since transmission is done, we can re-enter reception */ status = enableRx(); } static void sendMacPdu(void) { EasyLink_TxPacket txPacket = {{0}, 0, 0, {0}}; /* Fill some dummy data for testing */ txPacket.dstAddr[0] = 0xff; txPacket.len = 3; txPacket.payload[0] = 0x01; txPacket.payload[1] = 0x02; txPacket.payload[2] = 0x03; /* disable Rx prior transmission */ stat = disableRx(); /* Transmit the PDU */ // returns EasyLink_Status_BusyError stat = EasyLink_transmitAsync(&txPacket, echoTxDoneCb); } static void timerInit(void) { /* * Setting up the timer in continuous callback mode that calls the callback * function every 1,000,000 microseconds, or 1 second. */ Timer_init(); Timer_Params_init(¶ms); params.period = 1000000; params.periodUnits = Timer_PERIOD_US; params.timerMode = Timer_CONTINUOUS_CALLBACK; params.timerCallback = timerCallback; timer0 = Timer_open(CONFIG_TIMER_0, ¶ms); if (timer0 == NULL) { /* Failed to initialized timer */ while (1) {} } } static void startTimer(void) { if (Timer_start(timer0) == Timer_STATUS_ERROR) { /* Failed to start timer */ while (1) {} } }
Thank you in advance
Greetings,
Alex