Skip to content

Commit 0f58bdc

Browse files
authored
Rework TI EasyLink (#1726)
***NO_CI***
1 parent 3063f6c commit 0f58bdc

File tree

2 files changed

+169
-100
lines changed

2 files changed

+169
-100
lines changed

targets/TI-SimpleLink/nanoCLR/nanoFramework.TI.EasyLink/nf_ti_easylink.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
// TI-RTOS Header files
1616
#include <ti/drivers/rf/RF.h>
17+
#include <ti/sysbios/BIOS.h>
18+
#include <ti/sysbios/knl/Semaphore.h>
19+
#include <ti/sysbios/knl/Event.h>
1720

1821
// Board Header files
1922
#include <Board.h>

targets/TI-SimpleLink/nanoCLR/nanoFramework.TI.EasyLink/nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController.cpp

Lines changed: 166 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,20 @@
1010
typedef Library_nf_ti_easylink_nanoFramework_TI_EasyLink_TransmitPacket TransmitPacket;
1111
typedef Library_nf_ti_easylink_nanoFramework_TI_EasyLink_ReceivedPacket ReceivedPacket;
1212

13+
#define RADIO_EVENT_ALL 0xFFFFFFFF
14+
#define RADIO_EVENT_TX_PACKET (uint32_t)(1 << 0)
15+
#define RADIO_EVENT_RX (uint32_t)(1 << 1)
16+
#define RADIO_EVENT_ABORT (uint32_t)(1 << 2)
17+
1318
static EasyLink_RxPacket latestRxPacket;
19+
static EasyLink_TxPacket packetToTx;
1420
static EasyLink_Status latestOperationStatus;
1521
static EasyLink_Params easyLink_params;
1622

17-
static Task_Handle abortEasyLinkTask;
18-
19-
// Task to abort EasyLink
20-
static void AbortEasyLink(UArg arg0, UArg arg1)
21-
{
22-
(void)arg0;
23-
(void)arg1;
24-
25-
latestOperationStatus = EasyLink_abort();
26-
27-
// fire event for EasyLink init completed
28-
Events_Set(SYSTEM_EVENT_FLAG_RADIO);
29-
}
23+
// developer note: these are NOT static so they are visible during debug
24+
Task_Struct easyLinkTask;
25+
Event_Struct radioOperationEvent;
26+
Event_Handle radioOperationEventHandle;
3027

3128
// handler for TX operation done
3229
static void TxDone(EasyLink_Status status)
@@ -55,6 +52,71 @@ static void RxDone(EasyLink_RxPacket *rxPacket, EasyLink_Status status)
5552
Events_Set(SYSTEM_EVENT_FLAG_RADIO);
5653
}
5754

55+
// EasyLink Task
56+
void EasyLinkTask(UArg arg0, UArg arg1)
57+
{
58+
(void)arg0;
59+
(void)arg1;
60+
61+
// init EasyLink
62+
latestOperationStatus = EasyLink_init(&easyLink_params);
63+
64+
if (latestOperationStatus == EasyLink_Status_Success)
65+
{
66+
// EasyLink init successfull
67+
// OK to proceed
68+
69+
// fire CLR event
70+
Events_Set(SYSTEM_EVENT_FLAG_RADIO);
71+
72+
while (1)
73+
{
74+
// wait for RADIO events
75+
uint32_t events = Event_pend(radioOperationEventHandle, 0, RADIO_EVENT_ALL, BIOS_WAIT_FOREVER);
76+
77+
if (events & RADIO_EVENT_TX_PACKET)
78+
{
79+
// set priority for the transmission
80+
EasyLink_setCtrl(EasyLink_Ctrl_Cmd_Priority, (uint32_t)EasyLink_Priority_Normal);
81+
82+
// start async transmission
83+
latestOperationStatus = EasyLink_transmitAsync(&packetToTx, TxDone);
84+
85+
if (latestOperationStatus != EasyLink_Status_Success)
86+
{
87+
// something went wrong!
88+
// fire CLR event
89+
Events_Set(SYSTEM_EVENT_FLAG_RADIO);
90+
}
91+
}
92+
93+
if (events & RADIO_EVENT_RX)
94+
{
95+
// start async receive
96+
latestOperationStatus = EasyLink_receiveAsync(RxDone, 0);
97+
98+
if (latestOperationStatus != EasyLink_Status_Success)
99+
{
100+
// something went wrong!
101+
// fire CLR event
102+
Events_Set(SYSTEM_EVENT_FLAG_RADIO);
103+
}
104+
}
105+
106+
if (events & RADIO_EVENT_ABORT)
107+
{
108+
latestOperationStatus = EasyLink_abort();
109+
110+
// fire CLR event
111+
Events_Set(SYSTEM_EVENT_FLAG_RADIO);
112+
}
113+
}
114+
}
115+
116+
// fire event for EasyLink abort completed
117+
Events_Set(SYSTEM_EVENT_FLAG_RADIO);
118+
}
119+
58120
HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::get_AbsoluteTime___U4(
59121
CLR_RT_StackFrame &stack)
60122
{
@@ -171,8 +233,6 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::Dis
171233
{
172234
NANOCLR_HEADER();
173235

174-
Task_Params taskParams;
175-
176236
CLR_RT_HeapBlock hbTimeout;
177237
CLR_INT64 *timeoutTicks;
178238
CLR_INT32 timeout_ms;
@@ -188,26 +248,8 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::Dis
188248

189249
if (stack.m_customState == 1)
190250
{
191-
// setup Task thread
192-
Task_Params_init(&taskParams);
193-
taskParams.stackSize = 512;
194-
taskParams.priority = 4;
195-
196-
// create task
197-
abortEasyLinkTask = Task_create((Task_FuncPtr)AbortEasyLink, &taskParams, Error_IGNORE);
198-
if (abortEasyLinkTask == NULL)
199-
{
200-
// store result
201-
latestOperationStatus = EasyLink_Status_Aborted;
202-
203-
// prevent event from being processed
204-
eventResult = false;
205-
}
206-
else
207-
{
208-
// bump custom state
209-
stack.m_customState = 2;
210-
}
251+
// bump custom state
252+
stack.m_customState = 2;
211253
}
212254

213255
while (eventResult)
@@ -216,7 +258,9 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::Dis
216258
NANOCLR_CHECK_HRESULT(
217259
g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_Radio, eventResult));
218260

219-
Task_delete(&abortEasyLinkTask);
261+
Task_destruct(&easyLinkTask);
262+
263+
Event_destruct(&radioOperationEvent);
220264

221265
if (eventResult)
222266
{
@@ -251,51 +295,92 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::Ini
251295
uint8_t i = 0;
252296
EasyLink_PhyType phyType = (EasyLink_PhyType)0;
253297

298+
Task_Params taskParams;
299+
300+
CLR_RT_HeapBlock hbTimeout;
301+
CLR_INT64 *timeoutTicks;
302+
CLR_INT32 timeout_ms;
303+
bool eventResult = true;
304+
254305
CLR_RT_HeapBlock *pThis = stack.This();
255306
FAULT_ON_NULL(pThis);
256307

257-
// initialize the EasyLink parameters to their default values
258-
EasyLink_Params_init(&easyLink_params);
259-
260-
// get managed Phy Type
261-
phyType = (EasyLink_PhyType)(pThis[FIELD___phyType].NumericByRef().u1);
308+
// set timeout
309+
// !! need to cast to CLR_INT64 otherwise it wont setup a proper timeout infinite
310+
hbTimeout.SetInteger((CLR_INT64)-1);
311+
NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks));
262312

263-
// check if this PHY config is supported
264-
while (i < EasyLink_numSupportedPhys)
313+
if (stack.m_customState == 1)
265314
{
266-
if (EasyLink_supportedPhys[i].EasyLink_phyType == phyType)
315+
// initialize the EasyLink parameters to their default values
316+
EasyLink_Params_init(&easyLink_params);
317+
318+
// get managed Phy Type
319+
phyType = (EasyLink_PhyType)(pThis[FIELD___phyType].NumericByRef().u1);
320+
321+
// check if this PHY config is supported
322+
while (i < EasyLink_numSupportedPhys)
267323
{
268-
break;
324+
if (EasyLink_supportedPhys[i].EasyLink_phyType == phyType)
325+
{
326+
break;
327+
}
328+
i++;
269329
}
270-
i++;
271-
}
272330

273-
if (i == EasyLink_numSupportedPhys)
274-
{
275-
NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED);
276-
}
331+
if (i == EasyLink_numSupportedPhys)
332+
{
333+
NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED);
334+
}
277335

278-
easyLink_params.ui32ModType = phyType;
336+
easyLink_params.ui32ModType = phyType;
279337

280-
// try to start EasyLink
281-
latestOperationStatus = EasyLink_init(&easyLink_params);
338+
// Create event used internally for state changes
339+
Event_Params eventParam;
340+
Event_Params_init(&eventParam);
341+
Event_construct(&radioOperationEvent, &eventParam);
342+
radioOperationEventHandle = Event_handle(&radioOperationEvent);
282343

283-
if (latestOperationStatus != EasyLink_Status_Success)
284-
{
285-
// something went wrong
286-
// call abort to force any TX/RX operation that could be lingering
287-
EasyLink_abort();
344+
// setup Task thread
345+
Task_Params_init(&taskParams);
346+
taskParams.stackSize = 1024;
347+
taskParams.priority = 4;
288348

289-
// try again
290-
latestOperationStatus = EasyLink_init(&easyLink_params);
349+
// create task
350+
Task_construct(&easyLinkTask, EasyLinkTask, &taskParams, NULL);
291351

292-
// need to setup Rx address, if any is set
293-
if (latestOperationStatus == EasyLink_Status_Success)
352+
// bump custom state
353+
stack.m_customState = 2;
354+
}
355+
356+
while (eventResult)
357+
{
358+
// non-blocking wait allowing other threads to run while we wait for the receive operation to complete
359+
NANOCLR_CHECK_HRESULT(
360+
g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_Radio, eventResult));
361+
362+
if (eventResult)
294363
{
295-
UpdateRxAddressFilter(stack);
364+
// event occurred!!
365+
if (latestOperationStatus == EasyLink_Status_Success)
366+
{
367+
// need to setup Rx address, if any is set
368+
UpdateRxAddressFilter(stack);
369+
}
296370
}
371+
else
372+
{
373+
// timeout occurred
374+
// nothing else that can be done here
375+
}
376+
377+
// done here
378+
break;
297379
}
298380

381+
// pop timeout heap block from stack
382+
stack.PopValue();
383+
299384
// return operation status
300385
stack.SetResult_U1(latestOperationStatus);
301386

@@ -362,19 +447,10 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::
362447
if (stack.m_customState == 1)
363448
{
364449
// enter receive mode
365-
latestOperationStatus = EasyLink_receiveAsync(RxDone, 0);
366-
if (latestOperationStatus != EasyLink_Status_Success)
367-
{
368-
// fail to start
450+
Event_post(radioOperationEventHandle, RADIO_EVENT_RX);
369451

370-
// prevent event from being processed
371-
eventResult = false;
372-
}
373-
else
374-
{
375-
// bump custom state
376-
stack.m_customState = 2;
377-
}
452+
// bump custom state
453+
stack.m_customState = 2;
378454
}
379455

380456
while (eventResult)
@@ -545,7 +621,6 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::
545621
CLR_UINT64 dueTimeMiliseconds;
546622
CLR_INT64 *timeoutTicks;
547623
uint32_t absTime;
548-
EasyLink_TxPacket txPacket = {{0}, 0, 0, {0}};
549624
bool eventResult = true;
550625

551626
// get a pointer to the managed object instance and check that it's not NULL
@@ -596,20 +671,23 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::
596671
packet = stack.Arg1().Dereference();
597672
FAULT_ON_NULL(packet);
598673

674+
// clear packet
675+
memset(&packetToTx, 0, sizeof(EasyLink_TxPacket));
676+
599677
// dereference the payload buffer
600678
payloadBuffer = packet[TransmitPacket::FIELD___payload].DereferenceArray();
601679

602680
// get payload length
603-
txPacket.len = payloadBuffer->m_numOfElements;
681+
packetToTx.len = payloadBuffer->m_numOfElements;
604682

605683
// copy buffer to packet
606-
memcpy(txPacket.payload, payloadBuffer->GetFirstElement(), txPacket.len);
684+
memcpy(packetToTx.payload, payloadBuffer->GetFirstElement(), packetToTx.len);
607685

608686
// dereference the address buffer
609687
address = packet[TransmitPacket::FIELD___address].DereferenceArray();
610688

611689
// copy buffer to packet
612-
memcpy(txPacket.dstAddr, address->GetFirstElement(), address->m_numOfElements);
690+
memcpy(packetToTx.dstAddr, address->GetFirstElement(), address->m_numOfElements);
613691

614692
// get dueTime managed parameter
615693

@@ -623,29 +701,17 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::
623701
if (dueTimeMiliseconds > 0)
624702
{
625703
EasyLink_getAbsTime(&absTime);
626-
txPacket.absTime = absTime + EasyLink_ms_To_RadioTime(dueTimeMiliseconds);
627-
}
628-
else
629-
{
630-
// Set Tx absolute time to current time + 100ms
631-
txPacket.absTime = absTime + EasyLink_ms_To_RadioTime(100);
704+
packetToTx.absTime = absTime + EasyLink_ms_To_RadioTime(dueTimeMiliseconds);
632705
}
633706

634-
// start transmission
635-
latestOperationStatus = EasyLink_transmitAsync(&txPacket, TxDone);
707+
// set priority for the transmission
708+
EasyLink_setCtrl(EasyLink_Ctrl_Cmd_Priority, (uint32_t)EasyLink_Priority_Normal);
636709

637-
if (latestOperationStatus != EasyLink_Status_Success)
638-
{
639-
// fail to start
710+
// signal event to start transmission
711+
Event_post(radioOperationEventHandle, RADIO_EVENT_TX_PACKET);
640712

641-
// prevent event from being processed
642-
eventResult = false;
643-
}
644-
else
645-
{
646-
// bump custom state
647-
stack.m_customState = 2;
648-
}
713+
// bump custom state
714+
stack.m_customState = 2;
649715
}
650716

651717
while (eventResult)
@@ -671,7 +737,7 @@ HRESULT Library_nf_ti_easylink_nanoFramework_TI_EasyLink_EasyLinkController::
671737
if ((latestOperationStatus != EasyLink_Status_Success) && (latestOperationStatus != EasyLink_Status_Aborted))
672738
{
673739
// abort EasyLink operation
674-
EasyLink_abort();
740+
Event_post(radioOperationEventHandle, RADIO_EVENT_ABORT);
675741
}
676742

677743
// done here

0 commit comments

Comments
 (0)