Working Example for CC430

Ufuk Sevim
2012-07-06
2013-05-30
  • Ufuk Sevim

    Ufuk Sevim - 2012-07-06

    Hi JP,

    Could you supply a working example for CC430? I couldn't make the latest version (from github, a few days ago) work. It doesn't even compile due to a parsing error (line 969, radio_CC430.c) which I assume you haven't tested CC430 with the new version. Also there is a bug (I guess) at line 1010 in radio_CC430.c which prevents radio.state being equal to RADIO_STATE_TXSTART.

    I fixed those and configured all the ISF files properly but it didn't work. So, a working example for CC430 would be great. By the way agaidi version works properly, but it is a very old version as you know.

    Thanks

     
  • JP Norair

    JP Norair - 2012-07-11

    Try the latest commit.  I don't seem to remember ever getting these compile errors, and I just compiled and tested the CC430 port 5 minutes ago.  There is a TX bug that I am working to fix, but at least it will compile, and TX works at least for a while before it hangs.  TX might actually work continuously on your device - I'm testing a new piece of hardware that might be at fault.  It has been very difficult to track down this bug.

     
  • JP Norair

    JP Norair - 2012-07-11

    OK, I found and resolved the TX bug.  It might be a CC430 Erratum that no-one knew about until today.  But I have a workaround now.

     
  • Ufuk Sevim

    Ufuk Sevim - 2012-07-17

    I have 2 EZ430-CHRONOS-433 watches and I want to send application shell commands between these two devices. I downloaded the latest version and try to compile Demo_Opmode. It didn't compile due to lack of some definitions in app_config.h. I defined the absent ones properly and replaced the query template with an application shell template. Also, I modified the application for sending periodic packets. The transmitter seems to transmit packets periodically (at least it says like so in RF terminate callback). However, the receiver never receives a packet and a RX timeout occurs constantly. I changed some of the ISF files but no luck.

    Which application are you using for your tests? Are you doing any tests with Chronos?

     
  • Ufuk Sevim

    Ufuk Sevim - 2012-07-18

    Hi,

    I finally made RX work. Here a few bugs I could find:

    1. The Hold Scan Timeout calculation is NOT
    SC * ((SC) ? 1024 : 1)
    as stated in the code comments and spec. It is calculated like
    SC * (1 << (SC * 2))
    where SC is Scan Code in Hold Channel Scan Series file. My RX timeout value was so low that it always timed out. (see otutils_calc_timeout in OT_utils.c)

    2. The min_rssi variable in subcc430_lowrssi_reenter function in radio_CC430.c reads as -7, when I set CS threshold to -85 (+140 of course) in Channel Configuration ISF file. It is a direct comparison with current RSSI, so -7 is a very high value for that. I don't know why it is this way, but I set min_rssi to -85 statically for a temporary workaround. The received packets were rejected due to RSSI threshold requirement before.

    3. M2QP_CB_UDP is defined as
    m2qp.signal.shell_request(&m2np.rt.dlog, (ot_int)(rxq.back-rxq.getcursor), rxq.getcursor)
    But rxq.back is the end of the "allocation" of the buffer. So it returns a very big length to the UDP callback. It should be
    m2qp.signal.shell_request(&m2np.rt.dlog, (ot_int)(rxq.putcursor-rxq.getcursor-2), rxq.getcursor)
    where 2 for CRC.

    However, the automated response for Shell Request could not be send due to CSMA error. dll.comm.tca variable always reads as -1 in sysevt_txcsma in system.c when sending Shell Response. So, CSMA error is called due to timing requirements. I couldn't find the reason for this yet, any ideas?

     
  • Ufuk Sevim

    Ufuk Sevim - 2012-07-20

    Hi,

    Shell Request and Response are working now. Here a few bugs I could find:

    1. dll.comm.tca variable is calculated from timeout field of the dialog template according to the algorithm in the first entry of previous message. So, changing this value properly made it work.

    2. Also most significant bit of timeout field of dialog template is used for indicating presence of RX channel list. But line 180 in m2_transport.c (otapi_put_dialog_tmpl function) is
    dialog->timeout    |= (dialog->channels != 0) ? 0 : 0x80;
    which causes parsing error in the request. This line should be
    dialog->timeout    |= (dialog->channels != 0) ? 0x80 : 0;

    3. In function rm2_rxdata_isr in radio_CC430.c, radio.state reads as RADIO_STATE_RXINIT when receiving a response. But there is no "case" clause for this state which causes killing radio. So, I added
    case (RADIO_STATE_RXINIT >> RADIO_STATE_RXSHIFT): {
    return;
    }
    to the switch statement.

    However, after receiving Shell Response, the state machine in sys_event_manager stucks at TASK_radio state. sys.evt.RFA.event_no and sys.mutex don't get cleared. I haven't any workaround for this yet.

     
  • Ufuk Sevim

    Ufuk Sevim - 2012-07-20

    Hi,

    I have changed line 1415 in system.c from
    fcode = (session->netstate & M2_NETSTATE_RESP);
    to
    fcode = 0;
    for a temporary workaround. I have to say that, I couldn't understand the logic behind the previous statement, but it makes the state machine stuck at TASK_radio.

    Also there is an erratum for CC430 "TAB24" in http://www.ti.com/lit/er/slaz052j/slaz052j.pdf. After RF Receive Complete interrupt, sometimes platform_ot_preempt couldn't fire the timer interrupt. I added a
    __no_operation();
    line at the end of the platform_ot_preempt function which solved the problem.

    Now the whole thing (Shell Request and Response) works, but it is not stable. Sometimes the requester just hangs. It could be an erratum for CC430.

     
  • Ufuk Sevim

    Ufuk Sevim - 2012-07-21

    Hi,

    I find out that the TAB24 erratum has nothing to do with the situation. Sometimes timer interrupt doesn't fire after calling platform_ot_preempt and exiting from RF interrupt. So, the device stucks at LPM0.

    I read all the errata document but haven't find any workarounds yet.

     
  • JP Norair

    JP Norair - 2012-07-22

    Replying one at a time:

    1. The Hold Scan Timeout calculation is NOT
    SC * ((SC) ? 1024 : 1)
    as stated in the code comments and spec. It is calculated like
    SC * (1 << (SC * 2))
    where SC is Scan Code in Hold Channel Scan Series file. My RX timeout value was so low that it always timed out. (see otutils_calc_timeout in OT_utils.c)

    The exponent + mantissa is actually the correct way to represent timeout.  The spec has had some small modifications since draft 12, which is the public spec right now.  DASH7 Alliance is managing the changes.

    2. The min_rssi variable in subcc430_lowrssi_reenter function in radio_CC430.c reads as -7, when I set CS threshold to -85 (+140 of course) in Channel Configuration ISF file. It is a direct comparison with current RSSI, so -7 is a very high value for that. I don't know why it is this way, but I set min_rssi to -85 statically for a temporary workaround. The received packets were rejected due to RSSI threshold requirement before.

    I'll look into this, it seems like a simple bug.  I know that RSSI has worked in the past, but I re-arranged things and maybe there is a problem.

    3. M2QP_CB_UDP is defined as
    m2qp.signal.shell_request(&m2np.rt.dlog, (ot_int)(rxq.back-rxq.getcursor), rxq.getcursor)
    But rxq.back is the end of the "allocation" of the buffer. So it returns a very big length to the UDP callback. It should be
    m2qp.signal.shell_request(&m2np.rt.dlog, (ot_int)(rxq.putcursor-rxq.getcursor-2), rxq.getcursor)
    where 2 for CRC.

    I'm cleaning up the M2QP callback system for v0.3.  Actually, I'm working on this now.  The UDP callback now will be issued on both request and response, and the application may use the port information to determine request v. response.

    However, the automated response for Shell Request could not be send due to CSMA error. dll.comm.tca variable always reads as -1 in sysevt_txcsma in system.c when sending Shell Response. So, CSMA error is called due to timing requirements. I couldn't find the reason for this yet, any ideas?

    I've had this problem sometimes when there's an interrupt collision with another system - so, by the time the txcsma function is called in system.c, the process has already expired.  In my case, the other task was a USB MAC, so I have to be careful about calling logger functions in time-sensitive callbacks.  MSP430 is not good at managing multiple, time-sensitive tasks (like two MACs) because the interrupt driver is flat.  I've had success using it with multiple, slower tasks.

    For the record, the Cortex-M parts have a sophisticated interrupt controller that is much better for using with multiple, time-sensitive tasks.  So for gateway-type parts, it's a better choice.  For most kinds of endpoints, the MSP430 should be fine.

     
  • JP Norair

    JP Norair - 2012-07-23

    I have changed line 1415 in system.c from
    fcode = (session->netstate & M2_NETSTATE_RESP);
    to
    fcode = 0;
    for a temporary workaround. I have to say that, I couldn't understand the logic behind the previous statement, but it makes the state machine stuck at TASK_radio.

    This is an interesting problem.  I think I have found that the problem is in the network or transport layers, which don't adequately handle session netstates.  I'm making updates and I will test them shortly.

     
  • JP Norair

    JP Norair - 2012-07-23

    Regarding the last post, try this as well:

    radio_CC430.c, line 1185: (Notice sys_clear_mutex)

    void subcc430_finish(ot_int main_err, ot_int frame_err) {
        /// 1. Turn-off interrupts, reset autocalibration flag, clear DATA mutex
        radio_gag();
        //radio_idle();
        subcc430_reset_autocal();
        sys_clear_mutex(SYS_MUTEX_RADIO_DATA);
        
        /// 2. Run Callback, then reset radio & callback to null state
        radio.evtdone(main_err, frame_err);
        radio.evtdone   = &otutils_sig2_null;
        radio.flags    &= RADIO_FLAG_SETPWR;    //clear all other flags
        radio.state     = 0;
    }
    

    system.c, near line1442: (Notice sys.mutex &= …)

            if (pcode == 0) {
                fcode = (session->netstate & M2_NETSTATE_RESP);  // repurpose fcode
                if (frx_code == 0) {
                    sys.mutex |= SYS_MUTEX_PROCESSING;
                }
                if (frx_code | fcode) {
                    pcode = frx_code;       //don't return to kernel for bad frames
                    rm2_reenter_rx(0);
                }
                else if (fcode == 0) {
                    sys.evt.RFA.event_no    = 0;
                    sys.mutex              &= ~(SYS_MUTEX_RADIO_DATA | SYS_MUTEX_RADIO_LISTEN);
                    radio_sleep();
                }
            }
    

    These updates should prevent the task from getting stuck in TASK_radio.

     
  • Ufuk Sevim

    Ufuk Sevim - 2012-07-24

    Hi JP,

    Thanks for the reply. I did the changes you wrote. But it didn't work and I don't think this is the problem. Because fcode will not be zero in response state, so

    if (frx_code | fcode) {
        pcode = frx_code; //don't return to kernel for bad frames
        rm2_reenter_rx(0);
    }
    

    part is executed which doesn't clear event no and mutex and causes the stuck at TASK_radio.

    Also, I solved the device stuck problem. It has nothing to do with the timer interrupt firing. The problem was getting the RSSI. In sub_mac_filter in system.c, RSSI is tried to read before stabilize. So I added
    __delay_cycles(2000); // Wait for RSSI to stabilize
    just before getting RSSI in sub_mac_filter function which solved the problem.

    The link quality requirement was not satisfied before because RSSI was read as -95 dBm, which is not possible in my setup. Then frx_code was equal to -4 in rfevt_frx in system.c and the state machine stucked in TASK_radio again. I guess it will stuck at there for any kind of error due to previous problem.

     
  • Ufuk Sevim

    Ufuk Sevim - 2012-08-15

    Hi,

    I have found two more bugs.

    1. dll.comm.redundants reads as 0 when transmitting response in rfevt_ftx function in system.c. So,

    dll.comm.redundants    -= 1;

    line makes this variable 0xFF and 255 responses are sent instead of 1. I have added

    if(dll.comm.redundants > 0)

    check before reducing this variable.

    2. In sub_filedata function in alp_filedata.c

    if (respond & ((err_code != 0) | file_mod))

    line is just wrong and will be always 0, which causes no response when writing to a file. It should be

    if (respond && ((err_code != 0) || file_mod))