update bootloader
This commit is contained in:
		@@ -10,6 +10,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
#include "bootloader.h"
 | 
			
		||||
#include "bootloader_types.h"
 | 
			
		||||
#include "bootloader_util.h"
 | 
			
		||||
@@ -25,9 +26,8 @@
 | 
			
		||||
#include "pstorage.h"
 | 
			
		||||
#include "app_scheduler.h"
 | 
			
		||||
#include "nrf_delay.h"
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
 | 
			
		||||
#include "app_timer_appsh.h"
 | 
			
		||||
#include "app_timer.h"
 | 
			
		||||
 | 
			
		||||
#define APP_TIMER_PRESCALER    0
 | 
			
		||||
 | 
			
		||||
@@ -326,7 +326,7 @@ uint32_t bootloader_dfu_start(bool ota, uint32_t timeout_ms)
 | 
			
		||||
        _terminate_startup_dfu = false;
 | 
			
		||||
 | 
			
		||||
        (void) app_timer_create(&_forced_startup_dfu_timer, APP_TIMER_MODE_SINGLE_SHOT, forced_startup_dfu_timer_handler);
 | 
			
		||||
        app_timer_start(_forced_startup_dfu_timer, APP_TIMER_TICKS(timeout_ms, APP_TIMER_PRESCALER), NULL);
 | 
			
		||||
        app_timer_start(_forced_startup_dfu_timer, APP_TIMER_TICKS(timeout_ms), NULL);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      err_code = dfu_transport_serial_update_start();
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ typedef enum
 | 
			
		||||
} dfu_state_t;
 | 
			
		||||
 | 
			
		||||
#define APP_TIMER_PRESCALER         0                                               /**< Value of the RTC1 PRESCALER register. */
 | 
			
		||||
#define DFU_TIMEOUT_INTERVAL        APP_TIMER_TICKS(300000, APP_TIMER_PRESCALER)    /**< DFU timeout interval in units of timer ticks. */     
 | 
			
		||||
#define DFU_TIMEOUT_INTERVAL        APP_TIMER_TICKS(300000)    /**< DFU timeout interval in units of timer ticks. */
 | 
			
		||||
 | 
			
		||||
#define IS_UPDATING_SD(START_PKT)   ((START_PKT).dfu_update_mode & DFU_UPDATE_SD)   /**< Macro for determining if a SoftDevice update is ongoing. */
 | 
			
		||||
#define IS_UPDATING_BL(START_PKT)   ((START_PKT).dfu_update_mode & DFU_UPDATE_BL)   /**< Macro for determining if a Bootloader update is ongoing. */
 | 
			
		||||
 
 | 
			
		||||
@@ -65,8 +65,8 @@ enum { BLE_CONN_CFG_HIGH_BANDWIDTH = 1 };
 | 
			
		||||
 | 
			
		||||
#define APP_TIMER_PRESCALER                  0                                                       /**< Value of the RTC1 PRESCALER register. */
 | 
			
		||||
 | 
			
		||||
#define FIRST_CONN_PARAMS_UPDATE_DELAY       APP_TIMER_TICKS(100, APP_TIMER_PRESCALER)               /**< Time from the Connected event to first time sd_ble_gap_conn_param_update is called (100 milliseconds). */
 | 
			
		||||
#define NEXT_CONN_PARAMS_UPDATE_DELAY        APP_TIMER_TICKS(500, APP_TIMER_PRESCALER)               /**< Time between each call to sd_ble_gap_conn_param_update after the first call (500 milliseconds). */
 | 
			
		||||
#define FIRST_CONN_PARAMS_UPDATE_DELAY       APP_TIMER_TICKS(100)               /**< Time from the Connected event to first time sd_ble_gap_conn_param_update is called (100 milliseconds). */
 | 
			
		||||
#define NEXT_CONN_PARAMS_UPDATE_DELAY        APP_TIMER_TICKS(500)               /**< Time between each call to sd_ble_gap_conn_param_update after the first call (500 milliseconds). */
 | 
			
		||||
#define MAX_CONN_PARAMS_UPDATE_COUNT         3                                                       /**< Number of attempts before giving up the connection parameter negotiation. */
 | 
			
		||||
 | 
			
		||||
#define APP_ADV_INTERVAL                     MSEC_TO_UNITS(25, UNIT_0_625_MS)                        /**< The advertising interval (25 ms.). */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,98 +1,108 @@
 | 
			
		||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
#if NRF_MODULE_ENABLED(HCI_MEM_POOL)
 | 
			
		||||
#include "hci_mem_pool.h"
 | 
			
		||||
//#include "hci_mem_pool_internal.h"
 | 
			
		||||
#include "nordic_common.h"
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Adafruit for dual transport serial + ble
 | 
			
		||||
#define BLE_TX_BUF_SIZE           4u    /**< TX buffer size in bytes. */
 | 
			
		||||
#define BLE_RX_BUF_SIZE           32u   /**< RX buffer size in bytes. */
 | 
			
		||||
#define BLE_RX_BUF_QUEUE_SIZE     8u    /**< RX buffer element size. */
 | 
			
		||||
 | 
			
		||||
#define SERIAL_TX_BUF_SIZE        32u    /**< TX buffer size in bytes. */
 | 
			
		||||
#define SERIAL_RX_BUF_SIZE        600u   /**< RX buffer size in bytes. */
 | 
			
		||||
#define SERIAL_RX_BUF_QUEUE_SIZE  2u     /**< RX buffer element size. */
 | 
			
		||||
 | 
			
		||||
extern bool is_ota(void);
 | 
			
		||||
 | 
			
		||||
#define RX_BUF_SIZE         (is_ota() ? BLE_RX_BUF_SIZE : SERIAL_RX_BUF_SIZE)
 | 
			
		||||
#define TX_BUF_SIZE         (is_ota() ? BLE_TX_BUF_SIZE : SERIAL_TX_BUF_SIZE)
 | 
			
		||||
#define RX_BUF_QUEUE_SIZE   (is_ota() ? BLE_RX_BUF_QUEUE_SIZE : SERIAL_RX_BUF_QUEUE_SIZE)
 | 
			
		||||
 | 
			
		||||
/**@brief RX buffer element instance structure. 
 | 
			
		||||
/**@brief RX buffer element instance structure.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct 
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
//    uint8_t  rx_buffer[RX_BUF_SIZE];                                /**< RX buffer memory array. */
 | 
			
		||||
    uint8_t  rx_buffer[MAX(BLE_RX_BUF_SIZE, SERIAL_RX_BUF_SIZE)];
 | 
			
		||||
    uint8_t  rx_buffer[HCI_RX_BUF_SIZE];                            /**< RX buffer memory array. */
 | 
			
		||||
    uint32_t length;                                                /**< Length of the RX buffer memory array. */
 | 
			
		||||
} rx_buffer_elem_t;
 | 
			
		||||
 | 
			
		||||
/**@brief RX buffer queue element instance structure. 
 | 
			
		||||
/**@brief RX buffer queue element instance structure.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct 
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    rx_buffer_elem_t * p_buffer;                                    /**< Pointer to RX buffer element. */
 | 
			
		||||
    uint32_t           free_window_count;                           /**< Free space element count. */
 | 
			
		||||
    uint32_t           free_available_count;                        /**< Free area element count. */
 | 
			
		||||
    uint32_t           read_available_count;                        /**< Read area element count. */
 | 
			
		||||
    uint32_t           write_index;                                 /**< Write position index. */                                      
 | 
			
		||||
    uint32_t           read_index;                                  /**< Read position index. */                                                                            
 | 
			
		||||
    uint32_t           free_index;                                  /**< Free position index. */                                                                                                                  
 | 
			
		||||
    uint32_t           write_index;                                 /**< Write position index. */
 | 
			
		||||
    uint32_t           read_index;                                  /**< Read position index. */
 | 
			
		||||
    uint32_t           free_index;                                  /**< Free position index. */
 | 
			
		||||
} rx_buffer_queue_t;
 | 
			
		||||
 | 
			
		||||
static bool              m_is_tx_allocated;                         /**< Boolean value to determine if the TX buffer is allocated. */
 | 
			
		||||
static rx_buffer_elem_t  m_rx_buffer_elem_queue[MAX(BLE_RX_BUF_QUEUE_SIZE, SERIAL_RX_BUF_QUEUE_SIZE)]; /**< RX buffer element instances. */
 | 
			
		||||
static rx_buffer_elem_t  m_rx_buffer_elem_queue[HCI_RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */
 | 
			
		||||
static rx_buffer_queue_t m_rx_buffer_queue;                         /**< RX buffer queue element instance. */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_mem_pool_open(void)
 | 
			
		||||
{
 | 
			
		||||
    m_is_tx_allocated                      = false;    
 | 
			
		||||
    m_is_tx_allocated                      = false;
 | 
			
		||||
    m_rx_buffer_queue.p_buffer             = m_rx_buffer_elem_queue;
 | 
			
		||||
    m_rx_buffer_queue.free_window_count    = RX_BUF_QUEUE_SIZE;
 | 
			
		||||
    m_rx_buffer_queue.free_window_count    = HCI_RX_BUF_QUEUE_SIZE;
 | 
			
		||||
    m_rx_buffer_queue.free_available_count = 0;
 | 
			
		||||
    m_rx_buffer_queue.read_available_count = 0;
 | 
			
		||||
    m_rx_buffer_queue.write_index          = 0;    
 | 
			
		||||
    m_rx_buffer_queue.read_index           = 0;        
 | 
			
		||||
    m_rx_buffer_queue.free_index           = 0;            
 | 
			
		||||
    
 | 
			
		||||
    m_rx_buffer_queue.write_index          = 0;
 | 
			
		||||
    m_rx_buffer_queue.read_index           = 0;
 | 
			
		||||
    m_rx_buffer_queue.free_index           = 0;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_mem_pool_close(void)
 | 
			
		||||
{    
 | 
			
		||||
{
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer)
 | 
			
		||||
{
 | 
			
		||||
    static uint8_t tx_buffer[MAX(BLE_TX_BUF_SIZE, SERIAL_TX_BUF_SIZE)];
 | 
			
		||||
    static uint8_t tx_buffer[HCI_TX_BUF_SIZE];
 | 
			
		||||
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (pp_buffer == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_NULL;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (!m_is_tx_allocated)
 | 
			
		||||
    {        
 | 
			
		||||
    {
 | 
			
		||||
            m_is_tx_allocated = true;
 | 
			
		||||
            *pp_buffer        = tx_buffer;
 | 
			
		||||
            err_code          = NRF_SUCCESS;
 | 
			
		||||
@@ -101,7 +111,7 @@ uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer)
 | 
			
		||||
    {
 | 
			
		||||
        err_code              = NRF_ERROR_NO_MEM;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -109,51 +119,51 @@ uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer)
 | 
			
		||||
uint32_t hci_mem_pool_tx_free(void)
 | 
			
		||||
{
 | 
			
		||||
    m_is_tx_allocated = false;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code; 
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    if (pp_buffer == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_NULL;
 | 
			
		||||
    }    
 | 
			
		||||
    }
 | 
			
		||||
    *pp_buffer = NULL;
 | 
			
		||||
    
 | 
			
		||||
    if (m_rx_buffer_queue.free_window_count != 0)
 | 
			
		||||
    {    
 | 
			
		||||
        if (length <= RX_BUF_SIZE)
 | 
			
		||||
        {    
 | 
			
		||||
            --(m_rx_buffer_queue.free_window_count);            
 | 
			
		||||
            ++(m_rx_buffer_queue.read_available_count);            
 | 
			
		||||
 | 
			
		||||
            *pp_buffer                    = 
 | 
			
		||||
    if (m_rx_buffer_queue.free_window_count != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (length <= HCI_RX_BUF_SIZE)
 | 
			
		||||
        {
 | 
			
		||||
            --(m_rx_buffer_queue.free_window_count);
 | 
			
		||||
            ++(m_rx_buffer_queue.read_available_count);
 | 
			
		||||
 | 
			
		||||
            *pp_buffer                    =
 | 
			
		||||
                    m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer;
 | 
			
		||||
 | 
			
		||||
            m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index);
 | 
			
		||||
 | 
			
		||||
            // @note: Adjust the write_index making use of the fact that the buffer size is of 
 | 
			
		||||
            // power of two and two's complement arithmetic. For details refer example to book 
 | 
			
		||||
            // @note: Adjust the write_index making use of the fact that the buffer size is of
 | 
			
		||||
            // power of two and two's complement arithmetic. For details refer example to book
 | 
			
		||||
            // "Making embedded systems: Elicia White".
 | 
			
		||||
            m_rx_buffer_queue.write_index = 
 | 
			
		||||
                    (m_rx_buffer_queue.write_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
            
 | 
			
		||||
            m_rx_buffer_queue.write_index =
 | 
			
		||||
                    (m_rx_buffer_queue.write_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
 | 
			
		||||
            err_code                      = NRF_SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            err_code = NRF_ERROR_DATA_SIZE;    
 | 
			
		||||
        }        
 | 
			
		||||
            err_code = NRF_ERROR_DATA_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        err_code = NRF_ERROR_NO_MEM;    
 | 
			
		||||
        err_code = NRF_ERROR_NO_MEM;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -163,16 +173,16 @@ uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    uint32_t consume_index;
 | 
			
		||||
    uint32_t start_index;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (m_rx_buffer_queue.free_available_count != 0)
 | 
			
		||||
    {
 | 
			
		||||
        // Find the buffer that has been freed -
 | 
			
		||||
        // Start at read_index minus free_available_count and then increment until read index.
 | 
			
		||||
        err_code      = NRF_ERROR_INVALID_ADDR;
 | 
			
		||||
        consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) & 
 | 
			
		||||
                        (RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
        consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) &
 | 
			
		||||
                        (HCI_RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
        start_index   = consume_index;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        do
 | 
			
		||||
        {
 | 
			
		||||
            if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer)
 | 
			
		||||
@@ -183,36 +193,36 @@ uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                consume_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
                consume_index = (consume_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        while (consume_index != m_rx_buffer_queue.read_index);
 | 
			
		||||
 | 
			
		||||
        while (!(m_rx_buffer_queue.free_index & (1 << start_index)) && 
 | 
			
		||||
        while (!(m_rx_buffer_queue.free_index & (1 << start_index)) &&
 | 
			
		||||
                (m_rx_buffer_queue.free_available_count != 0))
 | 
			
		||||
        {
 | 
			
		||||
            --(m_rx_buffer_queue.free_available_count);
 | 
			
		||||
            ++(m_rx_buffer_queue.free_window_count);            
 | 
			
		||||
            start_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
            ++(m_rx_buffer_queue.free_window_count);
 | 
			
		||||
            start_index = (consume_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        err_code = NRF_ERROR_NO_MEM;
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    return err_code;    
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_mem_pool_rx_data_size_set(uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
    // @note: Adjust the write_index making use of the fact that the buffer size is of power
 | 
			
		||||
    // of two and two's complement arithmetic. For details refer example to book 
 | 
			
		||||
    // of two and two's complement arithmetic. For details refer example to book
 | 
			
		||||
    // "Making embedded systems: Elicia White".
 | 
			
		||||
    const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
    m_rx_buffer_queue.p_buffer[index].length = length;    
 | 
			
		||||
    
 | 
			
		||||
    const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
    m_rx_buffer_queue.p_buffer[index].length = length;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -220,34 +230,35 @@ uint32_t hci_mem_pool_rx_data_size_set(uint32_t length)
 | 
			
		||||
uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if ((pp_buffer == NULL) || (p_length == NULL))
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_NULL;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (m_rx_buffer_queue.read_available_count != 0)
 | 
			
		||||
    {
 | 
			
		||||
        --(m_rx_buffer_queue.read_available_count);
 | 
			
		||||
        ++(m_rx_buffer_queue.free_available_count);        
 | 
			
		||||
        
 | 
			
		||||
        *pp_buffer                   = 
 | 
			
		||||
        ++(m_rx_buffer_queue.free_available_count);
 | 
			
		||||
 | 
			
		||||
        *pp_buffer                   =
 | 
			
		||||
            m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer;
 | 
			
		||||
        *p_length                    = 
 | 
			
		||||
        *p_length                    =
 | 
			
		||||
            m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // @note: Adjust the write_index making use of the fact that the buffer size is of power
 | 
			
		||||
        // of two and two's complement arithmetic. For details refer example to book 
 | 
			
		||||
        // "Making embedded systems: Elicia White".            
 | 
			
		||||
        m_rx_buffer_queue.read_index = 
 | 
			
		||||
            (m_rx_buffer_queue.read_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); 
 | 
			
		||||
        
 | 
			
		||||
        // of two and two's complement arithmetic. For details refer example to book
 | 
			
		||||
        // "Making embedded systems: Elicia White".
 | 
			
		||||
        m_rx_buffer_queue.read_index =
 | 
			
		||||
            (m_rx_buffer_queue.read_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
 | 
			
		||||
 | 
			
		||||
        err_code                     = NRF_SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        err_code                     = NRF_ERROR_NO_MEM;        
 | 
			
		||||
        err_code                     = NRF_ERROR_NO_MEM;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
#endif //NRF_MODULE_ENABLED(HCI_MEM_POOL)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,57 @@
 | 
			
		||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup memory_pool Memory pool
 | 
			
		||||
 * @defgroup hci_mem_pool Memory pool
 | 
			
		||||
 * @{
 | 
			
		||||
 * @ingroup app_common
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Memory pool implementation
 | 
			
		||||
 *
 | 
			
		||||
 * Memory pool implementation, based on circular buffer data structure, which supports asynchronous 
 | 
			
		||||
 * Memory pool implementation, based on circular buffer data structure, which supports asynchronous
 | 
			
		||||
 * processing of RX data. The current default implementation supports 1 TX buffer and 4 RX buffers.
 | 
			
		||||
 * The memory managed by the pool is allocated from static storage instead of heap. The internal 
 | 
			
		||||
 * design of the circular buffer implementing the RX memory layout is illustrated in the picture 
 | 
			
		||||
 * below. 
 | 
			
		||||
 * The memory managed by the pool is allocated from static storage instead of heap. The internal
 | 
			
		||||
 * design of the circular buffer implementing the RX memory layout is illustrated in the picture
 | 
			
		||||
 * below.
 | 
			
		||||
 *
 | 
			
		||||
 * @image html memory_pool.png "Circular buffer design"
 | 
			
		||||
 * @image html memory_pool.svg "Circular buffer design"
 | 
			
		||||
 *
 | 
			
		||||
 * The expected call order for the RX APIs is as follows:
 | 
			
		||||
 * - hci_mem_pool_rx_produce
 | 
			
		||||
@@ -37,26 +64,30 @@
 | 
			
		||||
 * \par Component specific configuration options
 | 
			
		||||
 *
 | 
			
		||||
 * The following compile time configuration options are available to suit various implementations:
 | 
			
		||||
 * - TX_BUF_SIZE TX buffer size in bytes. 
 | 
			
		||||
 * - RX_BUF_SIZE RX buffer size in bytes. 
 | 
			
		||||
 * - TX_BUF_SIZE TX buffer size in bytes.
 | 
			
		||||
 * - RX_BUF_SIZE RX buffer size in bytes.
 | 
			
		||||
 * - RX_BUF_QUEUE_SIZE RX buffer element size.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
#ifndef HCI_MEM_POOL_H__
 | 
			
		||||
#define HCI_MEM_POOL_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "nrf_error.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**@brief Function for opening the module.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success. 
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_mem_pool_open(void);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for closing the module.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success. 
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_mem_pool_close(void);
 | 
			
		||||
 | 
			
		||||
@@ -66,37 +97,37 @@ uint32_t hci_mem_pool_close(void);
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success. Memory was allocated.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM     Operation failure. No memory available for allocation.
 | 
			
		||||
 * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.  
 | 
			
		||||
 * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
/**@brief Function for freeing previously allocated TX memory.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Memory management follows the FIFO principle meaning that free() order must match the 
 | 
			
		||||
 *       alloc(...) order, which is the reason for omitting exact memory block identifier as an 
 | 
			
		||||
 * @note Memory management follows the FIFO principle meaning that free() order must match the
 | 
			
		||||
 *       alloc(...) order, which is the reason for omitting exact memory block identifier as an
 | 
			
		||||
 *       input parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success. Memory was freed.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_mem_pool_tx_free(void);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
/**@brief Function for producing a free RX memory block for usage.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Upon produce request amount being 0, NRF_SUCCESS is returned.   
 | 
			
		||||
 * @note Upon produce request amount being 0, NRF_SUCCESS is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  length           Amount, in bytes, of free memory to be produced.
 | 
			
		||||
 * @param[out] pp_buffer        Pointer to the allocated memory.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success. Free RX memory block produced.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM     Operation failure. No suitable memory available for allocation.
 | 
			
		||||
 * @retval NRF_ERROR_DATA_SIZE  Operation failure. Request size exceeds limit.  
 | 
			
		||||
 * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.   
 | 
			
		||||
 * @retval NRF_ERROR_DATA_SIZE  Operation failure. Request size exceeds limit.
 | 
			
		||||
 * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for setting the length of the last produced RX memory block.
 | 
			
		||||
 *
 | 
			
		||||
 * @warning If call to this API is omitted the end result is that the following call to 
 | 
			
		||||
 * @warning If call to this API is omitted the end result is that the following call to
 | 
			
		||||
 *          mem_pool_rx_extract will return incorrect data in the p_length output parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  length           Amount, in bytes, of actual memory used.
 | 
			
		||||
@@ -104,29 +135,34 @@ uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer);
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success. Length was set.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_mem_pool_rx_data_size_set(uint32_t length);
 | 
			
		||||
 
 | 
			
		||||
/**@brief Function for extracting a packet, which has been filled with read data, for further 
 | 
			
		||||
 | 
			
		||||
/**@brief Function for extracting a packet, which has been filled with read data, for further
 | 
			
		||||
 * processing.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out] pp_buffer        Pointer to the packet data.
 | 
			
		||||
 * @param[out] p_length         Length of packet data in bytes.  
 | 
			
		||||
 * @param[out] p_length         Length of packet data in bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success. 
 | 
			
		||||
 * @retval NRF_SUCCESS          Operation success.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM     Operation failure. No packet available to extract.
 | 
			
		||||
 * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.    
 | 
			
		||||
 * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
/**@brief Function for freeing previously extracted packet, which has been filled with read data.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_buffer             Pointer to consumed buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS             Operation success. 
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM        Operation failure. No packet available to free. 
 | 
			
		||||
 * @retval NRF_ERROR_INVALID_ADDR  Operation failure. Not a valid pointer. 
 | 
			
		||||
 * @retval NRF_SUCCESS             Operation success.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM        Operation failure. No packet available to free.
 | 
			
		||||
 * @retval NRF_ERROR_INVALID_ADDR  Operation failure. Not a valid pointer.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // HCI_MEM_POOL_H__
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,46 @@
 | 
			
		||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
#if NRF_MODULE_ENABLED(HCI_SLIP)
 | 
			
		||||
#include "hci_slip.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "hci_transport_config.h"
 | 
			
		||||
#include "app_uart.h"
 | 
			
		||||
#include "nrf_error.h"
 | 
			
		||||
 | 
			
		||||
@@ -121,7 +149,7 @@ static uint32_t send_tx_byte_encoded(void)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    switch(mp_tx_buffer[m_tx_buffer_index])
 | 
			
		||||
    switch (mp_tx_buffer[m_tx_buffer_index])
 | 
			
		||||
    {
 | 
			
		||||
        case APP_SLIP_END:
 | 
			
		||||
            err_code = app_uart_put(APP_SLIP_ESC_END);
 | 
			
		||||
@@ -333,19 +361,19 @@ static uint32_t slip_uart_open(void)
 | 
			
		||||
 | 
			
		||||
    app_uart_comm_params_t comm_params =
 | 
			
		||||
    {
 | 
			
		||||
        HCI_SLIP_UART_RX_PIN_NUMBER,
 | 
			
		||||
        HCI_SLIP_UART_TX_PIN_NUMBER,
 | 
			
		||||
        HCI_SLIP_UART_RTS_PIN_NUMBER,
 | 
			
		||||
        HCI_SLIP_UART_CTS_PIN_NUMBER,
 | 
			
		||||
        HCI_SLIP_UART_MODE,
 | 
			
		||||
        HCI_UART_RX_PIN,
 | 
			
		||||
        HCI_UART_TX_PIN,
 | 
			
		||||
        HCI_UART_RTS_PIN,
 | 
			
		||||
        HCI_UART_CTS_PIN,
 | 
			
		||||
        (app_uart_flow_control_t)HCI_UART_FLOW_CONTROL,
 | 
			
		||||
        false,
 | 
			
		||||
        HCI_SLIP_UART_BAUDRATE
 | 
			
		||||
        HCI_UART_BAUDRATE
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    err_code = app_uart_init(&comm_params,
 | 
			
		||||
                             NULL,
 | 
			
		||||
                             slip_uart_eventhandler,
 | 
			
		||||
                             APP_IRQ_PRIORITY_LOW);
 | 
			
		||||
                             APP_IRQ_PRIORITY_LOWEST);
 | 
			
		||||
 | 
			
		||||
    if (err_code == NRF_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
@@ -426,3 +454,4 @@ uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length)
 | 
			
		||||
    handle_rx_byte      = handle_rx_byte_wait_start;
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
#endif //NRF_MODULE_ENABLED(HCI_SLIP)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,42 @@
 | 
			
		||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup hci_slip SLIP module
 | 
			
		||||
@@ -33,6 +60,10 @@
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**@brief Event types from the SLIP Layer. */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
@@ -59,7 +90,7 @@ typedef void (*hci_slip_event_handler_t)(hci_slip_evt_t event);
 | 
			
		||||
/**@brief Function for registering the event handler provided as parameter and this event handler
 | 
			
		||||
 *        will be used by SLIP layer to send events described in \ref hci_slip_evt_type_t.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Multiple registration requests will overwrite any existing registration. 
 | 
			
		||||
 * @note Multiple registration requests will overwrite any existing registration.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] event_handler         This function is called by the SLIP layer upon an event.
 | 
			
		||||
 *
 | 
			
		||||
@@ -70,8 +101,8 @@ uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler);
 | 
			
		||||
/**@brief Function for opening the SLIP layer. This function must be called before
 | 
			
		||||
 *        \ref hci_slip_write and before any data can be received.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Can be called multiple times. 
 | 
			
		||||
 * 
 | 
			
		||||
 * @note Can be called multiple times.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.
 | 
			
		||||
 *
 | 
			
		||||
 * The SLIP layer module will propagate errors from underlying sub-modules.
 | 
			
		||||
@@ -84,8 +115,8 @@ uint32_t hci_slip_open(void);
 | 
			
		||||
 *        transmitted or received in this layer.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function can be called multiple times and also for an unopened channel.
 | 
			
		||||
 * 
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.  
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_slip_close(void);
 | 
			
		||||
 | 
			
		||||
@@ -95,8 +126,8 @@ uint32_t hci_slip_close(void);
 | 
			
		||||
 * @param[in] p_buffer              Pointer to the packet to transmit.
 | 
			
		||||
 * @param[in] length                Packet length, in bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Packet was encoded and added to the 
 | 
			
		||||
 *                                  transmission queue and an event will be sent upon transmission 
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Packet was encoded and added to the
 | 
			
		||||
 *                                  transmission queue and an event will be sent upon transmission
 | 
			
		||||
 *                                  completion.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM         Operation failure. Transmission queue is full and packet was not
 | 
			
		||||
 *                                  added to the transmission queue. Application shall wait for
 | 
			
		||||
@@ -120,10 +151,15 @@ uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length);
 | 
			
		||||
 *                                  will be placed in this buffer.
 | 
			
		||||
 * @param[in]  length               Buffer length, in bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. 
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // HCI_SLIP_H__
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,51 @@
 | 
			
		||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "hci_transport_config.h"
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
#if NRF_MODULE_ENABLED(HCI_TRANSPORT)
 | 
			
		||||
#include "hci_transport.h"
 | 
			
		||||
#include "hci_slip.h"
 | 
			
		||||
#include "crc16.h"
 | 
			
		||||
#include "hci_mem_pool.h"
 | 
			
		||||
#include "hci_mem_pool_internal.h"
 | 
			
		||||
#include "app_timer.h"
 | 
			
		||||
#include "app_error.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
 | 
			
		||||
#define PKT_HDR_SIZE                    4u                                                                 /**< Packet header size in number of bytes. */
 | 
			
		||||
#define PKT_CRC_SIZE                    2u                                                                 /**< Packet CRC size in number of bytes. */
 | 
			
		||||
@@ -30,17 +56,19 @@
 | 
			
		||||
#define INITIAL_ACK_NUMBER_EXPECTED     1u                                                                 /**< Initial acknowledge number expected. */
 | 
			
		||||
#define INITIAL_ACK_NUMBER_TX           INITIAL_ACK_NUMBER_EXPECTED                                        /**< Initial acknowledge number transmitted. */
 | 
			
		||||
#define INVALID_PKT_TYPE                0xFFFFFFFFu                                                        /**< Internal invalid packet type value. */
 | 
			
		||||
#define MAX_TRANSMISSION_TIME           (ROUNDED_DIV((MAX_PACKET_SIZE_IN_BITS * 1000u), USED_BAUD_RATE))   /**< Max transmission time of a single application packet over UART in units of mseconds. */      
 | 
			
		||||
#define RETRANSMISSION_TIMEOUT_IN_MS    (3u * MAX_TRANSMISSION_TIME)                                       /**< Retransmission timeout for application packet in units of mseconds. */      
 | 
			
		||||
#define APP_TIMER_PRESCALER             0                                                                  /**< Value of the RTC1 PRESCALER register. */
 | 
			
		||||
#define RETRANSMISSION_TIMEOUT_IN_TICKS APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_MS, APP_TIMER_PRESCALER) /**< Retransmission timeout for application packet in units of timer ticks. */             
 | 
			
		||||
#define HCI_UART_REG_VALUE_TO_BAUDRATE(BAUDRATE) ((BAUDRATE)/268)                                          /**< Estimated relation between UART baudrate register value and actual baudrate */
 | 
			
		||||
#define MAX_TRANSMISSION_TIME                                                  \
 | 
			
		||||
                   (ROUNDED_DIV((HCI_MAX_PACKET_SIZE_IN_BITS * 1000u),         \
 | 
			
		||||
                    HCI_UART_REG_VALUE_TO_BAUDRATE(HCI_UART_BAUDRATE)))                                    /**< Max transmission time of a single application packet over UART in units of mseconds. */
 | 
			
		||||
#define RETRANSMISSION_TIMEOUT_IN_MS    (3u * MAX_TRANSMISSION_TIME)                                       /**< Retransmission timeout for application packet in units of mseconds. */
 | 
			
		||||
#define RETRANSMISSION_TIMEOUT_IN_TICKS APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_MS) /**< Retransmission timeout for application packet in units of timer ticks. */
 | 
			
		||||
#define MAX_RETRY_COUNT                 5u                                                                 /**< Max retransmission retry count for application packets. */
 | 
			
		||||
#define ACK_BUF_SIZE                    5u                                                                 /**< Length of module internal RX buffer which is big enough to hold an acknowledgement packet. */
 | 
			
		||||
 | 
			
		||||
/**@brief States of the TX state machine. */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    TX_STATE_IDLE,                                                   /**< State for: no application transmission packet processing in progress. */                                                                                             
 | 
			
		||||
    TX_STATE_IDLE,                                                   /**< State for: no application transmission packet processing in progress. */
 | 
			
		||||
    TX_STATE_PENDING,                                                /**< State for: TX in progress in slip layer and TX-done event is waited for to signal the end of transmission. */
 | 
			
		||||
    TX_STATE_ACTIVE                                                  /**< State for: application packet has been delivered to slip for transmission and peer transport entity acknowledgement packet is waited for. */
 | 
			
		||||
} tx_state_t;
 | 
			
		||||
@@ -48,7 +76,7 @@ typedef enum
 | 
			
		||||
/**@brief TX state machine events. */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    TX_EVENT_STATE_ENTRY,                                            /**< Event for: state entry use case. */                                                                                             
 | 
			
		||||
    TX_EVENT_STATE_ENTRY,                                            /**< Event for: state entry use case. */
 | 
			
		||||
    TX_EVENT_SLIP_TX_DONE,                                           /**< Event for: HCI_SLIP_TX_DONE event use case. */
 | 
			
		||||
    TX_EVENT_TIMEOUT,                                                /**< Event for: retransmission timeout use case. */
 | 
			
		||||
    TX_EVENT_VALID_RX_ACK                                            /**< Event for: valid acknowledgement received for TX packet use case. */
 | 
			
		||||
@@ -60,8 +88,8 @@ static tx_state_t                      m_tx_state;                   /**< Curren
 | 
			
		||||
static hci_transport_tx_done_handler_t m_transport_tx_done_handle;   /**< TX done event callback function. */
 | 
			
		||||
static hci_transport_event_handler_t   m_transport_event_handle;     /**< Event handler callback function. */
 | 
			
		||||
static uint8_t *                       mp_slip_used_rx_buffer;       /**< Reference to RX buffer used by the slip layer. */
 | 
			
		||||
static uint32_t                        m_packet_expected_seq_number; /**< Sequence number counter of the packet expected to be received . */ 
 | 
			
		||||
static uint32_t                        m_packet_transmit_seq_number; /**< Sequence number counter of the transmitted packet for which acknowledgement packet is waited for. */ 
 | 
			
		||||
static uint32_t                        m_packet_expected_seq_number; /**< Sequence number counter of the packet expected to be received . */
 | 
			
		||||
static uint32_t                        m_packet_transmit_seq_number; /**< Sequence number counter of the transmitted packet for which acknowledgement packet is waited for. */
 | 
			
		||||
static uint8_t *                       mp_tx_buffer;                 /**< Pointer to TX application buffer to be transmitted. */
 | 
			
		||||
static uint32_t                        m_tx_buffer_length;           /**< Length of application TX packet data to be transmitted in bytes. */
 | 
			
		||||
static bool                            m_is_slip_decode_ready;       /**< Boolean to determine has slip decode been completed or not. */
 | 
			
		||||
@@ -74,12 +102,12 @@ static uint8_t                         m_rx_ack_buffer[ACK_BUF_SIZE];/**< RX buf
 | 
			
		||||
/**@brief Function for validating a received packet.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data.
 | 
			
		||||
 * @param[in] length   Length of packet data in bytes.  
 | 
			
		||||
 * @param[in] length   Length of packet data in bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * @return true if received packet is valid, false in other case.
 | 
			
		||||
 */
 | 
			
		||||
static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length)
 | 
			
		||||
{  
 | 
			
		||||
{
 | 
			
		||||
    // Executed packet filtering algorithm order:
 | 
			
		||||
    // - verify packet overall length
 | 
			
		||||
    // - verify data integrity bit set
 | 
			
		||||
@@ -90,38 +118,38 @@ static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length)
 | 
			
		||||
    // - verify CRC
 | 
			
		||||
    if (length <= PKT_HDR_SIZE)
 | 
			
		||||
    {
 | 
			
		||||
        return false;        
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (!(p_buffer[0] & DATA_INTEGRITY_MASK))
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!(p_buffer[0] & RELIABLE_PKT_MASK))
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }        
 | 
			
		||||
    
 | 
			
		||||
    if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC)
 | 
			
		||||
    {    
 | 
			
		||||
        return false;    
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const uint32_t expected_checksum = 
 | 
			
		||||
        ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
 | 
			
		||||
    if (expected_checksum != 0)
 | 
			
		||||
    {    
 | 
			
		||||
 | 
			
		||||
    if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC)
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    const uint32_t expected_checksum =
 | 
			
		||||
        ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
 | 
			
		||||
    if (expected_checksum != 0)
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const uint16_t crc_calculated = crc16_compute(p_buffer, (length - PKT_CRC_SIZE), NULL);
 | 
			
		||||
    const uint16_t crc_received   = uint16_decode(&p_buffer[length - PKT_CRC_SIZE]);
 | 
			
		||||
    if (crc_calculated != crc_received)
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -131,7 +159,7 @@ static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length)
 | 
			
		||||
 * @return sequence number of the next reliable packet expected.
 | 
			
		||||
 */
 | 
			
		||||
static __INLINE uint8_t packet_number_expected_get(void)
 | 
			
		||||
{    
 | 
			
		||||
{
 | 
			
		||||
    return (uint8_t) m_packet_expected_seq_number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -146,13 +174,13 @@ static uint8_t header_checksum_calculate(const uint8_t * p_hdr)
 | 
			
		||||
{
 | 
			
		||||
    // @note: no pointer validation check needed as already checked by calling function.
 | 
			
		||||
    uint32_t checksum;
 | 
			
		||||
    
 | 
			
		||||
    checksum  = p_hdr[0];   
 | 
			
		||||
    checksum += p_hdr[1];          
 | 
			
		||||
    checksum += p_hdr[2];                  
 | 
			
		||||
 | 
			
		||||
    checksum  = p_hdr[0];
 | 
			
		||||
    checksum += p_hdr[1];
 | 
			
		||||
    checksum += p_hdr[2];
 | 
			
		||||
    checksum &= 0xFFu;
 | 
			
		||||
    checksum  = (~checksum + 1u);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return (uint8_t)checksum;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -162,31 +190,31 @@ static uint8_t header_checksum_calculate(const uint8_t * p_hdr)
 | 
			
		||||
static void ack_transmit(void)
 | 
			
		||||
{
 | 
			
		||||
    static uint8_t ack_packet[PKT_HDR_SIZE];
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // TX ACK packet format:
 | 
			
		||||
    // - Unreliable Packet type
 | 
			
		||||
    // - Payload Length set to 0
 | 
			
		||||
    // - Sequence Number set to 0
 | 
			
		||||
    // - Header checksum calculated
 | 
			
		||||
    // - Acknowledge Number set correctly            
 | 
			
		||||
    // - Acknowledge Number set correctly
 | 
			
		||||
    ack_packet[0] = (packet_number_expected_get() << 3u);
 | 
			
		||||
    ack_packet[1] = 0;    
 | 
			
		||||
    ack_packet[2] = 0;        
 | 
			
		||||
    ack_packet[3] = header_checksum_calculate(ack_packet); 
 | 
			
		||||
    ack_packet[1] = 0;
 | 
			
		||||
    ack_packet[2] = 0;
 | 
			
		||||
    ack_packet[3] = header_checksum_calculate(ack_packet);
 | 
			
		||||
 | 
			
		||||
    // @note: no return value check needed for hci_slip_write(...) call as acknowledgement packets 
 | 
			
		||||
    // are considered to be from system design point of view unreliable packets.Use case where 
 | 
			
		||||
    // @note: no return value check needed for hci_slip_write(...) call as acknowledgement packets
 | 
			
		||||
    // are considered to be from system design point of view unreliable packets.Use case where
 | 
			
		||||
    // underlying slip layer does not accept a packet for transmission is managed either by:
 | 
			
		||||
    // - acknowledged by possible future application packet as acknowledgement number header field 
 | 
			
		||||
    // is included 
 | 
			
		||||
    // - protocol peer entity will retransmit the packet        
 | 
			
		||||
    UNUSED_VARIABLE(hci_slip_write(ack_packet, sizeof(ack_packet)));   
 | 
			
		||||
    // - acknowledged by possible future application packet as acknowledgement number header field
 | 
			
		||||
    // is included
 | 
			
		||||
    // - protocol peer entity will retransmit the packet
 | 
			
		||||
    UNUSED_VARIABLE(hci_slip_write(ack_packet, sizeof(ack_packet)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for validating a received packet.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data. 
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data.
 | 
			
		||||
 *
 | 
			
		||||
 * @return sequence number field of the packet header with unrelated data masked out.
 | 
			
		||||
 */
 | 
			
		||||
@@ -201,14 +229,14 @@ static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer)
 | 
			
		||||
static __INLINE void packet_number_expected_inc(void)
 | 
			
		||||
{
 | 
			
		||||
    ++m_packet_expected_seq_number;
 | 
			
		||||
    m_packet_expected_seq_number &= 0x07u;    
 | 
			
		||||
    m_packet_expected_seq_number &= 0x07u;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for decoding a packet type field.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data. 
 | 
			
		||||
 * @param[in] length   Length of packet data in bytes.  
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data.
 | 
			
		||||
 * @param[in] length   Length of packet data in bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Packet type field or INVALID_PKT_TYPE in case of decode error.
 | 
			
		||||
 */
 | 
			
		||||
@@ -216,30 +244,30 @@ static __INLINE uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t l
 | 
			
		||||
{
 | 
			
		||||
    // @note: no pointer validation check needed as allready checked by calling function.
 | 
			
		||||
    uint32_t return_value;
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
    if (length >= PKT_HDR_SIZE)
 | 
			
		||||
    {
 | 
			
		||||
        return_value = (p_buffer[1] & 0x0Fu);
 | 
			
		||||
    }    
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return_value = INVALID_PKT_TYPE;
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return return_value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for processing a received vendor specific packet.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data. 
 | 
			
		||||
 * @param[in] length   Length of packet data in bytes.  
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data.
 | 
			
		||||
 * @param[in] length   Length of packet data in bytes.
 | 
			
		||||
 */
 | 
			
		||||
static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
    // @note: no pointer validation check needed as allready checked by calling function.
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (is_rx_pkt_valid(p_buffer, length))
 | 
			
		||||
    {
 | 
			
		||||
        // RX packet is valid: validate sequence number.
 | 
			
		||||
@@ -247,40 +275,40 @@ static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_
 | 
			
		||||
        if (packet_number_expected_get() == rx_seq_number)
 | 
			
		||||
        {
 | 
			
		||||
            // Sequence number is valid: transmit acknowledgement.
 | 
			
		||||
            packet_number_expected_inc();                    
 | 
			
		||||
            ack_transmit();                    
 | 
			
		||||
            packet_number_expected_inc();
 | 
			
		||||
            ack_transmit();
 | 
			
		||||
 | 
			
		||||
            m_is_slip_decode_ready = true;
 | 
			
		||||
 | 
			
		||||
            m_is_slip_decode_ready = true;            
 | 
			
		||||
            
 | 
			
		||||
            err_code = hci_mem_pool_rx_data_size_set(length);
 | 
			
		||||
            APP_ERROR_CHECK(err_code);
 | 
			
		||||
 | 
			
		||||
            err_code = hci_mem_pool_rx_produce(RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer); 
 | 
			
		||||
            err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
 | 
			
		||||
            APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
 | 
			
		||||
 | 
			
		||||
            // If memory pool RX buffer produce succeeded we register that buffer to slip layer 
 | 
			
		||||
            // otherwise we register the internal acknowledgement buffer. 
 | 
			
		||||
            // If memory pool RX buffer produce succeeded we register that buffer to slip layer
 | 
			
		||||
            // otherwise we register the internal acknowledgement buffer.
 | 
			
		||||
            err_code = hci_slip_rx_buffer_register(
 | 
			
		||||
                (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, 
 | 
			
		||||
                (err_code == NRF_SUCCESS) ? RX_BUF_SIZE : ACK_BUF_SIZE);            
 | 
			
		||||
                (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
 | 
			
		||||
                (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);
 | 
			
		||||
 | 
			
		||||
            APP_ERROR_CHECK(err_code);
 | 
			
		||||
 | 
			
		||||
            APP_ERROR_CHECK(err_code);                
 | 
			
		||||
                    
 | 
			
		||||
            if (m_transport_event_handle != NULL)
 | 
			
		||||
            {
 | 
			
		||||
                // Send application event of RX packet reception.
 | 
			
		||||
                const hci_transport_evt_t evt = {HCI_TRANSPORT_RX_RDY};
 | 
			
		||||
                m_transport_event_handle(evt);
 | 
			
		||||
            }                     
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // RX packet discarded: sequence number not valid, set the same buffer to slip layer in 
 | 
			
		||||
            // order to avoid buffer overrun. 
 | 
			
		||||
            err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE);                            
 | 
			
		||||
            APP_ERROR_CHECK(err_code);                            
 | 
			
		||||
                
 | 
			
		||||
            // As packet did not have expected sequence number: send acknowledgement with the 
 | 
			
		||||
            // RX packet discarded: sequence number not valid, set the same buffer to slip layer in
 | 
			
		||||
            // order to avoid buffer overrun.
 | 
			
		||||
            err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
 | 
			
		||||
            APP_ERROR_CHECK(err_code);
 | 
			
		||||
 | 
			
		||||
            // As packet did not have expected sequence number: send acknowledgement with the
 | 
			
		||||
            // current expected sequence number.
 | 
			
		||||
            ack_transmit();
 | 
			
		||||
        }
 | 
			
		||||
@@ -288,14 +316,14 @@ static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // RX packet discarded: reset the same buffer to slip layer in order to avoid buffer
 | 
			
		||||
        // overrun. 
 | 
			
		||||
        err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE);                            
 | 
			
		||||
        APP_ERROR_CHECK(err_code);                                    
 | 
			
		||||
    }            
 | 
			
		||||
        // overrun.
 | 
			
		||||
        err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
 | 
			
		||||
        APP_ERROR_CHECK(err_code);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol 
 | 
			
		||||
/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol
 | 
			
		||||
 * entity acknowledgment is pending.
 | 
			
		||||
 *
 | 
			
		||||
 * @return sequence number of a reliable TX packet for which peer protocol entity acknowledgement
 | 
			
		||||
@@ -313,43 +341,43 @@ static __INLINE uint8_t packet_number_to_transmit_get(void)
 | 
			
		||||
 */
 | 
			
		||||
static __INLINE uint8_t expected_ack_number_get(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t seq_nmbr = packet_number_to_transmit_get(); 
 | 
			
		||||
    uint8_t seq_nmbr = packet_number_to_transmit_get();
 | 
			
		||||
    ++seq_nmbr;
 | 
			
		||||
    seq_nmbr &= 0x07u;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return seq_nmbr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for processing a received acknowledgement packet.
 | 
			
		||||
 *
 | 
			
		||||
 * Verifies does the received acknowledgement packet has the expected acknowledgement number and 
 | 
			
		||||
 * that the header checksum is correct. 
 | 
			
		||||
 * Verifies does the received acknowledgement packet has the expected acknowledgement number and
 | 
			
		||||
 * that the header checksum is correct.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data. 
 | 
			
		||||
 * @param[in] p_buffer Pointer to the packet data.
 | 
			
		||||
 *
 | 
			
		||||
 * @return true if valid acknowledgement packet received.
 | 
			
		||||
 */
 | 
			
		||||
static __INLINE bool rx_ack_pkt_type_handle(const uint8_t * p_buffer)
 | 
			
		||||
{
 | 
			
		||||
    // @note: no pointer validation check needed as allready checked by calling function.
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // Verify header checksum.
 | 
			
		||||
    const uint32_t expected_checksum = 
 | 
			
		||||
    const uint32_t expected_checksum =
 | 
			
		||||
        ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
 | 
			
		||||
    if (expected_checksum != 0)
 | 
			
		||||
    {    
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    const uint8_t ack_number = (p_buffer[0] >> 3u) & 0x07u;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // Verify expected acknowledgment number.
 | 
			
		||||
    return (ack_number == expected_ack_number_get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for incrementing the sequence number counter of the TX packet. 
 | 
			
		||||
/**@brief Function for incrementing the sequence number counter of the TX packet.
 | 
			
		||||
 */
 | 
			
		||||
static __INLINE void packet_number_tx_inc(void)
 | 
			
		||||
{
 | 
			
		||||
@@ -365,84 +393,84 @@ static __INLINE void packet_number_tx_inc(void)
 | 
			
		||||
static void tx_sm_event_handle(tx_event_t event)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    switch (m_tx_state)
 | 
			
		||||
    {
 | 
			
		||||
        case TX_STATE_IDLE:
 | 
			
		||||
            if (event == TX_EVENT_STATE_ENTRY)
 | 
			
		||||
            {                 
 | 
			
		||||
            {
 | 
			
		||||
                err_code = app_timer_stop(m_app_timer_id);
 | 
			
		||||
                APP_ERROR_CHECK(err_code);
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                // Send TX-done event if registered handler exists.
 | 
			
		||||
                if (m_transport_tx_done_handle != NULL)                
 | 
			
		||||
                if (m_transport_tx_done_handle != NULL)
 | 
			
		||||
                {
 | 
			
		||||
                    m_transport_tx_done_handle(m_tx_done_result_code);
 | 
			
		||||
                }                
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
        case TX_STATE_PENDING:
 | 
			
		||||
            if (event == TX_EVENT_SLIP_TX_DONE)
 | 
			
		||||
            {     
 | 
			
		||||
                // @note: this call should always succeed as called from HCI_SLIP_TX_DONE context 
 | 
			
		||||
            {
 | 
			
		||||
                // @note: this call should always succeed as called from HCI_SLIP_TX_DONE context
 | 
			
		||||
                // and error cases are managed by dedicated error event from the slip layer.
 | 
			
		||||
                err_code = hci_slip_write(mp_tx_buffer, 
 | 
			
		||||
                                         (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));  
 | 
			
		||||
                APP_ERROR_CHECK(err_code);                                                  
 | 
			
		||||
                tx_sm_state_change(TX_STATE_ACTIVE);                                              
 | 
			
		||||
            }        
 | 
			
		||||
                err_code = hci_slip_write(mp_tx_buffer,
 | 
			
		||||
                                         (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));
 | 
			
		||||
                APP_ERROR_CHECK(err_code);
 | 
			
		||||
                tx_sm_state_change(TX_STATE_ACTIVE);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
        case TX_STATE_ACTIVE:
 | 
			
		||||
            switch (event)
 | 
			
		||||
            {
 | 
			
		||||
                case TX_EVENT_VALID_RX_ACK:                    
 | 
			
		||||
                    // Tx sequence number counter incremented as packet transmission 
 | 
			
		||||
                case TX_EVENT_VALID_RX_ACK:
 | 
			
		||||
                    // Tx sequence number counter incremented as packet transmission
 | 
			
		||||
                    // acknowledged by peer transport entity.
 | 
			
		||||
                    packet_number_tx_inc();                                  
 | 
			
		||||
                    packet_number_tx_inc();
 | 
			
		||||
                    tx_sm_state_change(TX_STATE_IDLE);
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                case TX_EVENT_STATE_ENTRY:
 | 
			
		||||
                    m_tx_retry_counter = 0;
 | 
			
		||||
                    err_code = app_timer_start(m_app_timer_id, 
 | 
			
		||||
                                               RETRANSMISSION_TIMEOUT_IN_TICKS, 
 | 
			
		||||
                    err_code = app_timer_start(m_app_timer_id,
 | 
			
		||||
                                               RETRANSMISSION_TIMEOUT_IN_TICKS,
 | 
			
		||||
                                               NULL);
 | 
			
		||||
                    APP_ERROR_CHECK(err_code);
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                case TX_EVENT_TIMEOUT:
 | 
			
		||||
                    if (m_tx_retry_counter != MAX_RETRY_COUNT)
 | 
			
		||||
                    {
 | 
			
		||||
                        ++m_tx_retry_counter;
 | 
			
		||||
                        // @note: no return value check done for hci_slip_write(...) call as current 
 | 
			
		||||
                        // system design allows use case where retransmission is not accepted by the 
 | 
			
		||||
                        // slip layer due to existing acknowledgement packet transmission in the 
 | 
			
		||||
                        // slip layer. 
 | 
			
		||||
                        UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer, 
 | 
			
		||||
                                                      (m_tx_buffer_length + 
 | 
			
		||||
                                                      PKT_HDR_SIZE        + 
 | 
			
		||||
                                                      PKT_CRC_SIZE)));                
 | 
			
		||||
                    }    
 | 
			
		||||
                        // @note: no return value check done for hci_slip_write(...) call as current
 | 
			
		||||
                        // system design allows use case where retransmission is not accepted by the
 | 
			
		||||
                        // slip layer due to existing acknowledgement packet transmission in the
 | 
			
		||||
                        // slip layer.
 | 
			
		||||
                        UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer,
 | 
			
		||||
                                                      (m_tx_buffer_length +
 | 
			
		||||
                                                      PKT_HDR_SIZE        +
 | 
			
		||||
                                                      PKT_CRC_SIZE)));
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        // Application packet retransmission count reached: 
 | 
			
		||||
                        // Application packet retransmission count reached:
 | 
			
		||||
                        // - set correct TX done event callback function result code
 | 
			
		||||
                        // - execute state change    
 | 
			
		||||
                        // - execute state change
 | 
			
		||||
                        // @note: m_tx_retry_counter is reset in TX_STATE_ACTIVE state entry.
 | 
			
		||||
                        m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;         
 | 
			
		||||
                        m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;
 | 
			
		||||
                        tx_sm_state_change(TX_STATE_IDLE);
 | 
			
		||||
                    }                
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    // No implementation needed.
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
        default:        
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            // No implementation needed.
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
@@ -465,73 +493,73 @@ static void tx_sm_state_change(tx_state_t new_state)
 | 
			
		||||
 * @param[in] event The event structure.
 | 
			
		||||
 */
 | 
			
		||||
void slip_event_handle(hci_slip_evt_t event)
 | 
			
		||||
{    
 | 
			
		||||
{
 | 
			
		||||
    uint32_t return_code;
 | 
			
		||||
    uint32_t err_code;    
 | 
			
		||||
    
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    switch (event.evt_type)
 | 
			
		||||
    {
 | 
			
		||||
        case HCI_SLIP_TX_DONE:   
 | 
			
		||||
        case HCI_SLIP_TX_DONE:
 | 
			
		||||
            tx_sm_event_handle(TX_EVENT_SLIP_TX_DONE);
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
        case HCI_SLIP_RX_RDY:
 | 
			
		||||
            return_code = packet_type_decode(event.packet, event.packet_length);
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            switch (return_code)
 | 
			
		||||
            {
 | 
			
		||||
                case PKT_TYPE_VENDOR_SPECIFIC:
 | 
			
		||||
                    rx_vendor_specific_pkt_type_handle(event.packet, event.packet_length);
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                case PKT_TYPE_ACK:
 | 
			
		||||
                    if (rx_ack_pkt_type_handle(event.packet))
 | 
			
		||||
                    {
 | 
			
		||||
                        // Valid expected acknowledgement packet received: set correct TX done event 
 | 
			
		||||
                        // Valid expected acknowledgement packet received: set correct TX done event
 | 
			
		||||
                        // callback function result code and execute state change.
 | 
			
		||||
                        m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS; 
 | 
			
		||||
                        m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS;
 | 
			
		||||
                        tx_sm_event_handle(TX_EVENT_VALID_RX_ACK);
 | 
			
		||||
                    }
 | 
			
		||||
                
 | 
			
		||||
                /* fall-through */                
 | 
			
		||||
 | 
			
		||||
                /* fall-through */
 | 
			
		||||
                default:
 | 
			
		||||
                    // RX packet dropped: reset memory buffer to slip in order to avoid RX buffer 
 | 
			
		||||
                    // overflow. 
 | 
			
		||||
                    // If existing mem pool produced RX buffer exists reuse that one. If existing 
 | 
			
		||||
                    // mem pool produced RX buffer does not exist try to produce new one. If 
 | 
			
		||||
                    // producing fails use the internal acknowledgement buffer.                    
 | 
			
		||||
                    // RX packet dropped: reset memory buffer to slip in order to avoid RX buffer
 | 
			
		||||
                    // overflow.
 | 
			
		||||
                    // If existing mem pool produced RX buffer exists reuse that one. If existing
 | 
			
		||||
                    // mem pool produced RX buffer does not exist try to produce new one. If
 | 
			
		||||
                    // producing fails use the internal acknowledgement buffer.
 | 
			
		||||
                    if (mp_slip_used_rx_buffer != NULL)
 | 
			
		||||
                    {
 | 
			
		||||
                        err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE);                                                            
 | 
			
		||||
                        APP_ERROR_CHECK(err_code);                                                                
 | 
			
		||||
                        err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
 | 
			
		||||
                        APP_ERROR_CHECK(err_code);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        err_code = hci_mem_pool_rx_produce(RX_BUF_SIZE, 
 | 
			
		||||
                                                           (void **)&mp_slip_used_rx_buffer); 
 | 
			
		||||
                        APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || 
 | 
			
		||||
                        err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE,
 | 
			
		||||
                                                           (void **)&mp_slip_used_rx_buffer);
 | 
			
		||||
                        APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) ||
 | 
			
		||||
                                            (err_code == NRF_ERROR_NO_MEM));
 | 
			
		||||
 | 
			
		||||
                        err_code = hci_slip_rx_buffer_register(
 | 
			
		||||
                            (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, 
 | 
			
		||||
                            (err_code == NRF_SUCCESS) ? RX_BUF_SIZE : ACK_BUF_SIZE);            
 | 
			
		||||
                        APP_ERROR_CHECK(err_code);                                                                
 | 
			
		||||
                            (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
 | 
			
		||||
                            (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);
 | 
			
		||||
                        APP_ERROR_CHECK(err_code);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case HCI_SLIP_RX_OVERFLOW:
 | 
			
		||||
            err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE);                                                            
 | 
			
		||||
            APP_ERROR_CHECK(err_code);                                                                
 | 
			
		||||
            err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE);
 | 
			
		||||
            APP_ERROR_CHECK(err_code);
 | 
			
		||||
            break;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        case HCI_SLIP_ERROR:
 | 
			
		||||
            APP_ERROR_HANDLER(event.evt_type);
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            APP_ERROR_HANDLER(event.evt_type); 
 | 
			
		||||
            APP_ERROR_HANDLER(event.evt_type);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -539,36 +567,36 @@ void slip_event_handle(hci_slip_evt_t event)
 | 
			
		||||
 | 
			
		||||
uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;    
 | 
			
		||||
    
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    m_transport_event_handle = event_handler;
 | 
			
		||||
    err_code                 = hci_slip_evt_handler_register(slip_event_handle); 
 | 
			
		||||
    APP_ERROR_CHECK(err_code);                                                                        
 | 
			
		||||
    
 | 
			
		||||
    return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;        
 | 
			
		||||
    err_code                 = hci_slip_evt_handler_register(slip_event_handle);
 | 
			
		||||
    APP_ERROR_CHECK(err_code);
 | 
			
		||||
 | 
			
		||||
    return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;    
 | 
			
		||||
    
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    m_transport_tx_done_handle = event_handler;
 | 
			
		||||
    err_code                   = hci_slip_evt_handler_register(slip_event_handle);    
 | 
			
		||||
    APP_ERROR_CHECK(err_code);                                                                    
 | 
			
		||||
    
 | 
			
		||||
    return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;        
 | 
			
		||||
    err_code                   = hci_slip_evt_handler_register(slip_event_handle);
 | 
			
		||||
    APP_ERROR_CHECK(err_code);
 | 
			
		||||
 | 
			
		||||
    return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for handling the application packet retransmission timeout.
 | 
			
		||||
 *        
 | 
			
		||||
 * This function is registered in the @ref app_timer module when a timer is created on 
 | 
			
		||||
 * @ref hci_transport_open. 
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function must be executed in APP-LO context otherwise retransmission behaviour is 
 | 
			
		||||
 * This function is registered in the @ref app_timer module when a timer is created on
 | 
			
		||||
 * @ref hci_transport_open.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function must be executed in APP-LO context otherwise retransmission behaviour is
 | 
			
		||||
 *       undefined, see @ref nrf51_system_integration_serialization.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_context The timeout context.
 | 
			
		||||
 */
 | 
			
		||||
void hci_transport_timeout_handle(void * p_context)
 | 
			
		||||
@@ -587,32 +615,32 @@ uint32_t hci_transport_open(void)
 | 
			
		||||
    m_packet_expected_seq_number = INITIAL_ACK_NUMBER_EXPECTED;
 | 
			
		||||
    m_packet_transmit_seq_number = INITIAL_ACK_NUMBER_TX;
 | 
			
		||||
    m_tx_done_result_code        = HCI_TRANSPORT_TX_DONE_FAILURE;
 | 
			
		||||
    
 | 
			
		||||
    uint32_t err_code = app_timer_create(&m_app_timer_id, 
 | 
			
		||||
                                         APP_TIMER_MODE_REPEATED, 
 | 
			
		||||
 | 
			
		||||
    uint32_t err_code = app_timer_create(&m_app_timer_id,
 | 
			
		||||
                                         APP_TIMER_MODE_REPEATED,
 | 
			
		||||
                                         hci_transport_timeout_handle);
 | 
			
		||||
    if (err_code != NRF_SUCCESS)
 | 
			
		||||
    {    
 | 
			
		||||
        // @note: conduct required interface adjustment.
 | 
			
		||||
        return NRF_ERROR_INTERNAL;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    err_code = hci_mem_pool_open();
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
    
 | 
			
		||||
    err_code = hci_slip_open();
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
    
 | 
			
		||||
    err_code = hci_mem_pool_rx_produce(RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
 | 
			
		||||
    if (err_code != NRF_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
        // @note: conduct required interface adjustment.
 | 
			
		||||
        return NRF_ERROR_INTERNAL;
 | 
			
		||||
    }   
 | 
			
		||||
    
 | 
			
		||||
    err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE);
 | 
			
		||||
    
 | 
			
		||||
    return err_code;    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err_code = hci_mem_pool_open();
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    err_code = hci_slip_open();
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
 | 
			
		||||
    if (err_code != NRF_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
        // @note: conduct required interface adjustment.
 | 
			
		||||
        return NRF_ERROR_INTERNAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -622,31 +650,31 @@ uint32_t hci_transport_close(void)
 | 
			
		||||
 | 
			
		||||
    m_transport_tx_done_handle = NULL;
 | 
			
		||||
    m_transport_event_handle   = NULL;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    err_code = hci_mem_pool_close();
 | 
			
		||||
    APP_ERROR_CHECK(err_code);    
 | 
			
		||||
    APP_ERROR_CHECK(err_code);
 | 
			
		||||
    err_code = hci_slip_close();
 | 
			
		||||
    APP_ERROR_CHECK(err_code);    
 | 
			
		||||
    
 | 
			
		||||
    APP_ERROR_CHECK(err_code);
 | 
			
		||||
 | 
			
		||||
    // @note: NRF_ERROR_NO_MEM is the only return value which should never be returned.
 | 
			
		||||
    err_code = app_timer_stop(m_app_timer_id);
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(err_code != NRF_ERROR_NO_MEM);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory)
 | 
			
		||||
{
 | 
			
		||||
    const uint32_t err_code = hci_mem_pool_tx_alloc((void **)pp_memory);    
 | 
			
		||||
    const uint32_t err_code = hci_mem_pool_tx_alloc((void **)pp_memory);
 | 
			
		||||
    if (err_code == NRF_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
        // @note: no need to validate pp_memory against null as validation has already been done 
 | 
			
		||||
        // @note: no need to validate pp_memory against null as validation has already been done
 | 
			
		||||
        // by hci_mem_pool_tx_alloc(...) and visible to us from the method return code.
 | 
			
		||||
        //lint -e(413) "Likely use of null pointer"        
 | 
			
		||||
        *pp_memory += PKT_HDR_SIZE; 
 | 
			
		||||
        //lint -e(413) "Likely use of null pointer"
 | 
			
		||||
        *pp_memory += PKT_HDR_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -663,11 +691,11 @@ uint32_t hci_transport_tx_free(void)
 | 
			
		||||
 */
 | 
			
		||||
static __INLINE uint8_t tx_packet_byte_zero_construct(void)
 | 
			
		||||
{
 | 
			
		||||
    const uint32_t value = DATA_INTEGRITY_MASK                  | 
 | 
			
		||||
                           RELIABLE_PKT_MASK                    | 
 | 
			
		||||
                           (packet_number_expected_get() << 3u) | 
 | 
			
		||||
                           packet_number_to_transmit_get();   
 | 
			
		||||
    
 | 
			
		||||
    const uint32_t value = DATA_INTEGRITY_MASK                  |
 | 
			
		||||
                           RELIABLE_PKT_MASK                    |
 | 
			
		||||
                           (packet_number_expected_get() << 3u) |
 | 
			
		||||
                           packet_number_to_transmit_get();
 | 
			
		||||
 | 
			
		||||
    return (uint8_t) value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -675,41 +703,41 @@ static __INLINE uint8_t tx_packet_byte_zero_construct(void)
 | 
			
		||||
/**@brief Function for handling the application packet write request in tx-idle state.
 | 
			
		||||
 */
 | 
			
		||||
static uint32_t pkt_write_handle(void)
 | 
			
		||||
{   
 | 
			
		||||
    uint32_t err_code;     
 | 
			
		||||
    
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    // Set packet header fields.
 | 
			
		||||
 | 
			
		||||
    mp_tx_buffer   -= PKT_HDR_SIZE;
 | 
			
		||||
    mp_tx_buffer[0] = tx_packet_byte_zero_construct();
 | 
			
		||||
                
 | 
			
		||||
    const uint16_t type_and_length_fields = ((m_tx_buffer_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC);            
 | 
			
		||||
 | 
			
		||||
    const uint16_t type_and_length_fields = ((m_tx_buffer_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC);
 | 
			
		||||
    // @note: no use case for uint16_encode(...) return value.
 | 
			
		||||
    UNUSED_VARIABLE(uint16_encode(type_and_length_fields, &(mp_tx_buffer[1])));
 | 
			
		||||
    mp_tx_buffer[3] = header_checksum_calculate(mp_tx_buffer);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // Calculate, append CRC to the packet and write it.
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    const uint16_t crc = crc16_compute(mp_tx_buffer, (PKT_HDR_SIZE + m_tx_buffer_length), NULL);
 | 
			
		||||
    // @note: no use case for uint16_encode(...) return value.
 | 
			
		||||
    UNUSED_VARIABLE(uint16_encode(crc, &(mp_tx_buffer[PKT_HDR_SIZE + m_tx_buffer_length])));        
 | 
			
		||||
    err_code = hci_slip_write(mp_tx_buffer, (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));        
 | 
			
		||||
    UNUSED_VARIABLE(uint16_encode(crc, &(mp_tx_buffer[PKT_HDR_SIZE + m_tx_buffer_length])));
 | 
			
		||||
    err_code = hci_slip_write(mp_tx_buffer, (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));
 | 
			
		||||
    switch (err_code)
 | 
			
		||||
    {
 | 
			
		||||
        case NRF_SUCCESS:
 | 
			
		||||
            tx_sm_state_change(TX_STATE_ACTIVE);
 | 
			
		||||
            break;
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
        case NRF_ERROR_NO_MEM:
 | 
			
		||||
            tx_sm_state_change(TX_STATE_PENDING);            
 | 
			
		||||
            tx_sm_state_change(TX_STATE_PENDING);
 | 
			
		||||
            err_code = NRF_SUCCESS;
 | 
			
		||||
            break;
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            // No implementation needed.
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -717,17 +745,17 @@ static uint32_t pkt_write_handle(void)
 | 
			
		||||
uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (p_buffer)
 | 
			
		||||
    {          
 | 
			
		||||
    {
 | 
			
		||||
        switch (m_tx_state)
 | 
			
		||||
        {
 | 
			
		||||
            case TX_STATE_IDLE:
 | 
			
		||||
                mp_tx_buffer       = (uint8_t *)p_buffer;
 | 
			
		||||
                m_tx_buffer_length = length;            
 | 
			
		||||
                m_tx_buffer_length = length;
 | 
			
		||||
                err_code = pkt_write_handle();
 | 
			
		||||
                break;
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                err_code = NRF_ERROR_NO_MEM;
 | 
			
		||||
                break;
 | 
			
		||||
@@ -737,26 +765,26 @@ uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = NRF_ERROR_NULL;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return err_code;    
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (pp_buffer != NULL && p_length != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t length = 0; 
 | 
			
		||||
        
 | 
			
		||||
        uint32_t length = 0;
 | 
			
		||||
 | 
			
		||||
        if (m_is_slip_decode_ready)
 | 
			
		||||
        {
 | 
			
		||||
            m_is_slip_decode_ready = false;
 | 
			
		||||
            err_code               = hci_mem_pool_rx_extract(pp_buffer, &length);
 | 
			
		||||
            length                -= (PKT_HDR_SIZE + PKT_CRC_SIZE);
 | 
			
		||||
            
 | 
			
		||||
            *p_length              = (uint16_t)length; 
 | 
			
		||||
 | 
			
		||||
            *p_length              = (uint16_t)length;
 | 
			
		||||
            *pp_buffer            += PKT_HDR_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
@@ -768,12 +796,13 @@ uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = NRF_ERROR_NULL;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer)
 | 
			
		||||
{
 | 
			
		||||
    return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE));     
 | 
			
		||||
    return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE));
 | 
			
		||||
}
 | 
			
		||||
#endif //NRF_MODULE_ENABLED(HCI_TRANSPORT)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,42 @@
 | 
			
		||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/**@file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup hci_transport HCI Transport
 | 
			
		||||
@@ -18,7 +45,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 * @brief    HCI transport module implementation.
 | 
			
		||||
 *
 | 
			
		||||
 * This module implements certain specific features from the three-wire UART transport layer, 
 | 
			
		||||
 * This module implements certain specific features from the three-wire UART transport layer,
 | 
			
		||||
 * defined by the Bluetooth specification version 4.0 [Vol 4] part D.
 | 
			
		||||
 *
 | 
			
		||||
 * \par Features supported
 | 
			
		||||
@@ -27,7 +54,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 * \par Features not supported
 | 
			
		||||
 * - Link establishment procedure: defined by chapter 8 of the specification.
 | 
			
		||||
 * - Low power: defined by chapter 9 of the specification. 
 | 
			
		||||
 * - Low power: defined by chapter 9 of the specification.
 | 
			
		||||
 *
 | 
			
		||||
 * \par Implementation specific behaviour
 | 
			
		||||
 * - As Link establishment procedure is not supported following static link configuration parameters
 | 
			
		||||
@@ -35,54 +62,58 @@
 | 
			
		||||
 * + TX window size is 1.
 | 
			
		||||
 * + 16 bit CCITT-CRC must be used.
 | 
			
		||||
 * + Out of frame software flow control not supported.
 | 
			
		||||
 * + Parameters specific for resending reliable packets are compile time configurable (clarifed 
 | 
			
		||||
 * + Parameters specific for resending reliable packets are compile time configurable (clarifed
 | 
			
		||||
 * later in this document).
 | 
			
		||||
 * + Acknowledgement packet transmissions are not timeout driven , meaning they are delivered for 
 | 
			
		||||
 * transmission within same context which the corresponding application packet was received. 
 | 
			
		||||
 * + Acknowledgement packet transmissions are not timeout driven , meaning they are delivered for
 | 
			
		||||
 * transmission within same context which the corresponding application packet was received.
 | 
			
		||||
 *
 | 
			
		||||
 * \par Implementation specific limitations
 | 
			
		||||
 * Current implementation has the following limitations which will have impact to system wide 
 | 
			
		||||
 * Current implementation has the following limitations which will have impact to system wide
 | 
			
		||||
 * behaviour:
 | 
			
		||||
 * - Delayed acknowledgement scheduling not implemented: 
 | 
			
		||||
 * There exists a possibility that acknowledgement TX packet and application TX packet will collide 
 | 
			
		||||
 * in the TX pipeline having the end result that acknowledgement packet will be excluded from the TX 
 | 
			
		||||
 * - Delayed acknowledgement scheduling not implemented:
 | 
			
		||||
 * There exists a possibility that acknowledgement TX packet and application TX packet will collide
 | 
			
		||||
 * in the TX pipeline having the end result that acknowledgement packet will be excluded from the TX
 | 
			
		||||
 * pipeline which will trigger the retransmission algorithm within the peer protocol entity.
 | 
			
		||||
 * - Delayed retransmission scheduling not implemented:  
 | 
			
		||||
 * - Delayed retransmission scheduling not implemented:
 | 
			
		||||
 * There exists a possibility that retransmitted application TX packet and acknowledgement TX packet
 | 
			
		||||
 * will collide in the TX pipeline having the end result that retransmitted application TX packet 
 | 
			
		||||
 * will collide in the TX pipeline having the end result that retransmitted application TX packet
 | 
			
		||||
 * will be excluded from the TX pipeline.
 | 
			
		||||
 * - Processing of the acknowledgement number from RX application packets:
 | 
			
		||||
 * Acknowledgement number is not processed from the RX application packets having the end result 
 | 
			
		||||
 * Acknowledgement number is not processed from the RX application packets having the end result
 | 
			
		||||
 * that unnecessary application packet retransmissions can occur.
 | 
			
		||||
 *
 | 
			
		||||
 * The application TX packet processing flow is illustrated by the statemachine below. 
 | 
			
		||||
 * The application TX packet processing flow is illustrated by the statemachine below.
 | 
			
		||||
 *
 | 
			
		||||
 * @image html hci_transport_tx_sm.png "TX - application packet statemachine"
 | 
			
		||||
 * @image html hci_transport_tx_sm.svg "TX - application packet statemachine"
 | 
			
		||||
 *
 | 
			
		||||
 * \par Component specific configuration options
 | 
			
		||||
 *
 | 
			
		||||
 * The following compile time configuration options are available, and used to configure the 
 | 
			
		||||
 * application TX packet retransmission interval, in order to suite various application specific 
 | 
			
		||||
 * The following compile time configuration options are available, and used to configure the
 | 
			
		||||
 * application TX packet retransmission interval, in order to suite various application specific
 | 
			
		||||
 * implementations:
 | 
			
		||||
 * - MAC_PACKET_SIZE_IN_BITS Maximum size of a single application packet in bits. 
 | 
			
		||||
 * - USED_BAUD_RATE Used uart baudrate. 
 | 
			
		||||
 * - MAC_PACKET_SIZE_IN_BITS Maximum size of a single application packet in bits.
 | 
			
		||||
 * - USED_BAUD_RATE Used uart baudrate.
 | 
			
		||||
 *
 | 
			
		||||
 * The following compile time configuration option is available to configure module specific 
 | 
			
		||||
 * The following compile time configuration option is available to configure module specific
 | 
			
		||||
 * behaviour:
 | 
			
		||||
 * - MAX_RETRY_COUNT Max retransmission retry count for applicaton packets.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
#ifndef HCI_TRANSPORT_H__
 | 
			
		||||
#define HCI_TRANSPORT_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "nrf_error.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**@brief Generic event callback function events. */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    HCI_TRANSPORT_RX_RDY,               /**< An event indicating that RX packet is ready for read. */
 | 
			
		||||
    HCI_TRANSPORT_EVT_TYPE_MAX          /**< Enumeration upper bound. */  
 | 
			
		||||
    HCI_TRANSPORT_EVT_TYPE_MAX          /**< Enumeration upper bound. */
 | 
			
		||||
} hci_transport_evt_type_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Struct containing events from the Transport layer.
 | 
			
		||||
@@ -94,7 +125,7 @@ typedef struct
 | 
			
		||||
 | 
			
		||||
/**@brief Transport layer generic event callback function type.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] event                Transport layer event.  
 | 
			
		||||
 * @param[in] event                Transport layer event.
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*hci_transport_event_handler_t)(hci_transport_evt_t event);
 | 
			
		||||
 | 
			
		||||
@@ -102,104 +133,104 @@ typedef void (*hci_transport_event_handler_t)(hci_transport_evt_t event);
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    HCI_TRANSPORT_TX_DONE_SUCCESS,      /**< Transmission success, peer transport entity has acknowledged the transmission. */
 | 
			
		||||
    HCI_TRANSPORT_TX_DONE_FAILURE       /**< Transmission failure. */    
 | 
			
		||||
    HCI_TRANSPORT_TX_DONE_FAILURE       /**< Transmission failure. */
 | 
			
		||||
} hci_transport_tx_done_result_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Transport layer TX done event callback function type.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] result                TX done event result code. 
 | 
			
		||||
 * @param[in] result                TX done event result code.
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*hci_transport_tx_done_handler_t)(hci_transport_tx_done_result_t result);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for registering a generic event handler.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Multiple registration requests will overwrite any possible existing registration. 
 | 
			
		||||
 * @note Multiple registration requests will overwrite any possible existing registration.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] event_handler         The function to be called by the transport layer upon an event.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.    
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for registering a handler for TX done event.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Multiple registration requests will overwrite any possible existing registration. 
 | 
			
		||||
 * @note Multiple registration requests will overwrite any possible existing registration.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] event_handler         The function to be called by the transport layer upon TX done
 | 
			
		||||
 *                                  event.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.    
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler);
 | 
			
		||||
                                        
 | 
			
		||||
 | 
			
		||||
/**@brief Function for opening the transport channel and initializing the transport layer.
 | 
			
		||||
 *
 | 
			
		||||
 * @warning Must not be called for a channel which has been allready opened. 
 | 
			
		||||
 * 
 | 
			
		||||
 * @warning Must not be called for a channel which has been allready opened.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.
 | 
			
		||||
 * @retval NRF_ERROR_INTERNAL       Operation failure. Internal error ocurred. 
 | 
			
		||||
 * @retval NRF_ERROR_INTERNAL       Operation failure. Internal error ocurred.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_open(void);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for closing the transport channel.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Can be called multiple times and also for not opened channel.
 | 
			
		||||
 * 
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.  
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_close(void);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for allocating tx packet memory.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out] pp_memory            Pointer to the packet data.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Memory was allocated.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM         Operation failure. No memory available.
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.   
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for freeing tx packet memory.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Memory management works in FIFO principle meaning that free order must match the alloc 
 | 
			
		||||
 * @note Memory management works in FIFO principle meaning that free order must match the alloc
 | 
			
		||||
 *       order.
 | 
			
		||||
 * 
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Memory was freed.   
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Memory was freed.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_tx_free(void);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for writing a packet.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Completion of this method does not guarantee that actual peripheral transmission would 
 | 
			
		||||
 * @note Completion of this method does not guarantee that actual peripheral transmission would
 | 
			
		||||
 *       have completed.
 | 
			
		||||
 *
 | 
			
		||||
 * @note In case of 0 byte packet length write request, message will consist of only transport 
 | 
			
		||||
 *       module specific headers.  
 | 
			
		||||
 * @note In case of 0 byte packet length write request, message will consist of only transport
 | 
			
		||||
 *       module specific headers.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Packet was added to the transmission queue 
 | 
			
		||||
 *                                  and an event will be send upon transmission completion. 
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Packet was added to the transmission queue
 | 
			
		||||
 *                                  and an event will be send upon transmission completion.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM         Operation failure. Transmission queue is full and packet was not
 | 
			
		||||
 *                                  added to the transmission queue. User should wait for 
 | 
			
		||||
 *                                  added to the transmission queue. User should wait for
 | 
			
		||||
 *                                  a appropriate event prior issuing this operation again.
 | 
			
		||||
 * @retval NRF_ERROR_DATA_SIZE      Operation failure. Packet size exceeds limit.   
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.  
 | 
			
		||||
 * @retval NRF_ERROR_DATA_SIZE      Operation failure. Packet size exceeds limit.
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.
 | 
			
		||||
 * @retval NRF_ERROR_INVALID_STATE  Operation failure. Channel is not open.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for extracting received packet.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Extracted memory can't be reused by the underlying transport layer untill freed by call to 
 | 
			
		||||
 * @note Extracted memory can't be reused by the underlying transport layer untill freed by call to
 | 
			
		||||
 *       hci_transport_rx_pkt_consume().
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out] pp_buffer            Pointer to the packet data.
 | 
			
		||||
 * @param[out] p_length             Length of packet data in bytes.  
 | 
			
		||||
 * @param[out] p_length             Length of packet data in bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Packet was extracted. 
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. Packet was extracted.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM         Operation failure. No packet available to extract.
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.   
 | 
			
		||||
 * @retval NRF_ERROR_NULL           Operation failure. NULL pointer supplied.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length);
 | 
			
		||||
 | 
			
		||||
@@ -209,12 +240,17 @@ uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length)
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_buffer              Pointer to the buffer that has been consumed.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success. 
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM         Operation failure. No packet available to consume. 
 | 
			
		||||
 * @retval NRF_ERROR_INVALID_ADDR   Operation failure. Not a valid pointer. 
 | 
			
		||||
 * @retval NRF_SUCCESS              Operation success.
 | 
			
		||||
 * @retval NRF_ERROR_NO_MEM         Operation failure. No packet available to consume.
 | 
			
		||||
 * @retval NRF_ERROR_INVALID_ADDR   Operation failure. Not a valid pointer.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // HCI_TRANSPORT_H__
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,50 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
#if NRF_MODULE_ENABLED(APP_SCHEDULER)
 | 
			
		||||
#include "app_scheduler.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "nrf_soc.h"
 | 
			
		||||
#include "nrf_assert.h"
 | 
			
		||||
#include "app_util.h"
 | 
			
		||||
#include "app_util_platform.h"
 | 
			
		||||
 | 
			
		||||
/**@brief Structure for holding a scheduled event header. */
 | 
			
		||||
@@ -35,10 +63,15 @@ static volatile uint8_t m_queue_end_index;      /**< Index of queue entry at the
 | 
			
		||||
static uint16_t         m_queue_event_size;     /**< Maximum event size in queue. */
 | 
			
		||||
static uint16_t         m_queue_size;           /**< Number of queue entries. */
 | 
			
		||||
 | 
			
		||||
#ifdef APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
#if APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
static uint16_t m_max_queue_utilization;    /**< Maximum observed queue utilization. */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if APP_SCHEDULER_WITH_PAUSE
 | 
			
		||||
static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing
 | 
			
		||||
                                                     and resuming the scheduler. */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**@brief Function for incrementing a queue index, and handle wrap-around.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   index   Old index.
 | 
			
		||||
@@ -89,7 +122,7 @@ uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event
 | 
			
		||||
    m_queue_event_size    = event_size;
 | 
			
		||||
    m_queue_size          = queue_size;
 | 
			
		||||
 | 
			
		||||
#ifdef APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
#if APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
    m_max_queue_utilization = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -97,7 +130,17 @@ uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
uint16_t app_sched_queue_space_get()
 | 
			
		||||
{
 | 
			
		||||
    uint16_t start = m_queue_start_index;
 | 
			
		||||
    uint16_t end   = m_queue_end_index;
 | 
			
		||||
    uint16_t free_space = m_queue_size - ((end >= start) ?
 | 
			
		||||
                           (end - start) : (m_queue_size + 1 - start + end));
 | 
			
		||||
    return free_space;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
static void queue_utilization_check(void)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t start = m_queue_start_index;
 | 
			
		||||
@@ -115,10 +158,10 @@ uint16_t app_sched_queue_utilization_get(void)
 | 
			
		||||
{
 | 
			
		||||
    return m_max_queue_utilization;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif // APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t app_sched_event_put(void                    * p_event_data,
 | 
			
		||||
uint32_t app_sched_event_put(void const              * p_event_data,
 | 
			
		||||
                             uint16_t                  event_data_size,
 | 
			
		||||
                             app_sched_event_handler_t handler)
 | 
			
		||||
{
 | 
			
		||||
@@ -135,7 +178,7 @@ uint32_t app_sched_event_put(void                    * p_event_data,
 | 
			
		||||
            event_index       = m_queue_end_index;
 | 
			
		||||
            m_queue_end_index = next_index(m_queue_end_index);
 | 
			
		||||
 | 
			
		||||
        #ifdef APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
        #if APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
            // This function call must be protected with critical region because
 | 
			
		||||
            // it modifies 'm_max_queue_utilization'.
 | 
			
		||||
            queue_utilization_check();
 | 
			
		||||
@@ -177,51 +220,69 @@ uint32_t app_sched_event_put(void                    * p_event_data,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for reading the next event from specified event queue.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out]  pp_event_data       Pointer to pointer to event data.
 | 
			
		||||
 * @param[out]  p_event_data_size   Pointer to size of event data.
 | 
			
		||||
 * @param[out]  p_event_handler     Pointer to event handler function pointer.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS if new event, NRF_ERROR_NOT_FOUND if event queue is empty.
 | 
			
		||||
 */
 | 
			
		||||
static uint32_t app_sched_event_get(void                     ** pp_event_data,
 | 
			
		||||
                                    uint16_t *                  p_event_data_size,
 | 
			
		||||
                                    app_sched_event_handler_t * p_event_handler)
 | 
			
		||||
#if APP_SCHEDULER_WITH_PAUSE
 | 
			
		||||
void app_sched_pause(void)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code = NRF_ERROR_NOT_FOUND;
 | 
			
		||||
    CRITICAL_REGION_ENTER();
 | 
			
		||||
 | 
			
		||||
    if (!APP_SCHED_QUEUE_EMPTY())
 | 
			
		||||
    if (m_scheduler_paused_counter < UINT32_MAX)
 | 
			
		||||
    {
 | 
			
		||||
        uint16_t event_index;
 | 
			
		||||
 | 
			
		||||
        // NOTE: There is no need for a critical region here, as this function will only be called
 | 
			
		||||
        //       from app_sched_execute() from inside the main loop, so it will never interrupt
 | 
			
		||||
        //       app_sched_event_put(). Also, updating of (i.e. writing to) the start index will be
 | 
			
		||||
        //       an atomic operation.
 | 
			
		||||
        event_index         = m_queue_start_index;
 | 
			
		||||
        m_queue_start_index = next_index(m_queue_start_index);
 | 
			
		||||
 | 
			
		||||
        *pp_event_data     = &m_queue_event_data[event_index * m_queue_event_size];
 | 
			
		||||
        *p_event_data_size = m_queue_event_headers[event_index].event_data_size;
 | 
			
		||||
        *p_event_handler   = m_queue_event_headers[event_index].handler;
 | 
			
		||||
 | 
			
		||||
        err_code = NRF_SUCCESS;
 | 
			
		||||
        m_scheduler_paused_counter++;
 | 
			
		||||
    }
 | 
			
		||||
    CRITICAL_REGION_EXIT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
void app_sched_resume(void)
 | 
			
		||||
{
 | 
			
		||||
    CRITICAL_REGION_ENTER();
 | 
			
		||||
 | 
			
		||||
    if (m_scheduler_paused_counter > 0)
 | 
			
		||||
    {
 | 
			
		||||
        m_scheduler_paused_counter--;
 | 
			
		||||
    }
 | 
			
		||||
    CRITICAL_REGION_EXIT();
 | 
			
		||||
}
 | 
			
		||||
#endif //APP_SCHEDULER_WITH_PAUSE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for checking if scheduler is paused which means that should break processing
 | 
			
		||||
 *        events.
 | 
			
		||||
 *
 | 
			
		||||
 * @return    Boolean value - true if scheduler is paused, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
static __INLINE bool is_app_sched_paused(void)
 | 
			
		||||
{
 | 
			
		||||
#if APP_SCHEDULER_WITH_PAUSE
 | 
			
		||||
    return (m_scheduler_paused_counter > 0);
 | 
			
		||||
#else
 | 
			
		||||
    return false;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void app_sched_execute(void)
 | 
			
		||||
{
 | 
			
		||||
    void                    * p_event_data;
 | 
			
		||||
    uint16_t                  event_data_size;
 | 
			
		||||
    app_sched_event_handler_t event_handler;
 | 
			
		||||
 | 
			
		||||
    // Get next event (if any), and execute handler
 | 
			
		||||
    while ((app_sched_event_get(&p_event_data, &event_data_size, &event_handler) == NRF_SUCCESS))
 | 
			
		||||
    while (!is_app_sched_paused() && !APP_SCHED_QUEUE_EMPTY())
 | 
			
		||||
    {
 | 
			
		||||
        // Since this function is only called from the main loop, there is no
 | 
			
		||||
        // need for a critical region here, however a special care must be taken
 | 
			
		||||
        // regarding update of the queue start index (see the end of the loop).
 | 
			
		||||
        uint16_t event_index = m_queue_start_index;
 | 
			
		||||
 | 
			
		||||
        void * p_event_data;
 | 
			
		||||
        uint16_t event_data_size;
 | 
			
		||||
        app_sched_event_handler_t event_handler;
 | 
			
		||||
 | 
			
		||||
        p_event_data = &m_queue_event_data[event_index * m_queue_event_size];
 | 
			
		||||
        event_data_size = m_queue_event_headers[event_index].event_data_size;
 | 
			
		||||
        event_handler   = m_queue_event_headers[event_index].handler;
 | 
			
		||||
 | 
			
		||||
        event_handler(p_event_data, event_data_size);
 | 
			
		||||
 | 
			
		||||
        // Event processed, now it is safe to move the queue start index,
 | 
			
		||||
        // so the queue entry occupied by this event can be used to store
 | 
			
		||||
        // a next one.
 | 
			
		||||
        m_queue_start_index = next_index(m_queue_start_index);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif //NRF_MODULE_ENABLED(APP_SCHEDULER)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,42 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup app_scheduler Scheduler
 | 
			
		||||
@@ -44,16 +71,21 @@
 | 
			
		||||
 * @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
 | 
			
		||||
 * @endif
 | 
			
		||||
 *
 | 
			
		||||
 * @image html scheduler_working.jpg The high level design of the scheduler
 | 
			
		||||
 * @image html scheduler_working.svg The high level design of the scheduler
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef APP_SCHEDULER_H__
 | 
			
		||||
#define APP_SCHEDULER_H__
 | 
			
		||||
 | 
			
		||||
#include "sdk_config.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "app_error.h"
 | 
			
		||||
#include "app_util.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define APP_SCHED_EVENT_HEADER_SIZE 8       /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */
 | 
			
		||||
 | 
			
		||||
/**@brief Compute number of bytes required to hold the scheduler buffer.
 | 
			
		||||
@@ -66,7 +98,7 @@
 | 
			
		||||
 */
 | 
			
		||||
#define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE)                                                 \
 | 
			
		||||
            (((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1))
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
/**@brief Scheduler event handler type. */
 | 
			
		||||
typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size);
 | 
			
		||||
 | 
			
		||||
@@ -123,31 +155,41 @@ void app_sched_execute(void);
 | 
			
		||||
 * @details Puts an event into the event queue.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_event_data   Pointer to event data to be scheduled.
 | 
			
		||||
 * @param[in]   event_size   Size of event data to be scheduled.
 | 
			
		||||
 * @param[in]   event_size     Size of event data to be scheduled.
 | 
			
		||||
 * @param[in]   handler        Event handler to receive the event.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on success, otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t app_sched_event_put(void *                    p_event_data,
 | 
			
		||||
uint32_t app_sched_event_put(void const *              p_event_data,
 | 
			
		||||
                             uint16_t                  event_size,
 | 
			
		||||
                             app_sched_event_handler_t handler);
 | 
			
		||||
 | 
			
		||||
#ifdef APP_SCHEDULER_WITH_PROFILER
 | 
			
		||||
/**@brief Function for getting the maximum observed queue utilization.
 | 
			
		||||
 *
 | 
			
		||||
 * Function for tuning the module and determining QUEUE_SIZE value and thus module RAM usage.
 | 
			
		||||
 *
 | 
			
		||||
 * @note @ref APP_SCHEDULER_WITH_PROFILER must be enabled to use this functionality.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Maximum number of events in queue observed so far.
 | 
			
		||||
 */
 | 
			
		||||
uint16_t app_sched_queue_utilization_get(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef APP_SCHEDULER_WITH_PAUSE
 | 
			
		||||
/**@brief Function for getting the current amount of free space in the queue.
 | 
			
		||||
 *
 | 
			
		||||
 * @details The real amount of free space may be less if entries are being added from an interrupt.
 | 
			
		||||
 *          To get the sxact value, this function should be called from the critical section.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Amount of free space in the queue.
 | 
			
		||||
 */
 | 
			
		||||
uint16_t app_sched_queue_space_get(void);
 | 
			
		||||
 | 
			
		||||
/**@brief A function to pause the scheduler.
 | 
			
		||||
 *
 | 
			
		||||
 * @details When the scheduler is paused events are not pulled from the scheduler queue for
 | 
			
		||||
 *          processing. The function can be called multiple times. To unblock the scheduler the
 | 
			
		||||
 *          function @ref app_sched_resume has to be called the same number of times.
 | 
			
		||||
 *
 | 
			
		||||
 * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality.
 | 
			
		||||
 */
 | 
			
		||||
void app_sched_pause(void);
 | 
			
		||||
 | 
			
		||||
@@ -155,9 +197,15 @@ void app_sched_pause(void);
 | 
			
		||||
 *
 | 
			
		||||
 * @details To unblock the scheduler this function has to be called the same number of times as
 | 
			
		||||
 *          @ref app_sched_pause function.
 | 
			
		||||
 *
 | 
			
		||||
 * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality.
 | 
			
		||||
 */
 | 
			
		||||
void app_sched_resume(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // APP_SCHEDULER_H__
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,15 +1,42 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without modification,
 | 
			
		||||
 * are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
 *    list of conditions and the following disclaimer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 2. Redistributions in binary form, except as embedded into a Nordic
 | 
			
		||||
 *    Semiconductor ASA integrated circuit in a product or a software update for
 | 
			
		||||
 *    such product, must reproduce the above copyright notice, this list of
 | 
			
		||||
 *    conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
 *    materials provided with the distribution.
 | 
			
		||||
 * 
 | 
			
		||||
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from this
 | 
			
		||||
 *    software without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * 4. This software, with or without modification, must only be used with a
 | 
			
		||||
 *    Nordic Semiconductor ASA integrated circuit.
 | 
			
		||||
 * 
 | 
			
		||||
 * 5. Any software provided in binary form under this license must not be reverse
 | 
			
		||||
 *    engineered, decompiled, modified and/or disassembled.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 | 
			
		||||
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 | 
			
		||||
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
			
		||||
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup app_timer Application Timer
 | 
			
		||||
@@ -19,7 +46,7 @@
 | 
			
		||||
 * @brief Application timer functionality.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This module enables the application to create multiple timer instances based on the RTC1
 | 
			
		||||
 *          peripheral. Checking for time-outs and invokation of user time-out handlers is performed
 | 
			
		||||
 *          peripheral. Checking for time-outs and invocation of user time-out handlers is performed
 | 
			
		||||
 *          in the RTC1 interrupt handler. List handling is done using a software interrupt (SWI0).
 | 
			
		||||
 *          Both interrupt handlers are running in APP_LOW priority level.
 | 
			
		||||
 *
 | 
			
		||||
@@ -32,67 +59,55 @@
 | 
			
		||||
 *          the scheduler.
 | 
			
		||||
 *
 | 
			
		||||
 * @details Use the USE_SCHEDULER parameter of the APP_TIMER_INIT() macro to select if the
 | 
			
		||||
 *          @ref app_scheduler should be used or not. Even if the scheduler is 
 | 
			
		||||
 *          @ref app_scheduler should be used or not. Even if the scheduler is
 | 
			
		||||
 *          not used, app_timer.h will include app_scheduler.h, so when
 | 
			
		||||
 *          compiling, app_scheduler.h must be available in one of the compiler include paths.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef APP_TIMER_H__
 | 
			
		||||
#define APP_TIMER_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "sdk_config.h"
 | 
			
		||||
#include "app_error.h"
 | 
			
		||||
#include "app_util.h"
 | 
			
		||||
#include "compiler_abstraction.h"
 | 
			
		||||
#include "nordic_common.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#define APP_TIMER_CLOCK_FREQ         32768                      /**< Clock frequency of the RTC timer used to implement the app timer module. */
 | 
			
		||||
#define APP_TIMER_MIN_TIMEOUT_TICKS  5                          /**< Minimum value of the timeout_ticks parameter of app_timer_start(). */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define APP_TIMER_NODE_SIZE          32                         /**< Size of app_timer.timer_node_t (used to allocate data). */
 | 
			
		||||
#define APP_TIMER_USER_OP_SIZE       24                         /**< Size of app_timer.timer_user_op_t (only for use inside APP_TIMER_BUF_SIZE()). */
 | 
			
		||||
#define APP_TIMER_USER_SIZE          8                          /**< Size of app_timer.timer_user_t (only for use inside APP_TIMER_BUF_SIZE()). */
 | 
			
		||||
#define APP_TIMER_INT_LEVELS         3                          /**< Number of interrupt levels from where timer operations may be initiated (only for use inside APP_TIMER_BUF_SIZE()). */
 | 
			
		||||
#define APP_TIMER_CLOCK_FREQ            32768                     /**< Clock frequency of the RTC timer used to implement the app timer module. */
 | 
			
		||||
#define APP_TIMER_MIN_TIMEOUT_TICKS     5                         /**< Minimum value of the timeout_ticks parameter of app_timer_start(). */
 | 
			
		||||
 | 
			
		||||
/**@brief Compute number of bytes required to hold the application timer data structures.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  OP_QUEUE_SIZE   Size of queues holding timer operations that are pending execution.
 | 
			
		||||
 *                             Note that due to the queue implementation, this size must be one more
 | 
			
		||||
 *                             than the size that is actually needed.
 | 
			
		||||
 *
 | 
			
		||||
 * @return     Required application timer buffer size (in bytes).
 | 
			
		||||
 */
 | 
			
		||||
#define APP_TIMER_BUF_SIZE(OP_QUEUE_SIZE)                                              \
 | 
			
		||||
    (                                                                                              \
 | 
			
		||||
        (                                                                                          \
 | 
			
		||||
            APP_TIMER_INT_LEVELS                                                                   \
 | 
			
		||||
            *                                                                                      \
 | 
			
		||||
            (APP_TIMER_USER_SIZE + ((OP_QUEUE_SIZE) + 1) * APP_TIMER_USER_OP_SIZE)                 \
 | 
			
		||||
        )                                                                                          \
 | 
			
		||||
    )
 | 
			
		||||
#ifdef RTX
 | 
			
		||||
#define APP_TIMER_NODE_SIZE             40                        /**< Size of app_timer.timer_node_t (used to allocate data). */
 | 
			
		||||
#else
 | 
			
		||||
#define APP_TIMER_NODE_SIZE             32                        /**< Size of app_timer.timer_node_t (used to allocate data). */
 | 
			
		||||
#endif // RTX
 | 
			
		||||
 | 
			
		||||
#define APP_TIMER_SCHED_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Size of event data when scheduler is used. */
 | 
			
		||||
 | 
			
		||||
/**@brief Convert milliseconds to timer ticks.
 | 
			
		||||
 *
 | 
			
		||||
 * This macro uses 64-bit integer arithmetic, but as long as the macro parameters are
 | 
			
		||||
 *       constants (i.e. defines), the computation will be done by the preprocessor.
 | 
			
		||||
 * 
 | 
			
		||||
 * When using this macro, ensure that the 
 | 
			
		||||
 *         values provided as input result in an output value that is supported by the
 | 
			
		||||
 *         @ref app_timer_start function. For example, when the ticks for 1 ms is needed, the
 | 
			
		||||
 *         maximum possible value of PRESCALER must be 6, when @ref APP_TIMER_CLOCK_FREQ is 32768.
 | 
			
		||||
 *         This will result in a ticks value as 5. Any higher value for PRESCALER will result in a
 | 
			
		||||
 *         ticks value that is not supported by this module.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  MS          Milliseconds.
 | 
			
		||||
 * @param[in]  PRESCALER   Value of the RTC1 PRESCALER register (must be the same value that was
 | 
			
		||||
 *                         passed to APP_TIMER_INIT()). 
 | 
			
		||||
 *
 | 
			
		||||
 * @return     Number of timer ticks.
 | 
			
		||||
 */
 | 
			
		||||
#define APP_TIMER_TICKS(MS, PRESCALER)\
 | 
			
		||||
            ((uint32_t)ROUNDED_DIV((MS) * (uint64_t)APP_TIMER_CLOCK_FREQ, ((PRESCALER) + 1) * 1000))
 | 
			
		||||
 | 
			
		||||
#ifndef FREERTOS
 | 
			
		||||
#define APP_TIMER_TICKS(MS)                                \
 | 
			
		||||
            ((uint32_t)ROUNDED_DIV(                        \
 | 
			
		||||
            (MS) * (uint64_t)APP_TIMER_CLOCK_FREQ,         \
 | 
			
		||||
            1000 * (APP_TIMER_CONFIG_RTC_FREQUENCY + 1)))
 | 
			
		||||
#else
 | 
			
		||||
#include "FreeRTOSConfig.h"
 | 
			
		||||
#define APP_TIMER_TICKS(MS) (uint32_t)ROUNDED_DIV((MS)*configTICK_RATE_HZ,1000)
 | 
			
		||||
#endif
 | 
			
		||||
typedef struct app_timer_t { uint32_t data[CEIL_DIV(APP_TIMER_NODE_SIZE, sizeof(uint32_t))]; } app_timer_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Timer ID type.
 | 
			
		||||
@@ -104,17 +119,20 @@ typedef app_timer_t * app_timer_id_t;
 | 
			
		||||
 *
 | 
			
		||||
 * @param timer_id Name of the timer identifier variable that will be used to control the timer.
 | 
			
		||||
 */
 | 
			
		||||
#define APP_TIMER_DEF(timer_id)                                  \
 | 
			
		||||
    static app_timer_t timer_id##_data = { {0} };                  \
 | 
			
		||||
    static const app_timer_id_t timer_id = &timer_id##_data
 | 
			
		||||
#define APP_TIMER_DEF(timer_id)                                      \
 | 
			
		||||
    static app_timer_t CONCAT_2(timer_id,_data) = { {0} };           \
 | 
			
		||||
    static const app_timer_id_t timer_id = &CONCAT_2(timer_id,_data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Application time-out handler type. */
 | 
			
		||||
typedef void (*app_timer_timeout_handler_t)(void * p_context);
 | 
			
		||||
 | 
			
		||||
/**@brief Type of function for passing events from the timer module to the scheduler. */
 | 
			
		||||
typedef uint32_t (*app_timer_evt_schedule_func_t) (app_timer_timeout_handler_t timeout_handler,
 | 
			
		||||
                                                   void *                      p_context);
 | 
			
		||||
/**@brief Structure passed to app_scheduler. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    app_timer_timeout_handler_t timeout_handler;
 | 
			
		||||
    void *                      p_context;
 | 
			
		||||
} app_timer_event_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Timer modes. */
 | 
			
		||||
typedef enum
 | 
			
		||||
@@ -123,69 +141,11 @@ typedef enum
 | 
			
		||||
    APP_TIMER_MODE_REPEATED                     /**< The timer will restart each time it expires. */
 | 
			
		||||
} app_timer_mode_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Initialize the application timer module.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This macro handles dimensioning and allocation of the memory buffer required by the timer,
 | 
			
		||||
 *          making sure that the buffer is correctly aligned. It will also connect the timer module
 | 
			
		||||
 *          to the scheduler (if specified).
 | 
			
		||||
 *
 | 
			
		||||
 * @note    This module assumes that the LFCLK is already running. If it is not, the module will 
 | 
			
		||||
 *          be non-functional, since the RTC will not run. If you do not use a SoftDevice, you 
 | 
			
		||||
 *          must start the LFCLK manually. See the rtc_example's lfclk_config() function 
 | 
			
		||||
 *          for an example of how to do this. If you use a SoftDevice, the LFCLK is started on 
 | 
			
		||||
 *          SoftDevice init. 
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  PRESCALER        Value of the RTC1 PRESCALER register. This will decide the
 | 
			
		||||
 *                              timer tick rate. Set to 0 for no prescaling.
 | 
			
		||||
 * @param[in]  OP_QUEUES_SIZE   Size of queues holding timer operations that are pending execution.
 | 
			
		||||
 * @param[in]  SCHEDULER_FUNC   Pointer to scheduler event handler
 | 
			
		||||
 *
 | 
			
		||||
 * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
 | 
			
		||||
 *       several times as long as it is from the same location, for example, to do a re-initialization).
 | 
			
		||||
 */
 | 
			
		||||
/*lint -emacro(506, APP_TIMER_INIT) */ /* Suppress "Constant value Boolean */
 | 
			
		||||
#define APP_TIMER_INIT(PRESCALER, OP_QUEUES_SIZE, SCHEDULER_FUNC)                                  \
 | 
			
		||||
    do                                                                                             \
 | 
			
		||||
    {                                                                                              \
 | 
			
		||||
        static uint32_t APP_TIMER_BUF[CEIL_DIV(APP_TIMER_BUF_SIZE((OP_QUEUES_SIZE) + 1),           \
 | 
			
		||||
                                               sizeof(uint32_t))];                                 \
 | 
			
		||||
        uint32_t ERR_CODE = app_timer_init((PRESCALER),                                            \
 | 
			
		||||
                                           (OP_QUEUES_SIZE) + 1,                                   \
 | 
			
		||||
                                           APP_TIMER_BUF,                                          \
 | 
			
		||||
                                           SCHEDULER_FUNC);                                        \
 | 
			
		||||
        APP_ERROR_CHECK(ERR_CODE);                                                                 \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for initializing the timer module.
 | 
			
		||||
 *
 | 
			
		||||
 * Normally, initialization should be done using the APP_TIMER_INIT() macro, because that macro will both
 | 
			
		||||
 *       allocate the buffers needed by the timer module (including aligning the buffers correctly)
 | 
			
		||||
 *       and take care of connecting the timer module to the scheduler (if specified).
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  prescaler           Value of the RTC1 PRESCALER register. Set to 0 for no prescaling.
 | 
			
		||||
 * @param[in]  op_queues_size      Size of queues holding timer operations that are pending
 | 
			
		||||
 *                                 execution. Note that due to the queue implementation, this size must
 | 
			
		||||
 *                                 be one more than the size that is actually needed.
 | 
			
		||||
 * @param[in]  p_buffer            Pointer to memory buffer for internal use in the app_timer
 | 
			
		||||
 *                                 module. The size of the buffer can be computed using the
 | 
			
		||||
 *                                 APP_TIMER_BUF_SIZE() macro. The buffer must be aligned to a
 | 
			
		||||
 *                                 4 byte boundary.
 | 
			
		||||
 * @param[in]  evt_schedule_func   Function for passing time-out events to the scheduler. Point to
 | 
			
		||||
 *                                 app_timer_evt_schedule() to connect to the scheduler. Set to NULL
 | 
			
		||||
 *                                 to make the timer module call the time-out handler directly from
 | 
			
		||||
 *                                 the timer interrupt handler.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval     NRF_SUCCESS               If the module was initialized successfully.
 | 
			
		||||
 * @retval     NRF_ERROR_INVALID_PARAM   If a parameter was invalid (buffer not aligned to a 4 byte
 | 
			
		||||
 *                                       boundary or NULL).
 | 
			
		||||
 */
 | 
			
		||||
uint32_t app_timer_init(uint32_t                      prescaler, 
 | 
			
		||||
                        uint8_t                       op_queues_size,
 | 
			
		||||
                        void *                        p_buffer,
 | 
			
		||||
                        app_timer_evt_schedule_func_t evt_schedule_func);
 | 
			
		||||
ret_code_t app_timer_init(void);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for creating a timer instance.
 | 
			
		||||
 *
 | 
			
		||||
@@ -206,9 +166,9 @@ uint32_t app_timer_init(uint32_t                      prescaler,
 | 
			
		||||
 * @attention The FreeRTOS and RTX app_timer implementation does not allow app_timer_create to
 | 
			
		||||
 *       be called on the previously initialized instance.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t app_timer_create(app_timer_id_t const *      p_timer_id,
 | 
			
		||||
                          app_timer_mode_t            mode,
 | 
			
		||||
                          app_timer_timeout_handler_t timeout_handler);
 | 
			
		||||
ret_code_t app_timer_create(app_timer_id_t const *      p_timer_id,
 | 
			
		||||
                            app_timer_mode_t            mode,
 | 
			
		||||
                            app_timer_timeout_handler_t timeout_handler);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for starting a timer.
 | 
			
		||||
 *
 | 
			
		||||
@@ -230,7 +190,7 @@ uint32_t app_timer_create(app_timer_id_t const *      p_timer_id,
 | 
			
		||||
 * @note When calling this method on a timer that is already running, the second start operation
 | 
			
		||||
 *       is ignored.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context);
 | 
			
		||||
ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for stopping the specified timer.
 | 
			
		||||
 *
 | 
			
		||||
@@ -242,7 +202,7 @@ uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void *
 | 
			
		||||
 *                                       has not been created.
 | 
			
		||||
 * @retval     NRF_ERROR_NO_MEM          If the timer operations queue was full.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t app_timer_stop(app_timer_id_t timer_id);
 | 
			
		||||
ret_code_t app_timer_stop(app_timer_id_t timer_id);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for stopping all running timers.
 | 
			
		||||
 *
 | 
			
		||||
@@ -250,36 +210,53 @@ uint32_t app_timer_stop(app_timer_id_t timer_id);
 | 
			
		||||
 * @retval     NRF_ERROR_INVALID_STATE   If the application timer module has not been initialized.
 | 
			
		||||
 * @retval     NRF_ERROR_NO_MEM          If the timer operations queue was full.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t app_timer_stop_all(void);
 | 
			
		||||
ret_code_t app_timer_stop_all(void);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for returning the current value of the RTC1 counter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out] p_ticks   Current value of the RTC1 counter.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval     NRF_SUCCESS   If the counter was successfully read.
 | 
			
		||||
 * @return    Current value of the RTC1 counter.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t app_timer_cnt_get(uint32_t * p_ticks);
 | 
			
		||||
uint32_t app_timer_cnt_get(void);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for computing the difference between two RTC1 counter values.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  ticks_to       Value returned by app_timer_cnt_get().
 | 
			
		||||
 * @param[in]  ticks_from     Value returned by app_timer_cnt_get().
 | 
			
		||||
 * @param[out] p_ticks_diff   Number of ticks from ticks_from to ticks_to.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval     NRF_SUCCESS   If the counter difference was successfully computed.
 | 
			
		||||
 * @return    Number of ticks from ticks_from to ticks_to.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t app_timer_cnt_diff_compute(uint32_t   ticks_to,
 | 
			
		||||
                                    uint32_t   ticks_from,
 | 
			
		||||
                                    uint32_t * p_ticks_diff);
 | 
			
		||||
                                    uint32_t   ticks_from);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef APP_TIMER_WITH_PROFILER
 | 
			
		||||
/**@brief Function for getting the maximum observed operation queue utilization.
 | 
			
		||||
 *
 | 
			
		||||
 * Function for tuning the module and determining OP_QUEUE_SIZE value and thus module RAM usage.
 | 
			
		||||
 *
 | 
			
		||||
 * @note APP_TIMER_WITH_PROFILER must be enabled to use this functionality.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Maximum number of events in queue observed so far.
 | 
			
		||||
 */
 | 
			
		||||
uint8_t app_timer_op_queue_utilization_get(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Function for pausing RTC activity which drives app_timer.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function can be used for debugging purposes to ensure
 | 
			
		||||
 *       that application is halted when entering a breakpoint.
 | 
			
		||||
 */
 | 
			
		||||
void app_timer_pause(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Function for resuming RTC activity which drives app_timer.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function can be used for debugging purposes to resume
 | 
			
		||||
 *       application activity.
 | 
			
		||||
 */
 | 
			
		||||
void app_timer_resume(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // APP_TIMER_H__
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "app_timer_appsh.h"
 | 
			
		||||
#include "app_scheduler.h"
 | 
			
		||||
 | 
			
		||||
static void app_timer_evt_get(void * p_event_data, uint16_t event_size)
 | 
			
		||||
{
 | 
			
		||||
    app_timer_event_t * p_timer_event = (app_timer_event_t *)p_event_data;
 | 
			
		||||
    
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(event_size == sizeof(app_timer_event_t));
 | 
			
		||||
    p_timer_event->timeout_handler(p_timer_event->p_context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t app_timer_evt_schedule(app_timer_timeout_handler_t timeout_handler,
 | 
			
		||||
                                void *                      p_context)
 | 
			
		||||
{
 | 
			
		||||
    app_timer_event_t timer_event;
 | 
			
		||||
 | 
			
		||||
    timer_event.timeout_handler = timeout_handler;
 | 
			
		||||
    timer_event.p_context       = p_context;
 | 
			
		||||
    
 | 
			
		||||
    return app_sched_event_put(&timer_event, sizeof(timer_event), app_timer_evt_get);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,44 +0,0 @@
 | 
			
		||||
/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 #ifndef APP_TIMER_APPSH_H
 | 
			
		||||
 #define APP_TIMER_APPSH_H
 | 
			
		||||
 | 
			
		||||
#include "app_timer.h"
 | 
			
		||||
 | 
			
		||||
#define APP_TIMER_SCHED_EVT_SIZE     sizeof(app_timer_event_t)  /**< Size of button events being passed through the scheduler (is to be used for computing the maximum size of scheduler events). */
 | 
			
		||||
 | 
			
		||||
/**@brief Macro for initializing the application timer module to use with app_scheduler.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  PRESCALER        Value of the RTC1 PRESCALER register. This will decide the
 | 
			
		||||
 *                              timer tick rate. Set to 0 for no prescaling.
 | 
			
		||||
 * @param[in]  OP_QUEUES_SIZE   Size of queues holding timer operations that are pending execution.
 | 
			
		||||
 * @param[in]  USE_SCHEDULER    TRUE if the application is using the app_scheduler,
 | 
			
		||||
 *                              FALSE otherwise.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
 | 
			
		||||
 *       several times as long as it is from the same location, e.g. to do a reinitialization).
 | 
			
		||||
 */
 | 
			
		||||
#define APP_TIMER_APPSH_INIT(PRESCALER, OP_QUEUES_SIZE, USE_SCHEDULER)                 \
 | 
			
		||||
    APP_TIMER_INIT(PRESCALER, OP_QUEUES_SIZE,                                          \
 | 
			
		||||
                                (USE_SCHEDULER) ? app_timer_evt_schedule : NULL)
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    app_timer_timeout_handler_t timeout_handler;
 | 
			
		||||
    void *                      p_context;
 | 
			
		||||
} app_timer_event_t;
 | 
			
		||||
 | 
			
		||||
uint32_t app_timer_evt_schedule(app_timer_timeout_handler_t timeout_handler,
 | 
			
		||||
                                void *                      p_context);
 | 
			
		||||
#endif // APP_TIMER_APPSH_H
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user