Esempio n. 1
0
OT_WEAK void dll_scan_timeout(void) {
/// This function just operates the timing-out of the RX.  RX is forced into
/// timeout when there is no data being received OR if the MAC is operating
/// under the Arbitrated regime, which uses strict time-slots.

/// @note if you want to use a built-in RX termination or polling timer inside
/// the radio core (some devices have these), be very careful.  If the radio
/// timer gets out of sync with the kernel (i.e. if your core timer isn't very
/// accurate), then it is going to cause all sorts of timing glitches.  Giving
/// the kernel control over listening makes the system more stable and better
/// synchronized.  Usage of HW RX timer is mostly useful for very specific
/// applications using very custom builds of OpenTag.

#if (RF_FEATURE(RXTIMER) == DISABLED)
    // If not presently receiving, time-out the RX.
    // else if presently receiving, pad timeout by 128
    if ((radio.state != RADIO_DataRX) || (dll.comm.csmaca_params & M2_CSMACA_A2P)) {    ///@todo change to LISTEN
        rm2_rxtimeout_isr();
    }
    else {
        sys.task[TASK_radio].event = 5;
        sys_task_setnext(&sys.task[TASK_radio], 128);
    }

#else
    // Add a little bit of time in case the radio timer is a bit slow.
    sys_task_setnext(&sys.task[TASK_radio]->nextevent, 10);
    sys.task[TASK_radio].event = 0;
#endif
}
Esempio n. 2
0
OT_WEAK void dll_systask_beacon(ot_task task) {
/// The beacon rountine runs as an idependent systask.
    m2session*  b_session;

    if ((task->event == 0) || (dll.netconf.b_attempts == 0)) {
        dll_idle();
        return;
    }

    /// Load file-based beacon:
    /// Open BTS ISF Element and read the beacon sequence.  Make sure there is
    /// a beacon file of non-zero length and that beacons are presently enabled.
    if (dll.netconf.dd_flags == 0) {
        ot_u16  scratch;
        vlFILE* fp;

        fp = ISF_open_su( ISF_ID(beacon_transmit_sequence) );
        if (fp == NULL) {
            return; //goto dll_systask_beacon_STOP;
        }
        if (fp->length == 0)    {
            vl_close(fp);
            return; //goto dll_systask_beacon_STOP;
        }

        // a little hack
        scratch     = fp->start;
        fp->start  += task->cursor;

        /// Beacon List Management:
        /// <LI> Move cursor onto next beacon period (above, +8)</LI>
        /// <LI> Loop cursor if it is past the length of the list </LI>
        /// <LI> In special case where cursor = 254, everything still works! </LI>
        task->cursor   += 8;
        task->cursor    = (task->cursor >= fp->length) ? 0 : task->cursor;

        // Load next beacon into btemp, then undo the start hack, then close
        vl_load(fp, 8, dll.netconf.btemp);
        fp->start = scratch;
        vl_close(fp);
    }

    // First 2 bytes: Chan ID, Cmd Code
    // - Setup beacon ad-hoc session, on specified channel (ad hoc sessions never return NULL)
    // - Assure cmd code is always Broadcast & Announcement
    b_session           = session_new(  &dll_beacon_applet, 0, dll.netconf.btemp[0],
                                        (M2_NETSTATE_INIT | M2_NETSTATE_REQTX | M2_NETFLAG_FIRSTRX)  );
    b_session->subnet   = dll.netconf.b_subnet;
    b_session->extra    = dll.netconf.btemp[1];
    b_session->flags    = dll.netconf.btemp[1] & 0x78;
    //b_session->flags   |= (b_session->extra & 0x30);

    // Last 2 bytes: Next Scan ticks
    sys_task_setnext(task, TI2CLK( PLATFORM_ENDIAN16(*(ot_u16*)&dll.netconf.btemp[6]) ));

    ///@note this might not be necessary or wise!
    //return;
    //dll_systask_beacon_STOP:
    //dll_idle();
}
Esempio n. 3
0
OT_WEAK void dll_systask_sleepscan(ot_task task) {
/// The Sleep Scan process runs as an independent task.  It is very similar
/// to the Hold Scan process, which actually calls this same routine.  They
/// use independent task markers, however, so they behave differently.
    ot_u8       s_channel;
    ot_u8       s_code;
    ot_uni16    scratch;
    vlFILE*     fp;
    m2session*  s_new;

    /// event = 0 is the initializer, but there is no state-based operation
    /// or any heap-stored data for this task, so it does nothing
    if (task->event == 0) {
        return;
    }

    fp = ISF_open_su( task->event );
    ///@note fp doesn't really need to be asserted unless you are mucking
    ///      with things in test builds.

    /// Pull channel ID and Scan flags
    scratch.ushort  = vl_read(fp, task->cursor);
    s_channel       = scratch.ubyte[0];
    s_code          = scratch.ubyte[1];

    /// Set the next idle event from the two-byte Next Scan field.
    /// The DASH7 registry is big-endian.
    scratch.ushort  = PLATFORM_ENDIAN16( vl_read(fp, (task->cursor)+=2 ) );
    sys_task_setnext(task, scratch.ushort);

    /// Advance cursor to next datum, go back to 0 if end of sequence
    /// (still works in special case where cursor = 254)
    task->cursor   += 2;
    task->cursor    = (task->cursor >= fp->length) ? 0 : task->cursor;
    vl_close(fp);

    /// Choosing Background-Scan or Foreground-Scan is based on scan-code.
    /// If b7 is set, do a Background-Scan.  At the session level, the "Flood"
    /// select uses b6, which is why there is a >> 1.
    s_new           = session_new(&dll_scan_applet, 0, s_channel,
                                    ((M2_NETSTATE_REQRX | M2_NETSTATE_INIT) | (s_code & 0x80) >> 1)  );
    s_new->extra    = s_code;
}
Esempio n. 4
0
/** DLL Systask RF I/O routines   <BR>
  * ========================================================================<BR>
  * These routines & subroutines are called from the dll_systack() function.
  * All of these routines interact with the Radio module & driver, which is an
  * interrupt-driven pre-emptive task.
  */
OT_WEAK void dll_init_rx(m2session* active) {
/// RX initialization is called by the session activation routine, and it is
/// often the result of an SSS or HSS invocation.  Scanning allows a 1 tick
/// latency for other tasks, although this could be potentially increased.
/// Background scans are very fast, and pending tasks will not be impacted
/// greatly by the strict latency requirement.  Foreground scans can last for
/// potentially long periods of time, however.  The latency, here, affects the
/// the request-response turnaround but not the radio RX process itself.
///
/// @todo A more adaptive method for scanning is planned, in which the latency
/// drops to 1 only after a sync word is detected.
    ot_sig2 callback;
    ot_u16  min_timeout;

    sys.task_RFA.event      = 3;
  //sys.task_RFA.reserved   = 10;   //un-necessary, RFA is max priority
    sys.task_RFA.latency    = (active->netstate & M2_NETSTATE_RESP) ? \
                                _RESPRX_LATENCY : _REQRX_LATENCY;

    min_timeout = rm2_rxtimeout_floor(active->channel);
    if (dll.comm.rx_timeout < min_timeout) {
        dll.comm.rx_timeout = min_timeout;
    }

	sys_task_setnext(&sys.task[TASK_radio], (ot_u16)dll.comm.rx_timeout);

    // E.g. lights a LED
    DLL_SIG_RFINIT(sys.task_RFA.event);

    //For synchronization test only
    //if ((active->netstate & M2_NETFLAG_BG) == 0) {
    //    sample_t1 = systim_chronstamp(&sample_t0);
    //    sample_t0 = 0;
    //}

    callback = (active->netstate & M2_NETFLAG_BG) ? \
                    &dll_rfevt_brx : &dll_rfevt_frx;

    rm2_rxinit(active->channel, active->netstate, callback);
}
Esempio n. 5
0
void ext_systask(ot_task task) {
    switch (task->event) {
        case 0: break;

        case 1: // break and deactivate task if switch is *not* being held-down
                if (PALFI_WAKE_PORT->DIN & BOARD_SW2_PIN) {
                    sys_task_setevent(task, 0);
                    break;
                }

        case 2: { // Add new DASH7 comm task to kernel, using most defaults.
            session_tmpl s_tmpl;
            sys_task_setevent(task, 1);
            sys_task_setnext(task, 512);

            s_tmpl.channel      = 7;
            s_tmpl.subnetmask   = 0;
            s_tmpl.flagmask     = 0;
            m2task_immediate(&s_tmpl, &applet_adcpacket);
        } break;
    }

}