This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Unable to consistently switch Rx channels (CC2530em on SmartRF05eb eval hardware)

Other Parts Discussed in Thread: Z-STACK, TIMAC, CC2530EM, CC2530, CC2591

Hi,

I don't really know what is going on in the TI MAC/Z-Stack library, but it is not working accordingly.

My hardware is a CC2530EM mounted on a SmartRF05eb evaluation board. Sofware is based on a mix of Timac 1.3.1 stack and Z-Stack 2.4.0-1.4.0  

I have a node that switches from a Chan22-Receiver to a Chan26-PanCoord beacon mode. It switches back and forth infinitely.

The problem occurs when switching from the Chan26-PanCoord beacon mode to Chan22-Receiver. It remains, occasionally, on the Chan 26 frequency.

What the written code does is as follows:

Forever Loop:

       (a)        Configure node to be a Chan26-PanCoord and put out 3 beacons on Chan 26  // MAC_RX_ON_WHEN_IDLE = False,  MAC_ASSOCIATION_PERMIT = False

       (b)        After 3 beacons, the code stops the Chan26-PanCoord by sending MAC_MlmeStartReq(&stopReq)  with stopReq.beaconOrder = 15;  // this always works

       (c)        // Now change to Chan22-Receiver ; 

        (d)         MAC_MlmeResetReq(TRUE); // this follows other codes which set up the Mac address and so forth ...

        (e)          MAC_MlmeScanReq(&scanReq) with scanReq.scanChannels = MAC_CHAN_22.  // sometimes ok, sometimes Nok (Not ok).

                                                                                                                                                                              // If Nok, node will remain on Chan26

        (f)        .... Lines of Codes to check if the switch is unsuccessful by checking if packets on Chan 26 is being received ....

        (g)          if packets on Chan 26 received successfully then {  // Something wrong here - did not switch to intended channel 22

                              // use even lower level Mac functions to change the channel: 

                            macRadioSetChannel(MAC_CHAN_22);  // This doesn't work at all - will still scan on Channel 26   

                             macLowLevelReset();  // This doesn't work at all - will still scan on Channel 26

                           macLowLevelInit(); // this definitely knocks the node back to Channel 22, but this line will screw up the (b) part in the Forever Loop. Program hangs on (b).

                            MAC_InitCoord(); //  this also knocks the node back to Channel 22, but like the above line, program will hang when it loops back to (b) later.

                     Endif

Repeat

Qn : why are all the High level and low level resets useless in making the node switch channels ( i.e. from 26 to 22) ?

While the high and low level Mac Init functions are effective, they screw up later codes which require switching back to Chan26-PanCoord . So they are not the solution either.

I know that another solution is to use watchdog reset. But that is my last means. I would expect a mature chip like the CC2530 to perform as expected.

My company has already invested on an entire reel of CC2530 and CC2591 ICs. I really don't know how to face my CEO if this simple channel switching issue is indeed a TI chip bug.

Thanx.

  

 

 

 

  • I did a little digging and found that MAC code got a small change recently that might be related to your problem.

     

    In mac_radio_defs.h, add the following definition:

    #define MAC_RADIO_CHANNEL_DEFAULT   11

    #define MAC_RADIO_CHANNEL_INVALID   0xFF

    #define MAC_RADIO_TX_POWER_INVALID   0xFF

     

    In mac_radio.c, in the function macRadioInit(), change the following line:

    macPhyChannel = MAC_RADIO_CHANNEL_INVALID;

  • The prescribed changes don't do a thing at all.

    macPhyChannel will  reset back to default Channel 11 later when I call macLowLevelInit().

    Here is my observation : Calling macLowLevelInit() helps a lot to change the frequency, but ... 

    1) sets macPhyChannel to Channel 11 eventually (with or without the prescribed changes) , but also

    2) re-inits all the RxStates to MAC_RX_ACTIVE_NO_ACTIVITY and

    3) the TxState to MAC_TX_ACTIVE_NO_ACTIVITY

    The above states do not match the higher level mac init functions and will cause system crash.  Latter commands like MAC_MlmeStartReq(startReq) will result in system to hang.

    This is my conclusion for the CC2530 chip:

    1) I suspect the CC2530 chip is not so frequency agile as claimed. So far the only way that seems to work consistently is a hard reset or watchdog reset, and

    2) users should avoid all the low level inits and resets, coz it screws up the higher layer Mac resets and Mac inits

    2) While a watchdog reset will solve the frequency agility issue, it is sadly prehistoric, it reminds me of the Windows 95 reset button

    3) A watchdog reset is not power efficient as I have to store info into NV_mem before the watchdog reset and then Restore from NV_mem again after the reset sequence.

    4) Since the CC2530 is stated to be a 802.15.4-standard compliant and a Zigbee-standard compliant solution, then it is expected for the chip to behave in accordance with the 802.15.4 standard specs. For example, in the standards, the MAC command  MAC_MlmeStartReq(&startReq) command and the MAC_MlmeScanReq(&scanReq) are decoupled from one another. In the CC2530 chip, they are so related ... if I issue a MAC_MlmeStartReq(&startReq) in one frequency bin, I have to go through a lot of crazy resets (Mac reset, timer resets and system resets to kill all the ghost of the MAC_MlmeStartReq(&startReq) command) before I can issue a successful  MAC_MlmeScanReq(&scanReq) in another frequency bin.  

       

       

     

     

  • Looks like I have solved the problem. This has something to do with invalid power saving states and mac states. An engineer had hardcoded and commented out all codes related to the

    #ifdef POWER_SAVING lines in functions osal_start_system() and in Hal_ProcessEvent()

    and added several lines of halSleep() calls in place of the commented-out codes.

    This, I think, mucked up the states especially when switching frequency bins. The brute force hard codes work as long as it does not switch frequency bins.

    But if the application switches frequency bins regularly, the states go wonky over time and the only solution is a hard reset or watchdog reset (Mac resets don't work anymore).

    So the only way was to hand back control to the osal system and let osal decide when to sleep. I removed all the explicit user-implemented halSleep() and it seems to run fine now (no problems switching frequency bins). I can compile and run successfully either with POWER_SAVING defined or not defined.

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------