Dear All,
I'm using MKW01 with Radio Utility source code which can be downloaded from freescale.com. I observed that in the provided project, UART transmission is blocking, indeed we always have the following code when sending UART data to external host.
(void)UartX_Transmit("hello world", 11, UartTxCallBack);
while (UartX_IsTxActive());
The same approach is used also when receiving a wireless packet that must be transmitted to external microcontroller. Indeed the function (void)MLMERXEnableRequest(gpSmacRxPacket, 0);
is called only after UART transmission is completed.
In my project I would like to have a non-blocking approach for UART transmission, in other words I would use a static buffer for UART TX activities where I can copy the information to be transmitted to external host and leave the UART TX ISR to handle UART TX. With this not blocking approach it would be possible to call MLMERXEnableRequest() before UART transmission is completed. Unfortunately I observed that if I call MLMERXEnableRequest() while UART TX is in progress it seams that RX enable request is not executed properly even if it does not return any error. Indeed I'm not able to receive other wireless packets. The problem is solved if I call MLMERXDisableRequest() and MLMERXEnableRequest() again.
Interestingly if I protect from UART TX ISR calls both MLMERXEnableRequest() and also Phy_ISR() when it is called for the first time when receiving a new wireless packet everything works fine. In other words RF RX packet handling is successfull if I temporary disable UART TX ISR. It seams that there are some activities in the above functions and in general in RF RX packet handling that are sensitive to interruptions or delays caused by UART TX ISR. I want to underline that UART TX ISR is the short ISR provided in the source code and it has the same priority of all other ISRs called in the project.
Does anybody know how to explain this behaviour? Should SMAC primitives and in general RF RX packet handling be protected from other application ISRs?
Best Regards,
Matteo
Hello Matteo,
I wanted to give you a head's up regarding the new KSDK based SMAC which will be launched soon. The reason I'm telling you about it is because it comes with a very powerful framework including serial interface management. The package will also include demo applications such as Connectivity Test, Wireless Messenger, Wireless Uart. These demos will give you both a good startup code and also tools to calibrate and configure MKW01.
Regards,
Andrei
Dear Matteo,
You must search for flag smacState. The state of this flag when UART TX is in progress is very likely to be mSmacStateTransmitting_c. So when calling MLMERXEnableRequest(), the return from this function will be gErrorBusy_c. This happens because, in order to continue the RX process, the Radio needs to be in Idle mode smacState = mSmacStateIdle_c. Disabling and enabling RF RX works in this case because MLMERXDisableRequest() resets that flag to different value.
It is recommended that you disable the Radio interrupts when configuring it, i.e. for TX or RX mode and DIO signal settings. However, this is already handled inside the PHY primitives (i.e. PhyPlmeRxRequest) and that is how it works.
Furthermore, please notice the application demo is provided as it is and the intention of it is to be a reference platform for users migrating it for their custom needs, you can certainly modify it to work with non blocking functions, but that is application specific.
Regards,
Angel
Dear AngelC,
thanks for your feedback. Actually this does not seem to be the problem. Indeed in the test I'm performing the device that experiences this problem is only a sniffer device that never transmits wireless packets. Moreover when calling MLMERXEnableRequest() I would get an error if smacState != mSmacStateIdle_c but in my case gErrorNoError_c is returned by the function. It seams that if UART TX ISR is active, something goes wrong during the configurations performed by MLMERXEnableRequest() or possibily during the subsequent RF RX reception process, but this error is not notified to higher layers and so the external host is not aware of this error situation.
Do you have other ideas that could help in solving this problem?
Best Regards,
Matteo
Dear Matteo,
Well, I would need to reproduce your issue locally to find out what is exactly happening. It is very likely to be a flag or missing configuration. Since I am not aware of all the changes you have done to Radio Utility source code, it would be easier to work in a different example.
I am attaching a “Wireless UART” project I just tested. You could modify UartUtil_Tx() function called in gWUAppStateSendDataUart_c state of WUApp_MainStateMachine() function. Whenever something is received over the air, it will be sent via UART entering this case. Normally it is a blocking function as you described before, but you could easily change not to have the while loops. I just tested that and the demo still worked without any issues.
I am also attaching the corresponding documentation to run the demo. I would recommend you to first test it as it is and then customize it as desired. Please notice this code should be used as reference and any modification to it is totally application specific.
I hope it helps.
AngelC
Dear AngelC,
unfortunately, so far I had no time to test the firmware you provided. Nevertheless I went deeper into the problem and I would like to share with you some new observations/considerations. The system where I implemented a non-blocking UART transmission is actually a sniffer device that transmits via UART the main parameters of each wireless packet it is able to receive. This device is deployed in a small network where 3 devices communicate together in the same channel. I observed that the RF RX problem in the sniffer device mainly arises when both UART TX ISR and RF packet reception become active in the same time period.
In the following I'm providing the radio register values when RF RX works properly and when RF RX seams to be blocked.
Reg. Number [HEX format] | Reg. Value when RF RX OK [HEX format] | Reg. Value when RF RX NOT OK [HEX format] |
00 | 36 | 00 |
01 | 10 | 10 |
02 | 00 | 00 |
03 | 01 | 01 |
04 | 40 | 40 |
05 | 03 | 03 |
06 | 33 | 33 |
07 | F6 | F6 |
08 | 74 | 74 |
09 | 09 | 09 |
0A | 41 | 41 |
0B | 40 | 40 |
0C | 02 | 02 |
0D | 92 | 92 |
0E | F5 | F5 |
0F | 20 | 20 |
10 | 23 | 23 |
11 | 9F | 9F |
12 | 09 | 09 |
13 | 1A | 1A |
14 | 40 | 40 |
15 | B0 | B0 |
16 | 7B | 7B |
17 | 9B | 9B |
18 | 88 | A8 |
19 | B1 | B1 |
1A | B1 | B1 |
1B | 40 | 40 |
1C | 80 | 80 |
1D | 06 | 06 |
1E | 10 | 10 |
1F | 00 | 00 |
20 | 00 | 00 |
21 | 00 | 00 |
22 | 00 | 00 |
23 | 00 | 00 |
24 | CD | A0 |
25 | 88 | 48 |
26 | 00 | 00 |
27 | D8 | D9 |
28 | 00 | 66 |
29 | FF | FF |
2A | 00 | 00 |
2B | 00 | 00 |
2C | 00 | 00 |
2D | 03 | 03 |
2E | 98 | 98 |
2F | 01 | 01 |
30 | 01 | 01 |
31 | 01 | 01 |
32 | 01 | 01 |
33 | 01 | 01 |
34 | 01 | 01 |
35 | 01 | 01 |
36 | 01 | 01 |
37 | 98 | 98 |
38 | FF | FF |
39 | 00 | 00 |
3A | 00 | 00 |
3B | 00 | 00 |
3C | 00 | 00 |
3D | 00 | 00 |
3E | 00 | 00 |
3F | 00 | 00 |
40 | 00 | 00 |
41 | 00 | 00 |
42 | 00 | 00 |
43 | 00 | 00 |
44 | 00 | 00 |
45 | 00 | 00 |
46 | 00 | 00 |
47 | 00 | 00 |
48 | 00 | 00 |
49 | 00 | 00 |
4A | 00 | 00 |
4B | 00 | 00 |
4C | 00 | 00 |
4D | 00 | 00 |
4E | 01 | 01 |
4F | 00 | 00 |
57 | 00 | 00 |
58 | 2D | 2D |
5F | 00 | 00 |
6F | 30 | 30 |
71 | 00 | 00 |
As already underlined in my previous posts it is necessary to call MLMERXDisableRequest() and MLMERXEnableRequest() to solve the problem.
Moreover please notice that when giving a smaller priority to UART TX/RX ISR with respect to SMAC ISRs the problem does not arises. Indeed assigning NVIC priority 0 to all SMAC ISRs and NVIC priority 1 to UART TX/RX ISRs I've never experienced the problem so far.
I hope this helps in having a deeper and more clear understaing of the problem.
Regards,
Matteo
Dear Matteo,
Please notice that the SMAC projects are provided as reference and obviously do not meet all application’s requirements. For this, they are provided in source code and could be modified to meet specific application’s needs, like the non-blocking feature your application requires, but that is totally application specific. While there might be different ways to attack this issue, user is free to use the one preferred.
I really appreciate your feedback and sharing your results. It would be helpful if you could run the code I sent so you could reproduce the same scenario using such code, but if yours already works then I guess it is not entirely necessary. Anyway, I am glad to hear you were able to implement a workaround for this specific scenario and your solution works properly.
Regards,
AngelC
------------------------------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------------------------