Time to create our first Radio project. A transmitter. Part 2 and final.
We continue with the project we created in part 1. At the end of this blog, we 'll have our transmitter running. And we'll be able to test it. |
Change our Source
We only need to change our main source file (mine is calles aes.c). We'll include the radio API, create variables for our task handle and payload, and the radio task.
That's really it. Fairly simple.
We borrow the TX code from the TI-RTOS rfPacketTx example.
Include the header file generated by SmartRF Studio, and stdlib.h (we use the rand() function to generate random payload).
#include "smartrf_tx.h" #include <stdlib.h>
Then we add our handles and constants. I've also created a prototype for our task function.
/***** Defines *****/ #define TX_TASK_STACK_SIZE 1024 #define TX_TASK_PRIORITY 2 /* TX Configuration */ #define PAYLOAD_LENGTH 30 #define PACKET_INTERVAL (uint32_t)(4000000*0.5f) /* Set packet interval to 500ms */ /***** Prototypes *****/ static void txTaskFunction(UArg arg0, UArg arg1); /***** Variable declarations *****/ static Task_Params txTaskParams; Task_Struct txTask; /* not static so you can see in ROV */ static uint8_t txTaskStack[TX_TASK_STACK_SIZE]; static RF_Object rfObject; static RF_Handle rfHandle; uint32_t time; static uint8_t packet[PAYLOAD_LENGTH]; static uint16_t seqNumber;
Our task initialisation function (we prototyped our task declaration because it's used in this function, before the implementation).
This function first primes our TI-RTOS parameters with defaults. We override where needed.
void TxTask_init() { Task_Params_init(&txTaskParams); txTaskParams.stackSize = TX_TASK_STACK_SIZE; txTaskParams.priority = TX_TASK_PRIORITY; txTaskParams.stack = &txTaskStack; txTaskParams.arg0 = (UInt)1000000; // we don't use this :) Task_construct(&txTask, txTaskFunction, &txTaskParams, NULL); }
Our TI-RTOS task will do the actual sending.
It's worth checking out the documentation of the RF API to see why we're using the time variable.
static void txTaskFunction(UArg arg0, UArg arg1) { uint32_t time; RF_Params rfParams; RF_Params_init(&rfParams); RF_cmdPropTx.pktLen = PAYLOAD_LENGTH; RF_cmdPropTx.pPkt = packet; RF_cmdPropTx.startTrigger.triggerType = TRIG_ABSTIME; RF_cmdPropTx.startTrigger.pastTrig = 1; RF_cmdPropTx.startTime = 0; /* Request access to the radio */ rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams); /* Set the frequency */ RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0); /* Get current time */ time = RF_getCurrentTime(); while(1) { /* Create packet with incrementing sequence number and random payload */ packet[0] = (uint8_t)(seqNumber >> 8); packet[1] = (uint8_t)(seqNumber++); uint8_t i; for (i = 2; i < PAYLOAD_LENGTH; i++) { packet[i] = rand(); } /* Set absolute TX time to utilize automatic power management */ time += PACKET_INTERVAL; RF_cmdPropTx.startTime = time; /* Send packet */ RF_EventMask result = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0); if (!(result & RF_EventLastCmdDone)) { /* Error */ while(1); } } }
Our main() is simple. We init TI-RTOS, and kick it off.
int main(void) { /* Call board init functions */ Board_initGeneral(); TxTask_init(); /* Start BIOS */ BIOS_start(); return (0); }
At this point our firmware is finished. Yes, it's virtually the same as the rfPacketTx example.
But we started from an empty frame. And we're using radio settings that we defined ourselves in SmartRF Studio.
So now, build the code and fire up the debugger. Don't execute the code yet, because first we'll...
Create the Test Bed
You don't know that your radio is transmitting if you can't measure the results.
We'll use our second LaunchPad as receiver, and SmartRF Studio as our console.
So plug in your second LaunchPad and fire up SmartRF Studio for that one.
It doesn't matter what firmware you have loaded to that second CC1310. SmartRF will talk to the radio sub-module directly.
Navigate to the Packet RX tab, set as shown above, and push Start.
Then Start your code in the CCS debug session.
The radio will start beaming, and our test bed shows the received packets.
You can see that the signal strength is different than you used to see with the standard SmartRF TX/RX test.
That's because we used a lower TX Power in the previous blog, when we asked SmartRF Studio to generate our sources.
Proof that we were able to build our own radio, from zero (but with help of some nice tools and examples).
I'm not going to write a blog post for the receiver. You can follow the same process as for this transmitter.
Just use the SmartRF Studio Packet RX tab, and use the TI-RTOS rfPacketRx example as inspiration.
My next blog will try to send encrypted data from our own sender app to our own receiver....
Top Comments