ANTStatus ant_init(void)
{
   ANTStatus status = ANT_STATUS_FAILED;
   ANT_FUNC_START();

   stRxThreadInfo.stRxThread = 0;
   stRxThreadInfo.ucRunThread = 0;
   stRxThreadInfo.ucChipResetting = 0;
   stRxThreadInfo.pstEnabledStatusLock = &stEnabledStatusLock;
   g_fnStateCallback = 0;

#ifdef ANT_DEVICE_NAME // Single transport path
   ant_channel_init(&stRxThreadInfo.astChannels[SINGLE_CHANNEL], ANT_DEVICE_NAME);
#else // Separate data/command paths
   ant_channel_init(&stRxThreadInfo.astChannels[COMMAND_CHANNEL], ANT_COMMANDS_DEVICE_NAME);
   ant_channel_init(&stRxThreadInfo.astChannels[DATA_CHANNEL], ANT_DATA_DEVICE_NAME);
#endif // Separate data/command paths

   // Make the eventfd. Want it non blocking so that we can easily reset it by reading.
   stRxThreadInfo.iRxShutdownEventFd = eventfd(0, EFD_NONBLOCK);

   // Check for error case
   if(stRxThreadInfo.iRxShutdownEventFd == -1)
   {
      ANT_ERROR("ANT init failed. Could not create event fd. Reason: %s", strerror(errno));
   } else {
      status = ANT_STATUS_SUCCESS;
   }

   ANT_FUNC_END();
   return status;
}
Example #2
0
uint32_t ant_hrm_init(ant_hrm_profile_t * p_profile, ant_channel_config_t const * p_channel_config,
                      ant_hrm_tx_config_t const * p_tx_config)
{
    ASSERT(p_profile != NULL);
    ASSERT(p_channel_config != NULL);

    p_profile->channel_number = p_channel_config->channel_number;

    if (p_tx_config != NULL)
    {
        p_profile->p_cb           = p_tx_config->p_cb_buffer;
        ant_hrm_tx_cb_t * p_hrm_cb   = (ant_hrm_tx_cb_t *)p_profile->p_cb;

        p_hrm_cb->page_1_present = p_tx_config->page_1_present;

        ASSERT((p_tx_config->main_page_number == ANT_HRM_PAGE_0) || (p_tx_config->main_page_number == ANT_HRM_PAGE_4));
        p_hrm_cb->main_page_number  = p_tx_config->main_page_number;

        p_hrm_cb->ext_page_number = p_hrm_cb->page_1_present ? ANT_HRM_PAGE_1 : ANT_HRM_PAGE_2;
        p_hrm_cb->message_counter = 0;
        p_hrm_cb->toggle_bit      = true;
    }

    p_profile->page_0 = (ant_hrm_page0_data_t)DEFAULT_ANT_HRM_PAGE0();
    p_profile->page_1 = (ant_hrm_page1_data_t)DEFAULT_ANT_HRM_PAGE1();
    p_profile->page_2 = (ant_hrm_page2_data_t)DEFAULT_ANT_HRM_PAGE2();
    p_profile->page_3 = (ant_hrm_page3_data_t)DEFAULT_ANT_HRM_PAGE3();
    p_profile->page_4 = (ant_hrm_page4_data_t)DEFAULT_ANT_HRM_PAGE4();

    LOG_ANT("ANT HRM channel %u init\n\r", p_profile->channel_number);
    return ant_channel_init(p_channel_config);
}
Example #3
0
File: main.c Project: IOIOI/nRF51
/**@brief Function for setting up the ANT module to be ready for TX broadcast.
 */
static void ant_channel_tx_broadcast_setup(void)
{
    uint32_t err_code;

    ant_channel_config_t broadcast_channel_config =
    {
        .channel_number    = ANT_BROADCAST_CHANNEL_NUMBER,
        .channel_type      = CHANNEL_TYPE_MASTER_TX_ONLY,
        .ext_assign        = EXT_ASSIGN_NONE,
        .rf_freq           = ANT_FREQUENCY,
        .transmission_type = ANT_BROADCAST_TRANSMISSION_TYPE,
        .device_type       = ANT_BROADCAST_DEVICE_TYPE,
        .device_number     = ANT_BROADCAST_DEVICE_NUMBER,
        .channel_period    = ANT_CHANNEL_PERIOD,
        .network_number    = ANT_NETWORK_NUMBER,
    };

    err_code = ant_channel_init(&broadcast_channel_config);
    APP_ERROR_CHECK(err_code);

    // Fill tx buffer for the first frame.
    ant_message_send();

    // Open channel.
    err_code = sd_ant_channel_open(ANT_BROADCAST_CHANNEL_NUMBER);
    APP_ERROR_CHECK(err_code);
}
Example #4
0
void ant_io_tx_setup(void)
{
    uint32_t err_code;

    ant_channel_config_t channel_config =
    {
        .channel_number     = ANT_CHANNEL_NUMBER,
        .channel_type       = CHANNEL_TYPE_MASTER,
        .ext_assign         = EXT_ASSIGN,
        .rf_freq            = RF_FREQUENCY,
        .transmission_type  = CHAN_ID_TRANS_TYPE,
        .device_type        = CHAN_ID_DEV_TYPE,
        .device_number      = CHAN_ID_DEV_NUM,
        .channel_period     = CHANNEL_PERIOD,
        .network_number     = ANT_CHANNEL_DEFAULT_NETWORK,
    };

    // Configure channel parameters
    err_code = ant_channel_init(&channel_config);
    APP_ERROR_CHECK(err_code);

    // Open channel.
    err_code = sd_ant_channel_open(ANT_CHANNEL_NUMBER);
    APP_ERROR_CHECK(err_code);
}
Example #5
0
void ant_io_rx_setup(void)
{
    uint32_t err_code;

    ant_channel_config_t channel_config =
    {
        .channel_number     = ANT_CHANNEL_NUMBER,
        .channel_type       = CHANNEL_TYPE_SLAVE,
        .ext_assign         = EXT_ASSIGN,
        .rf_freq            = RF_FREQUENCY,
        .transmission_type  = CHAN_ID_TRANS_TYPE,
        .device_type        = CHAN_ID_DEV_TYPE,
        .device_number      = CHAN_ID_DEV_NUM,
        .channel_period     = CHANNEL_PERIOD,
        .network_number     = ANT_CHANNEL_DEFAULT_NETWORK,
    };

    ant_search_config_t search_config  = DEFAULT_ANT_SEARCH_CONFIG(ANT_CHANNEL_NUMBER);
    search_config.low_priority_timeout = ANT_LOW_PRIORITY_TIMEOUT_DISABLE;

    // Configure channel parameters
    err_code = ant_channel_init(&channel_config);
    APP_ERROR_CHECK(err_code);

    // Configure search
    err_code = ant_search_init(&search_config);
    APP_ERROR_CHECK(err_code);

    // Open channel.
    err_code = sd_ant_channel_open(ANT_CHANNEL_NUMBER);
    APP_ERROR_CHECK(err_code);
}
Example #6
0
/**@brief Function for initializing the ANT HRM profile instance.
 *
 * @param[in]  p_profile        Pointer to the profile instance.
 * @param[in]  p_channel_config Pointer to the ANT channel configuration structure.
 *
 * @retval     NRF_SUCCESS      If initialization was successful. Otherwise, an error code is returned.
 */
static ret_code_t ant_hrm_init(ant_hrm_profile_t          * p_profile,
                             ant_channel_config_t const * p_channel_config)
{
    p_profile->channel_number = p_channel_config->channel_number;

    p_profile->page_0 = DEFAULT_ANT_HRM_PAGE0();
    p_profile->page_1 = DEFAULT_ANT_HRM_PAGE1();
    p_profile->page_2 = DEFAULT_ANT_HRM_PAGE2();
    p_profile->page_3 = DEFAULT_ANT_HRM_PAGE3();
    p_profile->page_4 = DEFAULT_ANT_HRM_PAGE4();

    NRF_LOG_INFO("ANT HRM channel %u init\r\n", p_profile->channel_number);
    return ant_channel_init(p_channel_config);
}
Example #7
0
/**@brief Function for initializing the ANT Bicycle Power Profile instance.
 *
 * @param[in]  p_profile        Pointer to the profile instance.
 * @param[in]  p_channel_config Pointer to the ANT channel configuration structure.
 *
 * @retval     NRF_SUCCESS      If initialization was successful. Otherwise, an error code is returned.
 */
static ret_code_t ant_bpwr_init(ant_bpwr_profile_t         * p_profile,
                                ant_channel_config_t const * p_channel_config)
{
    p_profile->channel_number = p_channel_config->channel_number;

    p_profile->page_1  = DEFAULT_ANT_BPWR_PAGE1();
    p_profile->page_16 = DEFAULT_ANT_BPWR_PAGE16();
    p_profile->page_17 = DEFAULT_ANT_BPWR_PAGE17();
    p_profile->page_18 = DEFAULT_ANT_BPWR_PAGE18();
    p_profile->page_80 = DEFAULT_ANT_COMMON_page80();
    p_profile->page_81 = DEFAULT_ANT_COMMON_page81();

    LOG_BPWR("ANT B-PWR channel %u init\n\r", p_profile->channel_number);
    return ant_channel_init(p_channel_config);
}
Example #8
0
/**@brief Function for initializing the ANT SDM profile instance.
 *
 * @param[in]  p_profile        Pointer to the profile instance.
 * @param[in]  p_channel_config Pointer to the ANT channel configuration structure.
 *
 * @retval     NRF_SUCCESS      Successful initialization.
 *             Error code when initialization failed.
 */
static ret_code_t ant_sdm_init(ant_sdm_profile_t          * p_profile,
                               ant_channel_config_t const * p_channel_config)
{
    p_profile->channel_number = p_channel_config->channel_number;

    p_profile->page_1  = DEFAULT_ANT_SDM_PAGE1();
    p_profile->page_2  = DEFAULT_ANT_SDM_PAGE2();
    p_profile->page_3  = DEFAULT_ANT_SDM_PAGE3();
    p_profile->page_22 = DEFAULT_ANT_SDM_PAGE22();
    p_profile->common  = DEFAULT_ANT_SDM_COMMON_DATA();
    p_profile->page_80 = DEFAULT_ANT_COMMON_page80();
    p_profile->page_81 = DEFAULT_ANT_COMMON_page81();

    LOG_SDM("ANT SDM channel %u init\n\r", p_profile->channel_number);
    return ant_channel_init(p_channel_config);
}
Example #9
0
/**@brief Function for initializing the ANT BSC profile instance.
 *
 * @param[in]  p_profile        Pointer to the profile instance.
 * @param[in]  p_channel_config Pointer to the ANT channel configuration structure.
 *
 * @retval     NRF_SUCCESS      If initialization was successful. Otherwise, an error code is returned.
 */
static ret_code_t ant_bsc_init(ant_bsc_profile_t          * p_profile,
                               ant_channel_config_t const * p_channel_config)
{
    p_profile->channel_number = p_channel_config->channel_number;

    p_profile->page_0       = DEFAULT_ANT_BSC_PAGE0();
    p_profile->page_1       = DEFAULT_ANT_BSC_PAGE1();
    p_profile->page_2       = DEFAULT_ANT_BSC_PAGE2();
    p_profile->page_3       = DEFAULT_ANT_BSC_PAGE3();
    p_profile->page_4       = DEFAULT_ANT_BSC_PAGE4();
    p_profile->page_5       = DEFAULT_ANT_BSC_PAGE5();
    p_profile->page_comb_0  = DEFAULT_ANT_BSC_COMBINED_PAGE0();

    LOG_BSC("ANT BSC channel %u init\n\r", p_profile->channel_number);
    return ant_channel_init(p_channel_config);
}
Example #10
0
/**@brief Function for setting up the ANT module to be ready for RX broadcast.
 */
static void ant_channel_rx_broadcast_setup(void)
{
    uint32_t err_code;

    ant_channel_config_t broadcast_channel_config =
    {
        .channel_number    = ANT_BROADCAST_CHANNEL_NUMBER,
        .channel_type      = CHANNEL_TYPE_SLAVE,
        .ext_assign        = EXT_ASSIGN_NONE,
        .rf_freq           = RF_FREQ,
        .transmission_type = CHAN_ID_TRANS_TYPE,
        .device_type       = CHAN_ID_DEV_TYPE,
        .device_number     = CHAN_ID_DEV_NUM,
        .channel_period    = CHAN_PERIOD,
        .network_number    = ANT_NETWORK_NUMBER,
    };

    err_code = ant_channel_init(&broadcast_channel_config);
    APP_ERROR_CHECK(err_code);

    // Open channel.
    err_code = sd_ant_channel_open(ANT_BROADCAST_CHANNEL_NUMBER);
    APP_ERROR_CHECK(err_code);
}
Example #11
0
File: main.c Project: IOIOI/nRF51
/**@brief initialize application
 */
static void continuous_scan_init()
{
    uint32_t err_code;

    // Set library config to report RSSI and Device ID
    err_code = sd_ant_lib_config_set(ANT_LIB_CONFIG_MESG_OUT_INC_RSSI | ANT_LIB_CONFIG_MESG_OUT_INC_DEVICE_ID);
    APP_ERROR_CHECK(err_code);
    
    // Configure channel 0 for scanning mode, but do not open it.
    // The scanning channel will be opened in scan mode for a short amount of time on a button press.
    ant_channel_config_t channel_config =
    {
        .channel_number     = ANT_SCAN_CHANNEL_NUMBER,
        .channel_type       = ANT_BS_CHANNEL_TYPE,
        .ext_assign         = 0,
        .rf_freq            = ANT_FREQUENCY,
        .transmission_type  = ANT_TRANSMISSION_TYPE,
        .device_type        = ANT_DEVICE_TYPE,
        .device_number      = ANT_BS_DEVICE_NUMBER,
        .channel_period     = 0,    // Not used, since this is going to be scanning
        .network_number     = ANT_NETWORK_NUMBER,
    };
    
    err_code = ant_channel_init(&channel_config);
    APP_ERROR_CHECK(err_code);
    
    // Assign a second channel for sending messages on the reverse direction
    // There is no need to configure any other parameters, this channel is never opened;
    // its resources are used by ANT to send messages in the reverse direction while in
    // continuous scanning mode.
    err_code = sd_ant_channel_assign(ANT_RESPONSE_CHANNEL_NUMBER,
                                     ANT_BS_CHANNEL_TYPE,
                                     ANT_NETWORK_NUMBER,
                                     0x00);
    APP_ERROR_CHECK(err_code);
}

/** @brief Add a newly discovered node to the m_node_list
 *
 * @param[in] device_number   The device_number of the current to be added
 * @param[in] rssi            The RSSI from the current node to be added
 */
void add_node_to_list(uint16_t device_number, uint8_t rssi)
{
   uint8_t index = MAX_DEVICES; // Specifed maximum total number in the array
   uint8_t start = CONVERT_DEVICE_NUM_TO_INDEX(device_number); // Start index of the array

    uint8_t node_device_number;
    for(int i = 0; i < MAX_DEVICES; i++ )
    {
        node_device_number = m_node_list[(start + i) % MAX_DEVICES].device_number;

        if( node_device_number == device_number ) // If this node already exists, don't add it
            return;

        if(node_device_number == 0) // If we found a place to put it
        {   // Find the best place to put this node (the place closest to the hash function result)
            index = (start + i) % MAX_DEVICES;
            break;
        }
    }

    if( index == MAX_DEVICES )
        return;

    m_node_list[index].device_number = device_number;
    m_node_list[index].rssi = rssi;
}
void ant_search_sharing_setup(void)
{
    uint32_t err_code;

    ant_channel_config_t channel_config =
    {
        .channel_type       = CHANNEL_TYPE_SLAVE,
        .ext_assign         = EXT_TYPE,
        .device_number      = 0,
        .network_number     = ANT_CHANNEL_DEFAULT_NETWORK,
    };

    ant_search_config_t search_config =
    {
        .low_priority_timeout  = CHAN_SEARCH_TIMEOUT,
        .high_priority_timeout = ANT_HIGH_PRIORITY_SEARCH_DISABLE,
        .search_sharing_cycles = CHAN_SEARCH_CYCLES,
        .search_priority       = ANT_SEARCH_PRIORITY_DEFAULT,
        .waveform              = ANT_WAVEFORM_FAST,     // Use fast waveform to limit impact on acquisition time from searching on multiple frequencies
    };

    m_rx_first_ch0 = false;
    m_rx_first_ch1 = false;

    // Configure channel parameters for channel 0
    channel_config.channel_number    = ANT_CHANNEL_NUMBER_0;
    channel_config.device_type       = CHAN_ID_DEV_TYPE_CH0;
    channel_config.transmission_type = CHAN_ID_TRANS_TYPE_CH0;
    channel_config.channel_period    = CHAN_PERIOD_CH0;
    channel_config.rf_freq           = RF_FREQ_CH0;
    err_code = ant_channel_init(&channel_config);
    APP_ERROR_CHECK(err_code);

    // Configure search parameters for channel 0
    search_config.channel_number = ANT_CHANNEL_NUMBER_0;
    err_code = ant_search_init(&search_config);
    APP_ERROR_CHECK(err_code);

    // Configure channel parameters for channel 1
    channel_config.channel_number    = ANT_CHANNEL_NUMBER_1;
    channel_config.device_type       = CHAN_ID_DEV_TYPE_CH1;
    channel_config.transmission_type = CHAN_ID_TRANS_TYPE_CH1;
    channel_config.channel_period    = CHAN_PERIOD_CH1;
    channel_config.rf_freq           = RF_FREQ_CH1;
    err_code = ant_channel_init(&channel_config);
    APP_ERROR_CHECK(err_code);

    // Configure search parameters for channel 1
    search_config.channel_number = ANT_CHANNEL_NUMBER_1;
    err_code = ant_search_init(&search_config);
    APP_ERROR_CHECK(err_code);

    // Open both channels
    err_code = sd_ant_channel_open(ANT_CHANNEL_NUMBER_0);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ant_channel_open(ANT_CHANNEL_NUMBER_1);
    APP_ERROR_CHECK(err_code);

}


void ant_search_sharing_event_handler(ant_evt_t * p_ant_evt)
{
    switch (p_ant_evt->event)
    {
        case EVENT_RX:
            switch(p_ant_evt->channel)
            {
                case ANT_CHANNEL_NUMBER_0:
                    if(!m_rx_first_ch0)
                    {
                        m_rx_first_ch0 = true;
                        LEDS_ON(BSP_LED_0_MASK);
                    }
                    break;

                case ANT_CHANNEL_NUMBER_1:
                    if(!m_rx_first_ch1)
                    {
                        m_rx_first_ch1 = true;
                        LEDS_ON(BSP_LED_1_MASK);
                    }
                    break;
            }
            break;

        default:
            break;
    }
}
Example #13
0
void ant_message_types_master_setup(void)
{
    uint32_t err_code;

    ant_channel_config_t channel_config =
    {
        .channel_number     = ANT_CHANNEL_NUMBER,
        .channel_type       = CHANNEL_TYPE_MASTER,
        .ext_assign         = EXT_ASSIGN,
        .rf_freq            = RF_FREQUENCY,
        .transmission_type  = CHAN_ID_TRANS_TYPE,
        .device_type        = CHAN_ID_DEV_TYPE,
        .device_number      = (uint16_t) (NRF_FICR->DEVICEID[0]),
        .channel_period     = CHANNEL_PERIOD,
        .network_number     = ANT_CHANNEL_DEFAULT_NETWORK,
    };

    err_code = ant_channel_init(&channel_config);
    APP_ERROR_CHECK(err_code);

    //Set Tx Power
    err_code = sd_ant_channel_radio_tx_power_set(ANT_CHANNEL_NUMBER, RADIO_TX_POWER_LVL_3, ANT_CUSTOM_TRANSMIT_POWER);
    APP_ERROR_CHECK(err_code);

    // Open channel.
    err_code = sd_ant_channel_open(ANT_CHANNEL_NUMBER);
    APP_ERROR_CHECK(err_code);

    // Write counter value to last byte of the broadcast data.
    // The last byte is chosen to get the data more visible in the end of an printout
    // on the recieving end.
    memset(m_tx_buffer, 0, BROADCAST_DATA_BUFFER_SIZE);
    m_tx_buffer[BROADCAST_DATA_BUFFER_SIZE - 1] = m_counter;

    // Configure the initial payload of the broadcast data
    err_code = sd_ant_broadcast_message_tx(ANT_CHANNEL_NUMBER, BROADCAST_DATA_BUFFER_SIZE, m_tx_buffer);
    APP_ERROR_CHECK(err_code);

    //Set state to broadcasting
    state_message_types = BROADCAST;
}


void ant_message_types_master_bsp_evt_handler(bsp_event_t evt)
{
    switch (evt)
    {
        case BSP_EVENT_KEY_0:
            state_message_types = BROADCAST;
            break;

        case BSP_EVENT_KEY_1:
            state_message_types = ACKNOWLEDGED;
            break;

        case BSP_EVENT_KEY_2:
            state_message_types = BURST;
            break;

        default:
            break; // no implementation needed
    }
}


void ant_message_types_master_event_handler(ant_evt_t * p_ant_evt)
{
    uint32_t err_code;
    uint32_t led_output = LED_BROADCAST;

    switch (p_ant_evt->event)
    {
        // ANT broadcast/Acknowledged/Burst Success
        // Send the next message according to the current state and increment the counter.
        case EVENT_TX:                      // Intentional fall through
        case EVENT_TRANSFER_TX_COMPLETED:   // Intentional fall through
        case EVENT_TRANSFER_TX_FAILED:
            LEDS_OFF(LEDS_MASK);
            m_tx_buffer[BROADCAST_DATA_BUFFER_SIZE - 1] = m_counter;

            if(state_message_types == BROADCAST)
            {
                // Send as broadcast
                err_code = sd_ant_broadcast_message_tx(ANT_CHANNEL_NUMBER,
                                                       BROADCAST_DATA_BUFFER_SIZE,
                                                       m_tx_buffer);
                APP_ERROR_CHECK(err_code);

                led_output = LED_BROADCAST;
            }
            else if(state_message_types == ACKNOWLEDGED)
            {
                // Send as acknowledged
                err_code = sd_ant_acknowledge_message_tx(ANT_CHANNEL_NUMBER,
                                                         BROADCAST_DATA_BUFFER_SIZE,
                                                         m_tx_buffer);
                APP_ERROR_CHECK(err_code);

                led_output = LED_ACKNOWLEDGED;
            }
            else if(state_message_types == BURST)
            {
                // If this is a new message, populate the burst buffer
                // with new dummy data.  Otherwise, will retry sending the
                // same content.
                if(p_ant_evt->event != EVENT_TRANSFER_TX_FAILED)
                {
                    for(uint32_t i = 0; i < BURST_BLOCK_SIZE; i++)
                    {
                        m_burst_data[i] = m_counter;
                        m_counter++;
                    }
                }

                // Queue a Burst Transfer.  Since this is a small burst, queue entire burst.
                err_code = sd_ant_burst_handler_request(ANT_CHANNEL_NUMBER,
                                                        BURST_BLOCK_SIZE,
                                                        m_burst_data,
                                                        (BURST_SEGMENT_START | BURST_SEGMENT_END));
                APP_ERROR_CHECK(err_code);

                led_output = LED_BURST;
            }
            // Activate LED for 20ms
            LEDS_ON(led_output);
            nrf_delay_ms(20);
            LEDS_OFF(led_output);
            m_counter++;
            break;

        case TRANSFER_IN_PROGRESS:              //Intentional fall through
        case TRANSFER_SEQUENCE_NUMBER_ERROR:    //Intentional fall through
        case TRANSFER_IN_ERROR:                 //Intentional fall through
        case TRANSFER_BUSY:
            // Ignore these events; will retry burst transfer when we get the EVENT_TRANSFER_TX_FAILED event.
            break;

        default:
            break;

    }
}