Beispiel #1
0
/**@brief Process ANT message on ANT scanner
 *
 * @param[in] p_ant_event ANT message content.
 */
void continuous_scan_event_handler(ant_evt_t * p_ant_evt)
{
    uint32_t err_code;
    uint8_t  message_rssi;
    uint16_t message_device_number;

    ANT_MESSAGE * p_ant_message = (ANT_MESSAGE *) p_ant_evt->msg.evt_buffer;

    switch (p_ant_evt->event)
    {
        case EVENT_RX:
            if (p_ant_message->ANT_MESSAGE_aucPayload[0] == DEVICE_STATUS_PAGE)
            {
                LEDS_INVERT(BSP_LED_1_MASK);
                if (p_ant_message->ANT_MESSAGE_stExtMesgBF.bANTDeviceID &&
                    p_ant_message->ANT_MESSAGE_stExtMesgBF.bANTRssi)
                {
                    message_device_number =
                        (uint16_t)(p_ant_message->ANT_MESSAGE_aucExtData[0] |
                                   ((uint16_t)p_ant_message->ANT_MESSAGE_aucExtData[1] << 8));
                    message_rssi = p_ant_message->ANT_MESSAGE_aucExtData[5];
                    node_to_list_add(message_device_number, message_rssi);
                }
            }
            break;

        case EVENT_TRANSFER_TX_COMPLETED:
            LEDS_OFF(BSP_LED_0_MASK | BSP_LED_1_MASK);
            err_code = sd_ant_channel_close(ANT_SCAN_CHANNEL_NUMBER);
            APP_ERROR_CHECK(err_code);
            break;

        case EVENT_TRANSFER_TX_FAILED:
            if (m_retries > 0)
            {
                command_send();
                m_retries--;
            }
            else
            {
                LEDS_OFF(BSP_LED_0_MASK | BSP_LED_1_MASK);
                err_code = sd_ant_channel_close(ANT_SCAN_CHANNEL_NUMBER);
                APP_ERROR_CHECK(err_code);
            }
            break;

        default:
            break; // No implementation needed
    }
}
/**@brief Application's Stack BLE event handler.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 */
static void on_ble_evt(ble_evt_t * p_ble_evt)
{
    uint32_t err_code = NRF_SUCCESS;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            nrf_gpio_pin_set(CONNECTED_LED_PIN_NO);
            nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            break;
            
        case BLE_GAP_EVT_DISCONNECTED:
            nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO);
            m_conn_handle = BLE_CONN_HANDLE_INVALID;

            // Need to close the ANT channel to make it safe to write bonding information to flash
            err_code = sd_ant_channel_close(ANT_HRMRX_ANT_CHANNEL);
            APP_ERROR_CHECK(err_code);
            
            // Note: Bonding information will be stored, advertising will be restarted and the
            //       ANT channel will be reopened when ANT event CHANNEL_CLOSED is received.
            break;

#ifndef BONDING_ENABLE
        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            err_code = sd_ble_gap_sec_params_reply(m_conn_handle, 
                                                   BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, 
                                                   NULL);
#endif // BONDING_ENABLE
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GAP_EVT_TIMEOUT:
            if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT)
            { 
                nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO);
                
                // Go to system-off mode (this function will not return; wakeup will cause a reset)
                err_code = sd_power_system_off();
                APP_ERROR_CHECK(err_code);
            }
            break;

#ifndef	BONDING_ENABLE
            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
                APP_ERROR_CHECK(err_code);
                break;
#endif // BONDING_ENABLE
            
        default:
            // No implementation needed.
            break;
    }
}
/**@brief Sets the state machine to the specified state.
 */
static void ascmm_set_state(ascmm_states_t new_state)
{
    uint32_t err_code;

    if(new_state != m_state)
    {
        switch (new_state)
        {
            case ASCMM_OFF:
            {
                //Close the channel
                err_code = sd_ant_channel_close(m_discovery_channel_number);
                APP_ERROR_CHECK(err_code);
                break;
            }
            case DISCOVERY:
            {
                if (m_state != ASCMM_OFF)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }

                m_state = new_state;
                //Open the discovery channel
                err_code = sd_ant_channel_open(m_discovery_channel_number);

                break;
            }
            case CONNECTED:
            {
                if (m_state != DISCOVERY)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }
                m_state = new_state;

                //Close the channel
                err_code = sd_ant_channel_close(m_discovery_channel_number);
                APP_ERROR_CHECK(err_code);


                //Assign the connection channel
                err_code = sd_ant_channel_assign(m_ant_connected_parameters.channel_number,
                                                 m_ant_connected_parameters.channel_type,
                                                 m_ant_connected_parameters.network_number, 0);
                APP_ERROR_CHECK(err_code);

                //Set channel id
                err_code = sd_ant_channel_id_set (m_ant_connected_parameters.channel_number,
                                                  m_connection_device_number,
                                                  m_ant_connected_parameters.device_type,
                                                  m_ant_connected_parameters.tx_type);
                APP_ERROR_CHECK(err_code);

                //Set radio frequency
                err_code = sd_ant_channel_radio_freq_set (m_ant_connected_parameters.channel_number,
                                                          m_ant_connected_parameters.rf_frequency);
                APP_ERROR_CHECK(err_code);

                if(m_ant_connected_parameters.channel_type == CHANNEL_TYPE_SLAVE)
                {
                    //Configure search timeout for slave channel
                    err_code = sd_ant_channel_rx_search_timeout_set(m_ant_connected_parameters.channel_number,
                                                                    ASCMM_SEARCH_TIMEOUT);
                    APP_ERROR_CHECK(err_code);

                    err_code = sd_ant_channel_low_priority_rx_search_timeout_set(m_ant_connected_parameters.channel_number,
                                                                                 ASCMM_LP_SEARCH_TIMEOUT);
                    APP_ERROR_CHECK(err_code);
                }
                else
                {
                    // Configure Tx power for master chanel
                    err_code = sd_ant_channel_radio_tx_power_set(m_ant_connected_parameters.channel_number,
                                                                 m_ant_connected_parameters.tx_power, 0);
                    APP_ERROR_CHECK(err_code);
                }

                err_code = sd_ant_channel_open(m_ant_connected_parameters.channel_number);
                APP_ERROR_CHECK(err_code);

                break;
            }
            default:
            {
                //if the new state was not recognized, return to avoid setting the state changed event
                asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                return;
            }
        }
        asc_event_set(&m_asc_event_flags, EVENT_ASC_STATE_CHANGED);
    }
//lint --e{438}       
}
Beispiel #4
0
/**@brief Send command to node with highest RSSI.
 * If a global command was selected, send to all.
 */
static void send_command(void)
{
    uint16_t device_number = 0;
    uint8_t  max_rssi      = 0;
    uint32_t err_code;

    // Loop through nodes and pick highest rssi node
    for(int node = 0; node < MAX_DEVICES; node++)
    {
        if(m_node_list[node].device_number != 0)
        {
            if(m_node_list[node].rssi > max_rssi)
            {
                max_rssi = m_node_list[node].rssi;
                device_number = m_node_list[node].device_number;
            }
        }
    }

    // Do not send the command if no device was found
    // Close scanning channel and return
    if( device_number == 0 )
    {
        LEDS_ON(BSP_LED_2_MASK);
        LEDS_OFF(BSP_LED_0_MASK);
        err_code = sd_ant_channel_close(ANT_SCAN_CHANNEL_NUMBER);
        APP_ERROR_CHECK(err_code);
        return;
    }
    else
    {
        LEDS_OFF(BSP_LED_2_MASK);
    }

    err_code = sd_ant_channel_id_set(ANT_RESPONSE_CHANNEL_NUMBER,
                                     device_number,
                                     ANT_DEVICE_TYPE,
                                     ANT_TRANSMISSION_TYPE);
    APP_ERROR_CHECK(err_code);

    switch( m_command )
    {
        case COMMAND_STATE_ON:
            m_command = COMMAND_LIGHT_ON;
            break;

        case COMMAND_STATE_OFF:
            m_command = COMMAND_LIGHT_OFF;
            break;

        case COMMAND_STATE_ALL_ON:
            device_number = ADDRESS_ALL_NODES;
            m_command = COMMAND_LIGHT_ON;
            break;

        case COMMAND_STATE_ALL_OFF:
            device_number = ADDRESS_ALL_NODES;
            m_command = COMMAND_LIGHT_OFF;
            break;
        
        default:
            break;
    }

    m_tx_buffer[0] = MOBILE_COMMAND_PAGE;
    m_tx_buffer[1] = 0xFF;
    m_tx_buffer[2] = device_number;
    m_tx_buffer[3] = 0xFF;
    m_tx_buffer[4] = 0xFF;
    m_tx_buffer[5] = 0xFF;
    m_tx_buffer[6] = 0xFF;
    m_tx_buffer[7] = m_command;

    err_code = sd_ant_acknowledge_message_tx(ANT_RESPONSE_CHANNEL_NUMBER,
                                             ANT_STANDARD_DATA_PAYLOAD_SIZE,
                                             m_tx_buffer);
    APP_ERROR_CHECK(err_code);
}
/**@brief Sets the state machine to the applicable state
 */
static void set_state(connection_states_t new_state)
{
    uint32_t err_code;

    if(m_state != new_state)
    {
        switch(new_state)
        {
            case PHONE_OFF:
            {
                uint8_t channel_status;
                err_code = sd_ant_channel_status_get(m_channel_number, &channel_status);
                APP_ERROR_CHECK(err_code);

                m_state = new_state;

                switch(channel_status)
                {
                    case STATUS_SEARCHING_CHANNEL:
                        //Intentional fallthrough
                    case STATUS_TRACKING_CHANNEL:
                    {
                        err_code = sd_ant_channel_close(m_channel_number);
                        APP_ERROR_CHECK(err_code);
                    } //Intentional fallthrough
                    case STATUS_ASSIGNED_CHANNEL:
                    {
                        err_code = sd_ant_channel_unassign(m_channel_number);
                        APP_ERROR_CHECK(err_code);
                        break;
                    }
                    default:
                    {
                        return;
                    }
                }
                break;
            }
            case PHONE_ON:
            {
                //uint32_t err_code;
                if(m_state == PHONE_OFF)
                {
                    //Open the channel
                    err_code = sd_ant_channel_open(m_channel_number);
                    APP_ERROR_CHECK(err_code);
                }

                m_state = new_state;

                //Prepare the buffer
                asc_encode_device_availability_page(m_neighbor_id, m_tx_buffer);
                err_code = sd_ant_broadcast_message_tx (m_channel_number, ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer);
                APP_ERROR_CHECK(err_code);
                break;
            }
            default:
            {
                return;
            }
        }
    }
}
Beispiel #6
0
/**@brief Sets the state machine to the specified state.
 */
static void ascs_set_state(ascs_states_t new_state)
{
    uint32_t err_code;

    if(m_state != new_state)
    {
        switch (new_state)
        {
            case OFF:
            {
                m_state = new_state;
                err_code = sd_ant_channel_close(m_channel_number);
                APP_ERROR_CHECK(err_code);
                break;
            }
            case SEARCHING:
            {
                //Check if we need to re-open the channel
                if (m_state == OFF)
                {
                    //Open slave channel
                    err_code = sd_ant_channel_open(m_channel_number);
                    APP_ERROR_CHECK(err_code);
                }

                m_state = new_state;
                m_groups_assigned = NO_GROUPS;
                m_shared_address = SEARCH_ADDRESS;
                asc_encode_set_shared_address(m_shared_address, m_tx_buffer);
                err_code = sd_ant_broadcast_message_tx (m_channel_number,  ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer);
                APP_ERROR_CHECK(err_code);
                break;
            }
            case REQUESTING:
            {
                if(m_state != SEARCHING)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }
                m_state = new_state;
                asc_encode_request_address_page(m_serial_number, m_tx_buffer);
                err_code = sd_ant_acknowledge_message_tx(m_channel_number,  ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer);
                APP_ERROR_CHECK(err_code);

                break;
            }
            case WAITING:
            {
                if(m_state != REQUESTING)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }
                m_state = new_state;
                m_shared_address = REGISTER_ADDRESS;
                asc_encode_set_shared_address(m_shared_address, m_tx_buffer);
                err_code = sd_ant_broadcast_message_tx (m_channel_number,  ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer);
                APP_ERROR_CHECK(err_code);
                break;
            }
            case CONFIRMING:
            {
                if(m_state != WAITING)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }
                m_state = new_state;
                m_timeout_counter = 0;
                asc_confirm_acquire_paramters_t params = {
                    .serial_number = m_serial_number,
                    .model_number = MODEL_NUMBER,
                    .hw_revision = HW_REVISION,
                    .sw_revision = SW_REVISION
                };
                asc_encode_confirm_acquire_page(params, m_tx_buffer);
                err_code = sd_ant_acknowledge_message_tx(m_channel_number,  ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer);
                APP_ERROR_CHECK(err_code);
                break;
            }
            case ASSIGNED:
            {
                if(m_state != CONFIRMING)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }
                ascs_states_t previous_state = m_state;
                m_state = new_state;
                m_timeout_counter = 0;
                if(previous_state == CONFIRMING)
                {
                    asc_encode_set_shared_address(m_shared_address, m_tx_buffer);
                    err_code = sd_ant_broadcast_message_tx (m_channel_number,  ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer);
                    APP_ERROR_CHECK(err_code);
                }
                break;
            }
            default:
            {
                asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                return;
            }
        }
        asc_event_set(&m_asc_event_flags, EVENT_ASC_STATE_CHANGED);
    }
}
Beispiel #7
0
/**@brief Sets the state machine to the specified state.
 */
static void ascm_set_state(ascm_states_t new_state)
{
    uint32_t err_code;

    if (new_state != m_state)
    {
        switch (new_state)
        {
            case ASCM_OFF:
            {
                //Close the channel
                m_previous_state = m_state;
                m_state = new_state;
                err_code = sd_ant_channel_close(m_channel_number);
                APP_ERROR_CHECK(err_code);
                break;
            }
            case ADDRESS_AVAILABLE:
            {
                if (m_state == ASCM_OFF)
                {
                    //Open the channel
                    err_code = sd_ant_channel_open(m_channel_number);
                    APP_ERROR_CHECK(err_code);
                }
                m_previous_state = m_state;
                m_state = new_state;
                m_is_address_available = !deviceregistry_is_full(pm_device_registry);
                ascm_send_address_available_page();
                break;
            }
            case HANDSHAKING:
            {
                if (m_state != ADDRESS_AVAILABLE)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }

                m_previous_state = m_state;
                m_state = new_state;
                //there is no need to check for validity of this shared address, as there must be a free address available
                //to be in the handshaking state at all.
                m_handshaking_device.shared_address = deviceregistry_get_next_free_shared_address(pm_device_registry);
                m_msg_counter_handshaking = 0;
                ascm_send_busy_acquiring_page();
                break;
            }
            case POLLING:
            {
                if (m_state != ADDRESS_AVAILABLE && m_state != SENDING_COMMAND)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }

                m_previous_state = m_state;
                m_state = new_state;

                //If the previous state was not SENDING_COMMAND, start from the beginning of the polling cycle.
                //Otherwise, allow the process_message handler to finish the cycle
                if (m_previous_state != SENDING_COMMAND)
                {
                    m_current_shared_address_polling = deviceregistry_get_first_registered_shared_address(pm_device_registry);
                    if (m_current_shared_address_polling != INVALID_SHARED_ADDRESS)
                    {
                        m_msg_counter_polling = 0;
                        send_polling_message();
                    }
                    else
                    {
                        //no devices are registered, go back to address available
                        ascm_set_state(ADDRESS_AVAILABLE);
                    }
                }
                break;
            }
            case SENDING_COMMAND:
            {
                //Only allow sending commands if the device is in the
                //Address available or polling states
                if (m_state != ADDRESS_AVAILABLE && m_state != POLLING)
                {
                    asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                    return;
                }

                m_previous_state = m_state;
                m_state = new_state;
                m_msg_counter_sending_command = 0;

                break;
            }
            default:
            {
                //if the new state was not recognized, return to avoid setting the state changed event
                asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE);
                return;
            }
        }
        asc_event_set(&m_asc_event_flags, EVENT_ASC_STATE_CHANGED);
    }
}