Other Parts Discussed in Thread: CC1310
Tool/software: TI-RTOS
Please help me figuring out a puzzle.
In this pretty basic program for LouchPad CC1310 I have a dedicated function for sending a radio message. Calling this function from the main task works fine. The messages go out every six seconds, as per the algorithm, and RF_runCmd returns 2 (RF_EventLastCmdDone) as it should.
My project, however, requires that I send out messages from event-based functions, such as hardware interrupt handlers and timer event handlers. And I cannot get either of those to work with the Tx function. The example below I have stripped off my application particularly for figuring out this problem. Please help me to get it to work.
Example description:
1. All inits, except for the radio's, are done in "main".
2. SendPacket is the radio function. All the radio stuff is done here - from init to shutting down.
3. txTaskFunction is the main task. It sends messages every 6 seconds. This works fine - messages are sent and received on the other end. In ROV (see screenshot 1) you can see a proof of error-free running in this "interrupt-free" mode. (Note that at the same time the Semaphore page shows an error as per screenshot 3. I don't know why this happens, as I am not using semaphores, and also I am not sure why this error is not reflected in BIOS scan results on screenshot 1.)
4. PinInterrupt is intended to process buttons events. Button 1 should shoot a message, Button 2 should start a 10 seconds timer, who's event handler Timer1Event would also shoot a message.
This is as for the description. Now how it doesn't work. When SendPacket is called from either PinInterrupt or Timer1Event, sending the packet fails. RF_runCmd returns 0 (zero) instead of 2. The program then gets stuck in some strange place in memory, before reaching the end of SendPacket. The ROV results of running it to that point are shown on screenshots 2 to 5 (number 3 is the same as in the "interrupt-free" mode).
Ideas? Thanks in advance!
/* * Copyright (c) 2015-2016, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /***** Includes *****/ #include <stdlib.h> #include <xdc/std.h> #include <xdc/runtime/System.h> #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/drivers/rf/RF.h> #include <ti/drivers/PIN.h> #include "Board.h" #include "smartrf_settings/smartrf_settings.h" /* Pin driver */ static PIN_State PinState; static PIN_Handle pinHandle; PIN_Config pinTable[] = { Board_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, Board_BTN1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE | PIN_HYSTERESIS, Board_BTN2 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE | PIN_HYSTERESIS, PIN_TERMINATE }; /* Prototypes */ static void txTaskFunction(UArg arg0, UArg arg1); /* Main Task */ Task_Struct txTask; static uint8_t txTaskStack[1024]; static Task_Params txTaskParams; /* Radio */ static RF_Object rfObject; static RF_Handle rfHandle; static RF_Params rfParams; #define PAYLOAD_LENGTH 30 static uint8_t packet[PAYLOAD_LENGTH]; static RF_EventMask TxResult; /* Timers */ Clock_Struct Timer1Struct; Clock_Handle Timer1Handle; /* Other */ bool Settling = 0; /* ====================== */ /* ==== Send packet ===== */ /* ====================== */ static void SendPacket(uint8_t data) { Settling = 1; // Flag to ignore buttons /* Construct payload */ packet[0] = 10; packet[1] = 15; packet[2] = data; /* Configure radio */ RF_Params_init(&rfParams); RF_cmdPropTx.pktLen = PAYLOAD_LENGTH; RF_cmdPropTx.pPkt = packet; RF_cmdPropTx.startTrigger.triggerType = TRIG_ABSTIME; RF_cmdPropTx.startTrigger.pastTrig = 1; rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams); RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL , 0); // Set the frequency /* Send packet */ RF_cmdPropTx.startTime = RF_getCurrentTime()+4000000*0.1f; // Transmit after 0.1 s delay TxResult = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0); if (!(TxResult & RF_EventLastCmdDone)) { /*System_abort("Radio transmission error\n");*/ } /* Power down the radio to save power */ RF_close(rfHandle); RF_yield(rfHandle); /* Blink green LED */ PIN_setOutputValue(pinHandle, Board_GLED, 1); Task_sleep(50*1000/Clock_tickPeriod); PIN_setOutputValue(pinHandle, Board_GLED, 0); /* Pause for settling */ Task_sleep(1000*1000/Clock_tickPeriod); Settling = 0; } /* ====================== */ /* === Pin interrupt ==== */ /* ====================== */ void PinInterrupt(PIN_Handle handle, PIN_Id pinId) { if (Settling) { } // Ignore buttons else if (pinId == 13) { SendPacket(11); } // Send a packet right away else if (pinId == 14) { // Start the send delay timer Clock_stop(Timer1Handle); Clock_start(Timer1Handle); } } /* ====================== */ /* == Timer1 interrupt == */ /* ====================== */ void Timer1Event(UArg arg0) { SendPacket(99); // Send a packet 10 s after Button 2 is pressed } /* ====================== */ /* ====== Main Task ===== */ /* ====================== */ static void txTaskFunction(UArg arg0, UArg arg1) { while(1) { Task_sleep(5000*1000/Clock_tickPeriod); // Send a packet approx. every 5 s SendPacket(00); } } /* ====================== */ /* ======== Init ======== */ /* ====================== */ int main(void) { /* Call board init functions. */ Board_initGeneral(); /* Open pins */ pinHandle = PIN_open(&PinState, pinTable); if (!pinHandle) { System_abort("Error initializing board pins\n"); } if (PIN_registerIntCb(&PinState, PinInterrupt)) { System_abort("Error initializing board pins\n"); } /* Initialize timers */ Clock_Params clkParams; Clock_Params_init(&clkParams); clkParams.period = 0; clkParams.startFlag = FALSE; Clock_construct(&Timer1Struct, (Clock_FuncPtr)Timer1Event, 10000*1000/Clock_tickPeriod, &clkParams); Timer1Handle = Clock_handle(&Timer1Struct); /* Initialize task */ Task_Params_init(&txTaskParams); txTaskParams.priority = 2; txTaskParams.stack = &txTaskStack; txTaskParams.stackSize = sizeof(txTaskStack); txTaskParams.arg0 = (UInt)1000000; Task_construct(&txTask, txTaskFunction, &txTaskParams, NULL); /* Start BIOS */ BIOS_start(); }