Exemplo n.º 1
0
/*
 * led_func() - Set LED states
 *
 * INPUT
 *     - act: led action
 * OUTPUT
 *     none
 */
void led_func(LedAction act)
{
#ifndef EMULATOR
    switch(act)
    {
        case CLR_GREEN_LED:
            SET_PIN(GREEN_LED);
            break;

        case SET_GREEN_LED:
            CLEAR_PIN(GREEN_LED);
            break;

        case TGL_GREEN_LED:
            TOGGLE_PIN(GREEN_LED);
            break;

        case CLR_RED_LED:
            SET_PIN(RED_LED);
            break;

        case SET_RED_LED:
            CLEAR_PIN(RED_LED);
            break;

        case TGL_RED_LED:
            TOGGLE_PIN(RED_LED);
            break;

        default:
            /* No action */
            break;
    }
#endif
}
static bool event_fifo_pop(fifo_t* evt_fifo)
{
    SET_PIN(PIN_SWI0);
    async_event_t evt;
    uint32_t error_code = fifo_pop(evt_fifo, &evt);
    if (error_code == NRF_SUCCESS)
    {
        async_event_execute(&evt);
        CLEAR_PIN(PIN_SWI0);
        return true;
    }
    CLEAR_PIN(PIN_SWI0);
    return false;
}
Exemplo n.º 3
0
/**
* @brief Handle incoming packets
*/
static void search_callback(uint8_t* data)
{
    SET_PIN(PIN_RX);

    uint32_t checksum = (NRF_RADIO->RXCRC & 0x00FFFFFF);

    /* check if timeslot is about to end */
    uint64_t radio_time_left = timeslot_get_remaining_time();

    if (radio_time_left > RADIO_SAFETY_TIMING_US)
    {
        /* setup next RX */
        order_search();
    }

    CLEAR_PIN(PIN_RX);

    if (data == NULL || !packet_is_data_packet(data))
    {
        return;
    }


    async_event_t async_evt;
    async_evt.type = EVENT_TYPE_PACKET;
    packet_create_from_data(data, &async_evt.callback.packet);
    async_evt.callback.packet.rx_crc = checksum;
    event_handler_push(&async_evt);


    /** @TODO: add packet chain handling */
}
Exemplo n.º 4
0
/* packet processing, executed in APP_LOW */
void tc_packet_handler(uint8_t* data, uint32_t crc, uint64_t timestamp)
{
//	LOGi("_6");
    SET_PIN(PIN_RX);
    mesh_packet_t* p_packet = (mesh_packet_t*) data;
//	printArray(p_packet, sizeof(mesh_packet_t));

    if (p_packet->header.length > MESH_PACKET_OVERHEAD + RBC_MESH_VALUE_MAX_LEN)
    {
//    	LOGi("_2");
        /* invalid packet, ignore */
        CLEAR_PIN(PIN_RX);
        mesh_packet_ref_count_dec(p_packet); /* from rx_cb */
        return;
    }
    
    ble_gap_addr_t addr;
    memcpy(addr.addr, p_packet->addr, BLE_GAP_ADDR_LEN);
    addr.addr_type = p_packet->header.addr_type;
    
    mesh_adv_data_t* p_mesh_adv_data = mesh_packet_adv_data_get(p_packet);
    
    
    if (p_mesh_adv_data != NULL)
    {
//    	LOGi("_3");
        /* filter mesh packets on handle range */
        if (p_mesh_adv_data->handle <= RBC_MESH_APP_MAX_HANDLE)
        {
//        	LOGi("_4");
            mesh_app_packet_handle(p_mesh_adv_data, timestamp);
        }
    }
    
    /* this packet is no longer needed in this context */
    mesh_packet_ref_count_dec(p_packet); /* from rx_cb */

    if (g_state.queue_saturation)
    {
//    	LOGi("_5");
        order_search();
        g_state.queue_saturation = false;
    }
    
    CLEAR_PIN(PIN_RX);
}
Exemplo n.º 5
0
/** Initialize the pins needed for the communication with D12.
 **/
void d12_pins_init(void) {
  INIT_PIN_OUTPUT(A0_PORT, A0_PIN);
  INIT_PIN_OUTPUT(RD_PORT, RD_PIN);
  INIT_PIN_OUTPUT(WR_PORT, WR_PIN);
  INIT_PIN_OUTPUT(SUSPEND_PORT, SUSPEND_PIN);

  INIT_PIN_INPUT(IRQ_PORT, IRQ_PIN);
  CLEAR_PIN(IRQ_PORT, IRQ_PIN);
}
Exemplo n.º 6
0
/**
* @brief Timeslot related events callback
*   Called whenever the softdevice tries to change the original course of actions 
*   related to the timeslots
*/
void ts_sd_event_handler(void)
{
    uint32_t evt;
    SET_PIN(6);
    while (sd_evt_get(&evt) == NRF_SUCCESS)
    {
        PIN_OUT(evt, 32);
        switch (evt)
        {
            case NRF_EVT_RADIO_SESSION_IDLE:

                timeslot_order_earliest(TIMESLOT_SLOT_LENGTH, true);
                break;

            case NRF_EVT_RADIO_SESSION_CLOSED:
                APP_ERROR_CHECK(NRF_ERROR_INVALID_DATA);

                break;

            case NRF_EVT_RADIO_BLOCKED:
                /* something in the softdevice is blocking our requests, 
                go into emergency mode, where slots are short, in order to 
                avoid complete lockout */
                timeslot_order_earliest(TIMESLOT_SLOT_EMERGENCY_LENGTH, true);
                break;

            case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
                APP_ERROR_CHECK(NRF_ERROR_INVALID_DATA);
                break;

            case NRF_EVT_RADIO_CANCELED:
                timeslot_order_earliest(TIMESLOT_SLOT_LENGTH, true);
                break;
            default:
                APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE);
        }
    }
    CLEAR_PIN(6);
}
/**
* @brief Timeslot related events callback
*   Called whenever the softdevice tries to change the original course of actions
*   related to the timeslots
*/
void ts_sd_event_handler(uint32_t evt)
{
    SET_PIN(PIN_SD_EVT_HANDLER);
    switch (evt)
    {
        case NRF_EVT_RADIO_SESSION_IDLE:
            /* the idle event is usually triggered when rbc_mesh_stop is called,
                but if this isn't the case, we have to restart the TS */
            if (g_timeslot_forced_command != TS_FORCED_COMMAND_STOP)
            {
                timeslot_order_earliest(TIMESLOT_SLOT_LENGTH, true);
            }
            break;

        case NRF_EVT_RADIO_SESSION_CLOSED:
            APP_ERROR_CHECK(NRF_ERROR_INVALID_DATA);

            break;

        case NRF_EVT_RADIO_BLOCKED:
            /* something in the softdevice is blocking our requests,
            go into emergency mode, where slots are short, in order to
            avoid complete lockout */
            timeslot_order_earliest(TIMESLOT_SLOT_EMERGENCY_LENGTH, true);
            break;

        case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
            APP_ERROR_CHECK(NRF_ERROR_INVALID_DATA);
            break;

        case NRF_EVT_RADIO_CANCELED:
            timeslot_order_earliest(TIMESLOT_SLOT_LENGTH, true);
            break;
        default:
            break;
    }
    CLEAR_PIN(PIN_SD_EVT_HANDLER);
}
Exemplo n.º 8
0
/**
* @brief Radio signal callback handler taking care of all signals in searching 
*   mode
*/
static nrf_radio_signal_callback_return_param_t* radio_signal_callback(uint8_t sig)
{
    g_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
    g_is_in_callback = true;
    static uint32_t requested_extend_time = 0;
    static uint32_t successful_extensions = 0;
    static uint64_t last_rtc_value = 0;
    //static uint8_t noise_val = 0x5F;
    SET_PIN(PIN_SYNC_TIME);

    static uint64_t time_now = 0;

    switch (sig)
    {
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
        {
            NVIC_ClearPendingIRQ(SWI0_IRQn);
            g_is_in_timeslot = true;

            event_fifo_flush();
            timer_init();
            SET_PIN(2);
            successful_extensions = 0;

            g_negotiate_timeslot_length = g_timeslot_length;

            g_timeslot_length = g_next_timeslot_length;

            g_timeslot_end_timer = 
                timer_order_cb_sync_exec(g_timeslot_length - TIMESLOT_END_SAFETY_MARGIN_US, 
                    end_timer_handler);


            /* attempt to extend our time right away */
            timeslot_extend(g_negotiate_timeslot_length);

#if USE_SWI_FOR_PROCESSING
            NVIC_EnableIRQ(SWI0_IRQn);
            NVIC_SetPriority(SWI0_IRQn, 3);
#endif

            /* sample RTC timer for trickle timing */
            uint32_t rtc_time = NRF_RTC0->COUNTER;

            /*First time the offset should be added*/
            if(last_rtc_value == 0)
            {
                last_rtc_value = g_start_time_ref;
            }

            /* Calculate delta rtc time */
            uint64_t delta_rtc_time;
            if(last_rtc_value > rtc_time)
            {
                delta_rtc_time = 0xFFFFFF - last_rtc_value + rtc_time;
            }
            else
            {
                delta_rtc_time = rtc_time - last_rtc_value;
            }
            /* Store last rtc time */
            last_rtc_value = rtc_time;


            /* scale to become us */
            time_now += ((delta_rtc_time << 15) / 1000);

            transport_control_timeslot_begin(time_now);
            break;
        }
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
            /* send to radio control module */
            TICK_PIN(PIN_RADIO_SIGNAL);
            radio_event_handler();
            break;

        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
            /* send to timer control module */
            TICK_PIN(PIN_TIMER_SIGNAL);
            timer_event_handler();
            break;

        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
            g_timeslot_length += requested_extend_time;
            requested_extend_time = 0;
            ++successful_extensions;
            g_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;

            timer_abort(g_timeslot_end_timer);

            g_timeslot_end_timer = 
                timer_order_cb_sync_exec(g_timeslot_length - TIMESLOT_END_SAFETY_MARGIN_US, 
                    end_timer_handler);

            TICK_PIN(1);
            if (g_timeslot_length + g_negotiate_timeslot_length < TIMESLOT_MAX_LENGTH)
            {
                timeslot_extend(g_negotiate_timeslot_length);   
            }
            else
            {
                /* done extending, check for new trickle event */
                transport_control_step();
            }

            break;

        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:
            g_negotiate_timeslot_length >>= 2;
            TICK_PIN(1);
            if (g_negotiate_timeslot_length > 1000)
            {
                timeslot_extend(g_negotiate_timeslot_length);
            }
            else
            {
                /* done extending, check for new trickle event */
                transport_control_step();
            }
            break;

        default:
            APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE);
    }


    g_is_in_callback = false;
    if (g_ret_param.callback_action == NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND)
    {
        requested_extend_time = g_ret_param.params.extend.length_us;
    }
    else if (g_ret_param.callback_action == NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END)
    {
        CLEAR_PIN(2);
        g_is_in_timeslot = false;
        event_fifo_flush();
    }
    else
    {
        requested_extend_time = 0;
    }

    CLEAR_PIN(PIN_SYNC_TIME);
    return &g_ret_param;
}
Exemplo n.º 9
0
void LED_INIT() { vAHI_DioSetDirection(0, 1 << 2); vAHI_DioSetDirection(0, 1 << 3); vAHI_DioSetDirection(0, 1 << 16); vAHI_DioSetDirection(0, 1 << 17); CLEAR_PIN(16); CLEAR_PIN(17); }
Exemplo n.º 10
0
void LEDS_OFF() { CLEAR_PIN(2); CLEAR_PIN(3); CLEAR_PIN(17); }
Exemplo n.º 11
0
/**
* @brief Radio signal callback handler taking care of all signals in searching
*   mode
*/
static nrf_radio_signal_callback_return_param_t* radio_signal_callback(uint8_t sig)
{
    static uint32_t requested_extend_time = 0;
    static uint32_t successful_extensions = 0;
    static uint32_t timeslot_count = 0;

    if (sig == NRF_RADIO_CALLBACK_SIGNAL_TYPE_START)
    {
        g_timeslot_forced_command = TS_FORCED_COMMAND_NONE;
    }
    else /* on forced command */
    {
        switch (g_timeslot_forced_command)
        {
            case TS_FORCED_COMMAND_STOP:
                g_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_END;
                g_is_in_timeslot = false;
                g_end_timer_triggered = false;
                CLEAR_PIN(PIN_IN_TS);
                event_handler_on_ts_end();
                timeslot_count = 0;
                return &g_ret_param;

            case TS_FORCED_COMMAND_RESTART:
                timeslot_order_earliest(TIMESLOT_SLOT_LENGTH, true);
                g_is_in_timeslot = false;
                g_end_timer_triggered = false;
                CLEAR_PIN(PIN_IN_TS);
                event_handler_on_ts_end();
                radio_disable();

                return &g_ret_param;

            default:
                break;
        }
    }

    g_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
    g_is_in_callback = true;

    SET_PIN(PIN_IN_CB);

    switch (sig)
    {
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
        {
            SET_PIN(PIN_IN_TS);
            g_is_in_timeslot = true;
            g_end_timer_triggered = false;
            successful_extensions = 0;

            if (timeslot_count > 0)
            {
                global_time_update();
            }
            mesh_packet_on_ts_begin();
            event_handler_on_ts_begin();
            timer_on_ts_begin();
            tc_on_ts_begin();

            g_negotiate_timeslot_length = TIMESLOT_SLOT_EXTEND_LENGTH;
            g_timeslot_length = g_next_timeslot_length;

            timer_order_cb_sync_exec(TIMER_INDEX_TS_END, g_timeslot_length - end_timer_margin(),
                    end_timer_handler);

            /* attempt to extend our time right away */
            timeslot_extend(g_negotiate_timeslot_length);

            /* increase timeslot-count, but skip =0 on rollover */
            if (!++timeslot_count)
            {
                timeslot_count++;
            }

            break;
        }
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
            /* send to radio control module */
            SET_PIN(PIN_RADIO_SIGNAL);
            radio_event_handler();
            CLEAR_PIN(PIN_RADIO_SIGNAL);
            break;

        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
            /* send to timer control module */
            SET_PIN(PIN_TIMER_SIGNAL);
            timer_event_handler();
            CLEAR_PIN(PIN_TIMER_SIGNAL);
            break;

        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
            g_timeslot_length += requested_extend_time;
            requested_extend_time = 0;
            ++successful_extensions;

            timer_abort(TIMER_INDEX_TS_END);

            timer_order_cb_sync_exec(TIMER_INDEX_TS_END, g_timeslot_length - end_timer_margin(),
                    end_timer_handler);

            g_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;

            TICK_PIN(PIN_EXTENSION_OK);
            if (g_timeslot_length + g_negotiate_timeslot_length < TIMESLOT_MAX_LENGTH)
            {
                timeslot_extend(g_negotiate_timeslot_length);
            }
            else
            {
                /* done extending, check for new trickle event */
                vh_on_timeslot_begin();
            }

            break;

        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:
            g_negotiate_timeslot_length >>= 1;
            TICK_PIN(PIN_EXTENSION_FAIL);
            if (g_negotiate_timeslot_length > 1000)
            {
                timeslot_extend(g_negotiate_timeslot_length);
            }
            else
            {
                /* done extending, check for new trickle event */
                vh_on_timeslot_begin();
            }
            break;

        default:
            APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE);
    }



    if (g_end_timer_triggered)
    {
        timeslot_order_earliest(TIMESLOT_SLOT_LENGTH, true);
        g_is_in_timeslot = false;
        g_end_timer_triggered = false;
        CLEAR_PIN(PIN_IN_TS);
        event_handler_on_ts_end();
        radio_disable();
        timer_on_ts_end();
    }
    else if (g_ret_param.callback_action == NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND)
    {
        requested_extend_time = g_ret_param.params.extend.length_us;
    }
    else
    {
        requested_extend_time = 0;
    }
    g_is_in_callback = false;

    CLEAR_PIN(PIN_IN_CB);
    return &g_ret_param;
}