1010typedef Library_nf_ti_easylink_nanoFramework_TI_EasyLink_TransmitPacket TransmitPacket;
1111typedef 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+
1318static EasyLink_RxPacket latestRxPacket;
19+ static EasyLink_TxPacket packetToTx;
1420static EasyLink_Status latestOperationStatus;
1521static 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
3229static 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+
58120HRESULT 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