follow #1
seperate files from latest SDK (currently 14.2.0) from good old non- secure bootloader sdk 11
This commit is contained in:
61
lib/sdk/components/libraries/crc16/crc16.c
Normal file
61
lib/sdk/components/libraries/crc16/crc16.c
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* 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(CRC16)
|
||||
#include "crc16.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc)
|
||||
{
|
||||
uint16_t crc = (p_crc == NULL) ? 0xFFFF : *p_crc;
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
crc = (uint8_t)(crc >> 8) | (crc << 8);
|
||||
crc ^= p_data[i];
|
||||
crc ^= (uint8_t)(crc & 0xFF) >> 4;
|
||||
crc ^= (crc << 8) << 4;
|
||||
crc ^= ((crc & 0xFF) << 4) << 1;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
#endif //NRF_MODULE_ENABLED(CRC16)
|
80
lib/sdk/components/libraries/crc16/crc16.h
Normal file
80
lib/sdk/components/libraries/crc16/crc16.h
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* 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 crc16 CRC16 compute
|
||||
* @{
|
||||
* @ingroup hci_transport
|
||||
*
|
||||
* @brief This module implements CRC-16-CCITT (polynomial 0x1021) with 0xFFFF initial value.
|
||||
* The data can be passed in multiple blocks.
|
||||
*/
|
||||
|
||||
#ifndef CRC16_H__
|
||||
#define CRC16_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Function for calculating CRC-16 in blocks.
|
||||
*
|
||||
* Feed each consecutive data block into this function, along with the current value of p_crc as
|
||||
* returned by the previous call of this function. The first call of this function should pass NULL
|
||||
* as the initial value of the crc in p_crc.
|
||||
*
|
||||
* @param[in] p_data The input data block for computation.
|
||||
* @param[in] size The size of the input data block in bytes.
|
||||
* @param[in] p_crc The previous calculated CRC-16 value or NULL if first call.
|
||||
*
|
||||
* @return The updated CRC-16 value, based on the input supplied.
|
||||
*/
|
||||
uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CRC16_H__
|
||||
|
||||
/** @} */
|
214
lib/sdk/components/libraries/fifo/app_fifo.c
Normal file
214
lib/sdk/components/libraries/fifo/app_fifo.c
Normal file
@ -0,0 +1,214 @@
|
||||
/**
|
||||
* 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(APP_FIFO)
|
||||
#include "app_fifo.h"
|
||||
|
||||
static __INLINE uint32_t fifo_length(app_fifo_t * p_fifo)
|
||||
{
|
||||
uint32_t tmp = p_fifo->read_pos;
|
||||
return p_fifo->write_pos - tmp;
|
||||
}
|
||||
|
||||
|
||||
#define FIFO_LENGTH() fifo_length(p_fifo) /**< Macro for calculating the FIFO length. */
|
||||
|
||||
|
||||
/**@brief Put one byte to the FIFO. */
|
||||
static __INLINE void fifo_put(app_fifo_t * p_fifo, uint8_t byte)
|
||||
{
|
||||
p_fifo->p_buf[p_fifo->write_pos & p_fifo->buf_size_mask] = byte;
|
||||
p_fifo->write_pos++;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Look at one byte in the FIFO. */
|
||||
static __INLINE void fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
|
||||
{
|
||||
*p_byte = p_fifo->p_buf[(p_fifo->read_pos + index) & p_fifo->buf_size_mask];
|
||||
}
|
||||
|
||||
|
||||
/**@brief Get one byte from the FIFO. */
|
||||
static __INLINE void fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
|
||||
{
|
||||
fifo_peek(p_fifo, 0, p_byte);
|
||||
p_fifo->read_pos++;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size)
|
||||
{
|
||||
// Check buffer for null pointer.
|
||||
if (p_buf == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
// Check that the buffer size is a power of two.
|
||||
if (!IS_POWER_OF_TWO(buf_size))
|
||||
{
|
||||
return NRF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
p_fifo->p_buf = p_buf;
|
||||
p_fifo->buf_size_mask = buf_size - 1;
|
||||
p_fifo->read_pos = 0;
|
||||
p_fifo->write_pos = 0;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte)
|
||||
{
|
||||
if (FIFO_LENGTH() <= p_fifo->buf_size_mask)
|
||||
{
|
||||
fifo_put(p_fifo, byte);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
return NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
|
||||
{
|
||||
if (FIFO_LENGTH() != 0)
|
||||
{
|
||||
fifo_get(p_fifo, p_byte);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
return NRF_ERROR_NOT_FOUND;
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
|
||||
{
|
||||
if (FIFO_LENGTH() > index)
|
||||
{
|
||||
fifo_peek(p_fifo, index, p_byte);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
return NRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_fifo_flush(app_fifo_t * p_fifo)
|
||||
{
|
||||
p_fifo->read_pos = p_fifo->write_pos;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size)
|
||||
{
|
||||
VERIFY_PARAM_NOT_NULL(p_fifo);
|
||||
VERIFY_PARAM_NOT_NULL(p_size);
|
||||
|
||||
const uint32_t byte_count = fifo_length(p_fifo);
|
||||
const uint32_t requested_len = (*p_size);
|
||||
uint32_t index = 0;
|
||||
uint32_t read_size = MIN(requested_len, byte_count);
|
||||
|
||||
(*p_size) = byte_count;
|
||||
|
||||
// Check if the FIFO is empty.
|
||||
if (byte_count == 0)
|
||||
{
|
||||
return NRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Check if application has requested only the size.
|
||||
if (p_byte_array == NULL)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
// Fetch bytes from the FIFO.
|
||||
while (index < read_size)
|
||||
{
|
||||
fifo_get(p_fifo, &p_byte_array[index++]);
|
||||
}
|
||||
|
||||
(*p_size) = read_size;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size)
|
||||
{
|
||||
VERIFY_PARAM_NOT_NULL(p_fifo);
|
||||
VERIFY_PARAM_NOT_NULL(p_size);
|
||||
|
||||
const uint32_t available_count = p_fifo->buf_size_mask - fifo_length(p_fifo) + 1;
|
||||
const uint32_t requested_len = (*p_size);
|
||||
uint32_t index = 0;
|
||||
uint32_t write_size = MIN(requested_len, available_count);
|
||||
|
||||
(*p_size) = available_count;
|
||||
|
||||
// Check if the FIFO is FULL.
|
||||
if (available_count == 0)
|
||||
{
|
||||
return NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
// Check if application has requested only the size.
|
||||
if (p_byte_array == NULL)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
//Fetch bytes from the FIFO.
|
||||
while (index < write_size)
|
||||
{
|
||||
fifo_put(p_fifo, p_byte_array[index++]);
|
||||
}
|
||||
|
||||
(*p_size) = write_size;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
#endif //NRF_MODULE_ENABLED(APP_FIFO)
|
181
lib/sdk/components/libraries/fifo/app_fifo.h
Normal file
181
lib/sdk/components/libraries/fifo/app_fifo.h
Normal file
@ -0,0 +1,181 @@
|
||||
/**
|
||||
* 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 app_fifo FIFO implementation
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief FIFO implementation.
|
||||
*/
|
||||
|
||||
#ifndef APP_FIFO_H__
|
||||
#define APP_FIFO_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief A FIFO instance structure.
|
||||
* @details Keeps track of which bytes to read and write next.
|
||||
* Also, it keeps the information about which memory is allocated for the buffer
|
||||
* and its size. This structure must be initialized by app_fifo_init() before use.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * p_buf; /**< Pointer to FIFO buffer memory. */
|
||||
uint16_t buf_size_mask; /**< Read/write index mask. Also used for size checking. */
|
||||
volatile uint32_t read_pos; /**< Next read position in the FIFO buffer. */
|
||||
volatile uint32_t write_pos; /**< Next write position in the FIFO buffer. */
|
||||
} app_fifo_t;
|
||||
|
||||
/**@brief Function for initializing the FIFO.
|
||||
*
|
||||
* @param[out] p_fifo FIFO object.
|
||||
* @param[in] p_buf FIFO buffer for storing data. The buffer size must be a power of two.
|
||||
* @param[in] buf_size Size of the FIFO buffer provided. This size must be a power of two.
|
||||
*
|
||||
* @retval NRF_SUCCESS If initialization was successful.
|
||||
* @retval NRF_ERROR_NULL If a NULL pointer is provided as buffer.
|
||||
* @retval NRF_ERROR_INVALID_LENGTH If size of buffer provided is not a power of two.
|
||||
*/
|
||||
uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size);
|
||||
|
||||
/**@brief Function for adding an element to the FIFO.
|
||||
*
|
||||
* @param[in] p_fifo Pointer to the FIFO.
|
||||
* @param[in] byte Data byte to add to the FIFO.
|
||||
*
|
||||
* @retval NRF_SUCCESS If an element has been successfully added to the FIFO.
|
||||
* @retval NRF_ERROR_NO_MEM If the FIFO is full.
|
||||
*/
|
||||
uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte);
|
||||
|
||||
/**@brief Function for getting the next element from the FIFO.
|
||||
*
|
||||
* @param[in] p_fifo Pointer to the FIFO.
|
||||
* @param[out] p_byte Byte fetched from the FIFO.
|
||||
*
|
||||
* @retval NRF_SUCCESS If an element was returned.
|
||||
* @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
|
||||
*/
|
||||
uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte);
|
||||
|
||||
/**@brief Function for looking at an element in the FIFO, without consuming it.
|
||||
*
|
||||
* @param[in] p_fifo Pointer to the FIFO.
|
||||
* @param[in] index Which element to look at. The lower the index, the earlier it was put.
|
||||
* @param[out] p_byte Byte fetched from the FIFO.
|
||||
*
|
||||
* @retval NRF_SUCCESS If an element was returned.
|
||||
* @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue, or the index was
|
||||
* too large.
|
||||
*/
|
||||
uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte);
|
||||
|
||||
/**@brief Function for flushing the FIFO.
|
||||
*
|
||||
* @param[in] p_fifo Pointer to the FIFO.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the FIFO was flushed successfully.
|
||||
*/
|
||||
uint32_t app_fifo_flush(app_fifo_t * p_fifo);
|
||||
|
||||
/**@brief Function for reading bytes from the FIFO.
|
||||
*
|
||||
* This function can also be used to get the number of bytes in the FIFO.
|
||||
*
|
||||
* @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
|
||||
* @param[out] p_byte_array Memory pointer where the read bytes are fetched from the FIFO.
|
||||
* Can be NULL. If NULL, the number of bytes that can be read in the FIFO
|
||||
* are returned in the p_size parameter.
|
||||
* @param[inout] p_size Address to memory indicating the maximum number of bytes to be read.
|
||||
* The provided memory is overwritten with the actual number of bytes
|
||||
* read if the procedure was successful. This field must not be NULL.
|
||||
* If p_byte_array is set to NULL by the application, this parameter
|
||||
* returns the number of bytes in the FIFO.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes read might
|
||||
* be less than the requested maximum, depending on how many elements exist
|
||||
* in the FIFO. Even if less bytes are returned, the procedure is considered
|
||||
* successful.
|
||||
* @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not
|
||||
* be NULL.
|
||||
* @retval NRF_ERROR_NOT_FOUND If the FIFO is empty.
|
||||
*/
|
||||
uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size);
|
||||
|
||||
/**@brief Function for writing bytes to the FIFO.
|
||||
*
|
||||
* This function can also be used to get the available size on the FIFO.
|
||||
*
|
||||
* @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
|
||||
* @param[in] p_byte_array Memory pointer containing the bytes to be written to the FIFO.
|
||||
* Can be NULL. If NULL, this function returns the number of bytes
|
||||
* that can be written to the FIFO.
|
||||
* @param[inout] p_size Address to memory indicating the maximum number of bytes to be written.
|
||||
* The provided memory is overwritten with the number of bytes that were actually
|
||||
* written if the procedure is successful. This field must not be NULL.
|
||||
* If p_byte_array is set to NULL by the application, this parameter
|
||||
* returns the number of bytes available in the FIFO.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes written might
|
||||
* be less than the requested maximum, depending on how much room there is in
|
||||
* the FIFO. Even if less bytes are written, the procedure is considered
|
||||
* successful. If the write was partial, the application should use
|
||||
* subsequent calls to attempt writing the data again.
|
||||
* @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not
|
||||
* be NULL.
|
||||
* @retval NRF_ERROR_NO_MEM If the FIFO is full.
|
||||
*
|
||||
*/
|
||||
uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // APP_FIFO_H__
|
||||
|
||||
/** @} */
|
264
lib/sdk/components/libraries/hci/hci_mem_pool.c
Normal file
264
lib/sdk/components/libraries/hci/hci_mem_pool.c
Normal file
@ -0,0 +1,264 @@
|
||||
/**
|
||||
* 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 <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**@brief RX buffer element instance structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
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.
|
||||
*/
|
||||
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. */
|
||||
} 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[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_rx_buffer_queue.p_buffer = m_rx_buffer_elem_queue;
|
||||
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;
|
||||
|
||||
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[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;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (pp_buffer == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
*pp_buffer = NULL;
|
||||
|
||||
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
|
||||
// "Making embedded systems: Elicia White".
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
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) &
|
||||
(HCI_RX_BUF_QUEUE_SIZE - 1u);
|
||||
start_index = consume_index;
|
||||
|
||||
do
|
||||
{
|
||||
if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer)
|
||||
{
|
||||
m_rx_buffer_queue.free_index ^= (1u << consume_index);
|
||||
err_code = NRF_SUCCESS;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)) &&
|
||||
(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) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
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
|
||||
// "Making embedded systems: Elicia White".
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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.p_buffer[m_rx_buffer_queue.read_index].rx_buffer;
|
||||
*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) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
|
||||
|
||||
err_code = NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
#endif //NRF_MODULE_ENABLED(HCI_MEM_POOL)
|
168
lib/sdk/components/libraries/hci/hci_mem_pool.h
Normal file
168
lib/sdk/components/libraries/hci/hci_mem_pool.h
Normal file
@ -0,0 +1,168 @@
|
||||
/**
|
||||
* 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_mem_pool Memory pool
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief Memory pool implementation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @image html memory_pool.svg "Circular buffer design"
|
||||
*
|
||||
* The expected call order for the RX APIs is as follows:
|
||||
* - hci_mem_pool_rx_produce
|
||||
* - hci_mem_pool_rx_data_size_set
|
||||
* - hci_mem_pool_rx_extract
|
||||
* - hci_mem_pool_rx_consume
|
||||
*
|
||||
* @warning If the above mentioned expected call order is violated the end result can be undefined.
|
||||
*
|
||||
* \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.
|
||||
* - 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.
|
||||
*/
|
||||
uint32_t hci_mem_pool_open(void);
|
||||
|
||||
/**@brief Function for closing the module.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
*/
|
||||
uint32_t hci_mem_pool_close(void);
|
||||
|
||||
/**@brief Function for allocating requested amount of TX memory.
|
||||
*
|
||||
* @param[out] pp_buffer Pointer to the allocated memory.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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
|
||||
* mem_pool_rx_extract will return incorrect data in the p_length output parameter.
|
||||
*
|
||||
* @param[in] length Amount, in bytes, of actual memory used.
|
||||
*
|
||||
* @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
|
||||
* processing.
|
||||
*
|
||||
* @param[out] pp_buffer Pointer to the packet data.
|
||||
* @param[out] p_length Length of packet data in bytes.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HCI_MEM_POOL_H__
|
||||
|
||||
/** @} */
|
457
lib/sdk/components/libraries/hci/hci_slip.c
Normal file
457
lib/sdk/components/libraries/hci/hci_slip.c
Normal file
@ -0,0 +1,457 @@
|
||||
/**
|
||||
* 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 "app_uart.h"
|
||||
#include "nrf_error.h"
|
||||
|
||||
#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */
|
||||
#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */
|
||||
#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */
|
||||
#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */
|
||||
|
||||
/** @brief States for the SLIP state machine. */
|
||||
typedef enum
|
||||
{
|
||||
SLIP_OFF, /**< SLIP state OFF. */
|
||||
SLIP_READY, /**< SLIP state ON. */
|
||||
SLIP_TRANSMITTING, /**< SLIP state is transmitting indicating write() has been called but data transmission has not completed. */
|
||||
} slip_states_t;
|
||||
|
||||
static slip_states_t m_current_state = SLIP_OFF; /** Current state for the SLIP TX state machine. */
|
||||
|
||||
static hci_slip_event_handler_t m_slip_event_handler; /** Event callback function for handling of SLIP events, @ref hci_slip_evt_type_t . */
|
||||
|
||||
static const uint8_t * mp_tx_buffer; /** Pointer to the current TX buffer that is in transmission. */
|
||||
static uint32_t m_tx_buffer_length; /** Length of the current TX buffer that is in transmission. */
|
||||
static volatile uint32_t m_tx_buffer_index; /** Current index for next byte to transmit in the mp_tx_buffer. */
|
||||
|
||||
static uint8_t * mp_rx_buffer; /** Pointer to the current RX buffer where the next SLIP decoded packet will be stored. */
|
||||
static uint32_t m_rx_buffer_length; /** Length of the current RX buffer. */
|
||||
static uint32_t m_rx_received_count; /** Number of SLIP decoded bytes received and stored in mp_rx_buffer. */
|
||||
|
||||
|
||||
/**@brief Function for parsing bytes received on the UART until a SLIP escape byte is received.
|
||||
*
|
||||
* @param[in] byte Byte received in UART module.
|
||||
*/
|
||||
static void handle_rx_byte_default(uint8_t byte);
|
||||
|
||||
/**@brief Function for parsing bytes received on the UART until SLIP end byte is received.
|
||||
*
|
||||
* @param[in] byte Byte received in UART module.
|
||||
*/
|
||||
static void handle_rx_byte_wait_start(uint8_t byte);
|
||||
|
||||
/**@brief Function for decoding a received SLIP escape byte.
|
||||
* It will ensure correct decoding of the byte following the SLIP escape byte.
|
||||
*
|
||||
* @param[in] byte Byte received in UART module.
|
||||
*/
|
||||
static void handle_rx_byte_esc(uint8_t byte);
|
||||
|
||||
/**@brief Function pointer for parsing and decoding SLIP bytes from the UART module.
|
||||
*
|
||||
* @param[in] byte Byte received in UART module.
|
||||
*/
|
||||
static void (*handle_rx_byte) (uint8_t byte) = handle_rx_byte_wait_start;
|
||||
|
||||
/**@brief Function pointer for sending a byte through the UART module.
|
||||
*/
|
||||
static uint32_t send_tx_byte_default(void);
|
||||
|
||||
/**@brief Function for transferring a SLIP escape byte (0xDB) when special bytes are transferred,
|
||||
* that is 0xC0 and 0xDB.
|
||||
*/
|
||||
static uint32_t send_tx_byte_esc(void);
|
||||
|
||||
/**@brief Function for transferring a byte when it collides with SLIP commands and follows the SLIP
|
||||
* escape byte, that is 0xC0 => 0xDC and 0xDB => 0xDD.
|
||||
*/
|
||||
static uint32_t send_tx_byte_encoded(void);
|
||||
|
||||
/**@brief Function for transferring the SLIP end frame byte, 0xC0.
|
||||
*/
|
||||
static uint32_t send_tx_byte_end(void);
|
||||
|
||||
/**@brief Function pointer for sending a byte through the UART module.
|
||||
*/
|
||||
uint32_t (*send_tx_byte) (void) = send_tx_byte_default;
|
||||
|
||||
|
||||
static uint32_t send_tx_byte_end(void)
|
||||
{
|
||||
uint32_t err_code = app_uart_put(APP_SLIP_END);
|
||||
|
||||
if ((err_code == NRF_SUCCESS) && (m_tx_buffer_index == 0))
|
||||
{
|
||||
// Packet transmission started.
|
||||
send_tx_byte = send_tx_byte_default;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t send_tx_byte_default(void)
|
||||
{
|
||||
uint32_t err_code = app_uart_put(mp_tx_buffer[m_tx_buffer_index]);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
m_tx_buffer_index++;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t send_tx_byte_encoded(void)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
switch (mp_tx_buffer[m_tx_buffer_index])
|
||||
{
|
||||
case APP_SLIP_END:
|
||||
err_code = app_uart_put(APP_SLIP_ESC_END);
|
||||
break;
|
||||
|
||||
case APP_SLIP_ESC:
|
||||
err_code = app_uart_put(APP_SLIP_ESC_ESC);
|
||||
break;
|
||||
|
||||
default:
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
m_tx_buffer_index++;
|
||||
send_tx_byte = send_tx_byte_default;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t send_tx_byte_esc(void)
|
||||
{
|
||||
uint32_t err_code = app_uart_put(APP_SLIP_ESC);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
send_tx_byte = send_tx_byte_encoded;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function for transferring the content of the mp_tx_buffer to the UART.
|
||||
* It continues to transfer bytes until the UART buffer is full or the complete buffer is
|
||||
* transferred.
|
||||
*/
|
||||
static void transmit_buffer(void)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
while (m_tx_buffer_index < m_tx_buffer_length)
|
||||
{
|
||||
if ((mp_tx_buffer[m_tx_buffer_index] == APP_SLIP_END ||
|
||||
mp_tx_buffer[m_tx_buffer_index] == APP_SLIP_ESC) &&
|
||||
send_tx_byte == send_tx_byte_default)
|
||||
{
|
||||
send_tx_byte = send_tx_byte_esc;
|
||||
}
|
||||
|
||||
err_code = send_tx_byte();
|
||||
|
||||
if (err_code == NRF_ERROR_NO_MEM || err_code == NRF_ERROR_BUSY)
|
||||
{
|
||||
// No memory left in UART TX buffer. Abort and wait for APP_UART_TX_EMPTY to continue.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
send_tx_byte = send_tx_byte_end;
|
||||
|
||||
err_code = send_tx_byte();
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
// Packet transmission ended. Notify higher level.
|
||||
m_current_state = SLIP_READY;
|
||||
|
||||
if (m_slip_event_handler != NULL)
|
||||
{
|
||||
hci_slip_evt_t event = {HCI_SLIP_TX_DONE, mp_tx_buffer, m_tx_buffer_index};
|
||||
|
||||
m_slip_event_handler(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function for handling the reception of a SLIP end byte.
|
||||
* If the number of bytes received is greater than zero it will call m_slip_event_handler
|
||||
* with number of bytes received and invalidate the mp_rx_buffer to protect against data
|
||||
* corruption.
|
||||
* No new bytes can be received until a new RX buffer is supplied.
|
||||
*/
|
||||
static void handle_slip_end(void)
|
||||
{
|
||||
if (m_rx_received_count > 0)
|
||||
{
|
||||
// Full packet received, push it up.
|
||||
if (m_slip_event_handler != NULL)
|
||||
{
|
||||
hci_slip_evt_t event = {HCI_SLIP_RX_RDY, mp_rx_buffer, m_rx_received_count};
|
||||
|
||||
m_rx_received_count = 0;
|
||||
mp_rx_buffer = NULL;
|
||||
|
||||
m_slip_event_handler(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void handle_rx_byte_esc(uint8_t byte)
|
||||
{
|
||||
switch (byte)
|
||||
{
|
||||
case APP_SLIP_END:
|
||||
handle_slip_end();
|
||||
break;
|
||||
|
||||
case APP_SLIP_ESC_END:
|
||||
mp_rx_buffer[m_rx_received_count++] = APP_SLIP_END;
|
||||
break;
|
||||
|
||||
case APP_SLIP_ESC_ESC:
|
||||
mp_rx_buffer[m_rx_received_count++] = APP_SLIP_ESC;
|
||||
break;
|
||||
|
||||
default:
|
||||
mp_rx_buffer[m_rx_received_count++] = byte;
|
||||
break;
|
||||
}
|
||||
|
||||
handle_rx_byte = handle_rx_byte_default;
|
||||
}
|
||||
|
||||
|
||||
static void handle_rx_byte_default(uint8_t byte)
|
||||
{
|
||||
switch (byte)
|
||||
{
|
||||
case APP_SLIP_END:
|
||||
handle_slip_end();
|
||||
break;
|
||||
|
||||
case APP_SLIP_ESC:
|
||||
handle_rx_byte = handle_rx_byte_esc;
|
||||
break;
|
||||
|
||||
default:
|
||||
mp_rx_buffer[m_rx_received_count++] = byte;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void handle_rx_byte_wait_start(uint8_t byte)
|
||||
{
|
||||
if (byte == APP_SLIP_END)
|
||||
{
|
||||
handle_rx_byte = handle_rx_byte_default;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function for checking the current index and length of the RX buffer to determine if the
|
||||
* buffer is full. If an event handler has been registered, the callback function will
|
||||
* be executed..
|
||||
*
|
||||
* @retval true If RX buffer has overflowed.
|
||||
* @retval false otherwise.
|
||||
*
|
||||
*/
|
||||
static bool rx_buffer_overflowed(void)
|
||||
{
|
||||
if (mp_rx_buffer == NULL || m_rx_received_count >= m_rx_buffer_length)
|
||||
{
|
||||
if (m_slip_event_handler != NULL)
|
||||
{
|
||||
hci_slip_evt_t event = {HCI_SLIP_RX_OVERFLOW, mp_rx_buffer, m_rx_received_count};
|
||||
m_slip_event_handler(event);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function for handling the UART module event. It parses events from the UART when
|
||||
* bytes are received/transmitted.
|
||||
*
|
||||
* @param[in] uart_event Event received from app_uart module.
|
||||
*/
|
||||
static void slip_uart_eventhandler(app_uart_evt_t * uart_event)
|
||||
{
|
||||
if (uart_event->evt_type == APP_UART_TX_EMPTY && m_current_state == SLIP_TRANSMITTING)
|
||||
{
|
||||
transmit_buffer();
|
||||
}
|
||||
|
||||
if ((uart_event->evt_type == APP_UART_DATA) && (!rx_buffer_overflowed()))
|
||||
{
|
||||
handle_rx_byte(uart_event->data.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function for enabling the UART module when the SLIP layer is opened.
|
||||
*/
|
||||
static uint32_t slip_uart_open(void)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
app_uart_comm_params_t comm_params =
|
||||
{
|
||||
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_UART_BAUDRATE
|
||||
};
|
||||
|
||||
err_code = app_uart_init(&comm_params,
|
||||
NULL,
|
||||
slip_uart_eventhandler,
|
||||
APP_IRQ_PRIORITY_LOWEST);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
m_current_state = SLIP_READY;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler)
|
||||
{
|
||||
m_slip_event_handler = event_handler;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_slip_open()
|
||||
{
|
||||
switch (m_current_state)
|
||||
{
|
||||
case SLIP_OFF:
|
||||
return slip_uart_open();
|
||||
|
||||
default:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_slip_close()
|
||||
{
|
||||
m_current_state = SLIP_OFF;
|
||||
uint32_t err_code = app_uart_close();
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length)
|
||||
{
|
||||
if (p_buffer == NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_ADDR;
|
||||
}
|
||||
|
||||
switch (m_current_state)
|
||||
{
|
||||
case SLIP_READY:
|
||||
m_tx_buffer_index = 0;
|
||||
m_tx_buffer_length = length;
|
||||
mp_tx_buffer = p_buffer;
|
||||
m_current_state = SLIP_TRANSMITTING;
|
||||
send_tx_byte = send_tx_byte_end;
|
||||
|
||||
transmit_buffer();
|
||||
return NRF_SUCCESS;
|
||||
|
||||
case SLIP_TRANSMITTING:
|
||||
return NRF_ERROR_NO_MEM;
|
||||
|
||||
case SLIP_OFF:
|
||||
default:
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length)
|
||||
{
|
||||
mp_rx_buffer = p_buffer;
|
||||
m_rx_buffer_length = length;
|
||||
m_rx_received_count = 0;
|
||||
handle_rx_byte = handle_rx_byte_wait_start;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
#endif //NRF_MODULE_ENABLED(HCI_SLIP)
|
165
lib/sdk/components/libraries/hci/hci_slip.h
Normal file
165
lib/sdk/components/libraries/hci/hci_slip.h
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* 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
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief SLIP layer for supporting packet framing in HCI transport.
|
||||
*
|
||||
* @details This module implements SLIP packet framing as described in the Bluetooth Core
|
||||
* Specification 4.0, Volume 4, Part D, Chapter 3 SLIP Layer.
|
||||
*
|
||||
* SLIP framing ensures that all packets sent on the UART are framed as:
|
||||
* <0xC0> SLIP packet 1 <0xC0> <0xC0> SLIP packet 2 <0xC0>.
|
||||
*
|
||||
* The SLIP layer uses events to notify the upper layer when data transmission is complete
|
||||
* and when a SLIP packet is received.
|
||||
*/
|
||||
|
||||
#ifndef HCI_SLIP_H__
|
||||
#define HCI_SLIP_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Event types from the SLIP Layer. */
|
||||
typedef enum
|
||||
{
|
||||
HCI_SLIP_RX_RDY, /**< An event indicating that an RX packet is ready to be read. */
|
||||
HCI_SLIP_TX_DONE, /**< An event indicating write completion of the TX packet provided in the function call \ref hci_slip_write . */
|
||||
HCI_SLIP_RX_OVERFLOW, /**< An event indicating that RX data has been discarded due to lack of free RX memory. */
|
||||
HCI_SLIP_ERROR, /**< An event indicating that an unrecoverable error has occurred. */
|
||||
HCI_SLIP_EVT_TYPE_MAX /**< Enumeration upper bound. */
|
||||
} hci_slip_evt_type_t;
|
||||
|
||||
/**@brief Structure containing an event from the SLIP layer.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
hci_slip_evt_type_t evt_type; /**< Type of event. */
|
||||
const uint8_t * packet; /**< This field contains a pointer to the packet for which the event relates, i.e. SLIP_TX_DONE: the packet transmitted, SLIP_RX_RDY: the packet received, SLIP_RX_OVERFLOW: The packet which overflow/or NULL if no receive buffer is available. */
|
||||
uint32_t packet_length; /**< Packet length, i.e. SLIP_TX_DONE: Bytes transmitted, SLIP_RX_RDY: Bytes received, SLIP_RX_OVERFLOW: index at which the packet overflowed. */
|
||||
} hci_slip_evt_t;
|
||||
|
||||
/**@brief Function for the SLIP layer event callback.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param[in] event_handler This function is called by the SLIP layer upon an event.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
*
|
||||
* The SLIP layer module will propagate errors from underlying sub-modules.
|
||||
* This implementation is using UART module as a physical transmission layer, and hci_slip_open
|
||||
* executes \ref app_uart_init . For an extended error list, please refer to \ref app_uart_init .
|
||||
*/
|
||||
uint32_t hci_slip_open(void);
|
||||
|
||||
/**@brief Function for closing the SLIP layer. After this function is called no data can be
|
||||
* 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.
|
||||
*/
|
||||
uint32_t hci_slip_close(void);
|
||||
|
||||
/**@brief Function for writing a packet with SLIP encoding. Packet transmission is confirmed when
|
||||
* the HCI_SLIP_TX_DONE event is received by the function caller.
|
||||
*
|
||||
* @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
|
||||
* 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
|
||||
* the \ref HCI_SLIP_TX_DONE event. After HCI_SLIP_TX_DONE this
|
||||
* function can be executed for transmission of next packet.
|
||||
* @retval NRF_ERROR_INVALID_ADDR If a NULL pointer is provided.
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. Module is not open.
|
||||
*/
|
||||
uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length);
|
||||
|
||||
/**@brief Function for registering a receive buffer. The receive buffer will be used for storage of
|
||||
* received and SLIP decoded data.
|
||||
* No data can be received by the SLIP layer until a receive buffer has been registered.
|
||||
*
|
||||
* @note The lifetime of the buffer must be valid during complete reception of data. A static
|
||||
* buffer is recommended.
|
||||
*
|
||||
* @warning Multiple registration requests will overwrite any existing registration.
|
||||
*
|
||||
* @param[in] p_buffer Pointer to receive buffer. The received and SLIP decoded packet
|
||||
* will be placed in this buffer.
|
||||
* @param[in] length Buffer length, in bytes.
|
||||
*
|
||||
* @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__
|
||||
|
||||
/** @} */
|
808
lib/sdk/components/libraries/hci/hci_transport.c
Normal file
808
lib/sdk/components/libraries/hci/hci_transport.c
Normal file
@ -0,0 +1,808 @@
|
||||
/**
|
||||
* 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_TRANSPORT)
|
||||
#include "hci_transport.h"
|
||||
#include "hci_slip.h"
|
||||
#include "crc16.h"
|
||||
#include "hci_mem_pool.h"
|
||||
#include "app_timer.h"
|
||||
#include "app_error.h"
|
||||
#include <stdio.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. */
|
||||
#define PKT_TYPE_VENDOR_SPECIFIC 14u /**< Packet type vendor specific. */
|
||||
#define PKT_TYPE_ACK 0 /**< Packet type acknowledgement. */
|
||||
#define DATA_INTEGRITY_MASK (1u << 6u) /**< Mask for data integrity bit in the packet header. */
|
||||
#define RELIABLE_PKT_MASK (1u << 7u) /**< Mask for reliable packet bit in the packet header. */
|
||||
#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 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_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;
|
||||
|
||||
/**@brief TX state machine events. */
|
||||
typedef enum
|
||||
{
|
||||
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. */
|
||||
} tx_event_t;
|
||||
|
||||
static void tx_sm_state_change(tx_state_t new_state);
|
||||
|
||||
static tx_state_t m_tx_state; /**< Current TX state. */
|
||||
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 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. */
|
||||
APP_TIMER_DEF(m_app_timer_id); /**< Application timer id. */
|
||||
static uint32_t m_tx_retry_counter; /**< Application packet retransmission counter. */
|
||||
static hci_transport_tx_done_result_t m_tx_done_result_code; /**< TX done event callback function result code. */
|
||||
static uint8_t m_rx_ack_buffer[ACK_BUF_SIZE];/**< RX buffer big enough to hold an acknowledgement packet and which is taken in use upon receiving HCI_SLIP_RX_OVERFLOW event. */
|
||||
|
||||
|
||||
/**@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.
|
||||
*
|
||||
* @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
|
||||
// - verify reliable packet bit set
|
||||
// - verify supported packet type
|
||||
// - verify header checksum
|
||||
// - verify payload length field
|
||||
// - verify CRC
|
||||
if (length <= PKT_HDR_SIZE)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for getting the sequence number of the next reliable packet expected.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for calculating a packet header checksum.
|
||||
*
|
||||
* @param[in] p_hdr Pointer to the packet header.
|
||||
*
|
||||
* @return Calculated checksum.
|
||||
*/
|
||||
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 &= 0xFFu;
|
||||
checksum = (~checksum + 1u);
|
||||
|
||||
return (uint8_t)checksum;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for writing an acknowledgment packet for transmission.
|
||||
*/
|
||||
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
|
||||
ack_packet[0] = (packet_number_expected_get() << 3u);
|
||||
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
|
||||
// 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)));
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for validating a received packet.
|
||||
*
|
||||
* @param[in] p_buffer Pointer to the packet data.
|
||||
*
|
||||
* @return sequence number field of the packet header with unrelated data masked out.
|
||||
*/
|
||||
static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer)
|
||||
{
|
||||
return (p_buffer[0] & 0x07u);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for incrementing the sequence number counter for next reliable packet expected.
|
||||
*/
|
||||
static __INLINE void packet_number_expected_inc(void)
|
||||
{
|
||||
++m_packet_expected_seq_number;
|
||||
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.
|
||||
*
|
||||
* @return Packet type field or INVALID_PKT_TYPE in case of decode error.
|
||||
*/
|
||||
static __INLINE uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t length)
|
||||
{
|
||||
// @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.
|
||||
*/
|
||||
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.
|
||||
const uint8_t rx_seq_number = packet_seq_nmbr_extract(p_buffer);
|
||||
if (packet_number_expected_get() == rx_seq_number)
|
||||
{
|
||||
// Sequence number is valid: transmit acknowledgement.
|
||||
packet_number_expected_inc();
|
||||
ack_transmit();
|
||||
|
||||
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(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.
|
||||
err_code = hci_slip_rx_buffer_register(
|
||||
(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);
|
||||
|
||||
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, 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();
|
||||
}
|
||||
}
|
||||
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, 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
|
||||
* entity acknowledgment is pending.
|
||||
*
|
||||
* @return sequence number of a reliable TX packet for which peer protocol entity acknowledgement
|
||||
* is pending.
|
||||
*/
|
||||
static __INLINE uint8_t packet_number_to_transmit_get(void)
|
||||
{
|
||||
return m_packet_transmit_seq_number;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for getting the expected acknowledgement number.
|
||||
*
|
||||
* @return expected acknowledgement number.
|
||||
*/
|
||||
static __INLINE uint8_t expected_ack_number_get(void)
|
||||
{
|
||||
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.
|
||||
*
|
||||
* @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 =
|
||||
((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.
|
||||
*/
|
||||
static __INLINE void packet_number_tx_inc(void)
|
||||
{
|
||||
++m_packet_transmit_seq_number;
|
||||
m_packet_transmit_seq_number &= 0x07u;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for TX state machine event processing in a state centric manner.
|
||||
*
|
||||
* @param[in] event Type of event occurred.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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
|
||||
// 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);
|
||||
}
|
||||
break;
|
||||
|
||||
case TX_STATE_ACTIVE:
|
||||
switch (event)
|
||||
{
|
||||
case TX_EVENT_VALID_RX_ACK:
|
||||
// Tx sequence number counter incremented as packet transmission
|
||||
// acknowledged by peer transport entity.
|
||||
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,
|
||||
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)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Application packet retransmission count reached:
|
||||
// - set correct TX done event callback function result code
|
||||
// - 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;
|
||||
tx_sm_state_change(TX_STATE_IDLE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// No implementation needed.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// No implementation needed.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for changing the state of the TX state machine.
|
||||
*
|
||||
* @param[in] new_state State TX state machine transits to.
|
||||
*/
|
||||
static void tx_sm_state_change(tx_state_t new_state)
|
||||
{
|
||||
m_tx_state = new_state;
|
||||
tx_sm_event_handle(TX_EVENT_STATE_ENTRY);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling slip events.
|
||||
*
|
||||
* @param[in] event The event structure.
|
||||
*/
|
||||
void slip_event_handle(hci_slip_evt_t event)
|
||||
{
|
||||
uint32_t return_code;
|
||||
uint32_t err_code;
|
||||
|
||||
switch (event.evt_type)
|
||||
{
|
||||
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
|
||||
// callback function result code and execute state change.
|
||||
m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS;
|
||||
tx_sm_event_handle(TX_EVENT_VALID_RX_ACK);
|
||||
}
|
||||
|
||||
/* 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.
|
||||
if (mp_slip_used_rx_buffer != NULL)
|
||||
{
|
||||
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(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) ? 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);
|
||||
break;
|
||||
|
||||
case HCI_SLIP_ERROR:
|
||||
APP_ERROR_HANDLER(event.evt_type);
|
||||
break;
|
||||
|
||||
default:
|
||||
APP_ERROR_HANDLER(event.evt_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**@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
|
||||
* undefined, see @ref nrf51_system_integration_serialization.
|
||||
*
|
||||
* @param[in] p_context The timeout context.
|
||||
*/
|
||||
void hci_transport_timeout_handle(void * p_context)
|
||||
{
|
||||
tx_sm_event_handle(TX_EVENT_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_transport_open(void)
|
||||
{
|
||||
mp_tx_buffer = NULL;
|
||||
m_tx_buffer_length = 0;
|
||||
m_tx_retry_counter = 0;
|
||||
m_is_slip_decode_ready = false;
|
||||
m_tx_state = TX_STATE_IDLE;
|
||||
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,
|
||||
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(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;
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_transport_close(void)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_transport_tx_done_handle = NULL;
|
||||
m_transport_event_handle = NULL;
|
||||
|
||||
err_code = hci_mem_pool_close();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
err_code = hci_slip_close();
|
||||
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);
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
// @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;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t hci_transport_tx_free(void)
|
||||
{
|
||||
return hci_mem_pool_tx_free();
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for constructing 1st byte of the packet header of the packet to be transmitted.
|
||||
*
|
||||
* @return 1st byte of the packet header of the packet to be transmitted
|
||||
*/
|
||||
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();
|
||||
|
||||
return (uint8_t) value;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling the application packet write request in tx-idle state.
|
||||
*/
|
||||
static uint32_t pkt_write_handle(void)
|
||||
{
|
||||
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);
|
||||
// @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));
|
||||
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);
|
||||
err_code = NRF_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
// No implementation needed.
|
||||
break;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
err_code = pkt_write_handle();
|
||||
break;
|
||||
|
||||
default:
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
*pp_buffer += PKT_HDR_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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));
|
||||
}
|
||||
#endif //NRF_MODULE_ENABLED(HCI_TRANSPORT)
|
256
lib/sdk/components/libraries/hci/hci_transport.h
Normal file
256
lib/sdk/components/libraries/hci/hci_transport.h
Normal file
@ -0,0 +1,256 @@
|
||||
/**
|
||||
* 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
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief HCI transport module implementation.
|
||||
*
|
||||
* 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
|
||||
* - Transmission and reception of Vendor Specific HCI packet type application packets.
|
||||
* - Transmission and reception of reliable packets: defined by chapter 6 of the specification.
|
||||
*
|
||||
* \par Features not supported
|
||||
* - Link establishment procedure: defined by chapter 8 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
|
||||
* are used:
|
||||
* + 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
|
||||
* 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.
|
||||
*
|
||||
* \par Implementation specific limitations
|
||||
* 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
|
||||
* pipeline which will trigger the retransmission algorithm within the peer protocol entity.
|
||||
* - 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 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
|
||||
* that unnecessary application packet retransmissions can occur.
|
||||
*
|
||||
* The application TX packet processing flow is illustrated by the statemachine below.
|
||||
*
|
||||
* @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
|
||||
* implementations:
|
||||
* - 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
|
||||
* 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_t;
|
||||
|
||||
/**@brief Struct containing events from the Transport layer.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
hci_transport_evt_type_t evt_type; /**< Type of event. */
|
||||
} hci_transport_evt_t;
|
||||
|
||||
/**@brief Transport layer generic event callback function type.
|
||||
*
|
||||
* @param[in] event Transport layer event.
|
||||
*/
|
||||
typedef void (*hci_transport_event_handler_t)(hci_transport_evt_t event);
|
||||
|
||||
/**@brief TX done event callback function result codes. */
|
||||
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_result_t;
|
||||
|
||||
/**@brief Transport layer TX done event callback function type.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
* order.
|
||||
*
|
||||
* @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
|
||||
* have completed.
|
||||
*
|
||||
* @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_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not
|
||||
* 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_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
|
||||
* hci_transport_rx_pkt_consume().
|
||||
*
|
||||
* @param[out] pp_buffer Pointer to the packet data.
|
||||
* @param[out] p_length Length of packet data in bytes.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length);
|
||||
|
||||
/**@brief Function for consuming extracted packet described by p_buffer.
|
||||
*
|
||||
* RX memory pointed to by p_buffer is freed and can be reused by the underlying transport layer.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HCI_TRANSPORT_H__
|
||||
|
||||
/** @} */
|
288
lib/sdk/components/libraries/scheduler/app_scheduler.c
Normal file
288
lib/sdk/components/libraries/scheduler/app_scheduler.c
Normal file
@ -0,0 +1,288 @@
|
||||
/**
|
||||
* 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_platform.h"
|
||||
|
||||
/**@brief Structure for holding a scheduled event header. */
|
||||
typedef struct
|
||||
{
|
||||
app_sched_event_handler_t handler; /**< Pointer to event handler to receive the event. */
|
||||
uint16_t event_data_size; /**< Size of event data. */
|
||||
} event_header_t;
|
||||
|
||||
STATIC_ASSERT(sizeof(event_header_t) <= APP_SCHED_EVENT_HEADER_SIZE);
|
||||
|
||||
static event_header_t * m_queue_event_headers; /**< Array for holding the queue event headers. */
|
||||
static uint8_t * m_queue_event_data; /**< Array for holding the queue event data. */
|
||||
static volatile uint8_t m_queue_start_index; /**< Index of queue entry at the start of the queue. */
|
||||
static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the end of the queue. */
|
||||
static uint16_t m_queue_event_size; /**< Maximum event size in queue. */
|
||||
static uint16_t m_queue_size; /**< Number of queue entries. */
|
||||
|
||||
#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.
|
||||
*
|
||||
* @return New (incremented) index.
|
||||
*/
|
||||
static __INLINE uint8_t next_index(uint8_t index)
|
||||
{
|
||||
return (index < m_queue_size) ? (index + 1) : 0;
|
||||
}
|
||||
|
||||
|
||||
static __INLINE uint8_t app_sched_queue_full()
|
||||
{
|
||||
uint8_t tmp = m_queue_start_index;
|
||||
return next_index(m_queue_end_index) == tmp;
|
||||
}
|
||||
|
||||
/**@brief Macro for checking if a queue is full. */
|
||||
#define APP_SCHED_QUEUE_FULL() app_sched_queue_full()
|
||||
|
||||
|
||||
static __INLINE uint8_t app_sched_queue_empty()
|
||||
{
|
||||
uint8_t tmp = m_queue_start_index;
|
||||
return m_queue_end_index == tmp;
|
||||
}
|
||||
|
||||
/**@brief Macro for checking if a queue is empty. */
|
||||
#define APP_SCHED_QUEUE_EMPTY() app_sched_queue_empty()
|
||||
|
||||
|
||||
uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer)
|
||||
{
|
||||
uint16_t data_start_index = (queue_size + 1) * sizeof(event_header_t);
|
||||
|
||||
// Check that buffer is correctly aligned
|
||||
if (!is_word_aligned(p_event_buffer))
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Initialize event scheduler
|
||||
m_queue_event_headers = p_event_buffer;
|
||||
m_queue_event_data = &((uint8_t *)p_event_buffer)[data_start_index];
|
||||
m_queue_end_index = 0;
|
||||
m_queue_start_index = 0;
|
||||
m_queue_event_size = event_size;
|
||||
m_queue_size = queue_size;
|
||||
|
||||
#if APP_SCHEDULER_WITH_PROFILER
|
||||
m_max_queue_utilization = 0;
|
||||
#endif
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
uint16_t end = m_queue_end_index;
|
||||
uint16_t queue_utilization = (end >= start) ? (end - start) :
|
||||
(m_queue_size + 1 - start + end);
|
||||
|
||||
if (queue_utilization > m_max_queue_utilization)
|
||||
{
|
||||
m_max_queue_utilization = queue_utilization;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t app_sched_queue_utilization_get(void)
|
||||
{
|
||||
return m_max_queue_utilization;
|
||||
}
|
||||
#endif // APP_SCHEDULER_WITH_PROFILER
|
||||
|
||||
|
||||
uint32_t app_sched_event_put(void const * p_event_data,
|
||||
uint16_t event_data_size,
|
||||
app_sched_event_handler_t handler)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
if (event_data_size <= m_queue_event_size)
|
||||
{
|
||||
uint16_t event_index = 0xFFFF;
|
||||
|
||||
CRITICAL_REGION_ENTER();
|
||||
|
||||
if (!APP_SCHED_QUEUE_FULL())
|
||||
{
|
||||
event_index = m_queue_end_index;
|
||||
m_queue_end_index = next_index(m_queue_end_index);
|
||||
|
||||
#if APP_SCHEDULER_WITH_PROFILER
|
||||
// This function call must be protected with critical region because
|
||||
// it modifies 'm_max_queue_utilization'.
|
||||
queue_utilization_check();
|
||||
#endif
|
||||
}
|
||||
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
if (event_index != 0xFFFF)
|
||||
{
|
||||
// NOTE: This can be done outside the critical region since the event consumer will
|
||||
// always be called from the main loop, and will thus never interrupt this code.
|
||||
m_queue_event_headers[event_index].handler = handler;
|
||||
if ((p_event_data != NULL) && (event_data_size > 0))
|
||||
{
|
||||
memcpy(&m_queue_event_data[event_index * m_queue_event_size],
|
||||
p_event_data,
|
||||
event_data_size);
|
||||
m_queue_event_headers[event_index].event_data_size = event_data_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_queue_event_headers[event_index].event_data_size = 0;
|
||||
}
|
||||
|
||||
err_code = NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
#if APP_SCHEDULER_WITH_PAUSE
|
||||
void app_sched_pause(void)
|
||||
{
|
||||
CRITICAL_REGION_ENTER();
|
||||
|
||||
if (m_scheduler_paused_counter < UINT32_MAX)
|
||||
{
|
||||
m_scheduler_paused_counter++;
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
211
lib/sdk/components/libraries/scheduler/app_scheduler.h
Normal file
211
lib/sdk/components/libraries/scheduler/app_scheduler.h
Normal file
@ -0,0 +1,211 @@
|
||||
/**
|
||||
* 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
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief The scheduler is used for transferring execution from the interrupt context to the main
|
||||
* context.
|
||||
*
|
||||
* @details See @ref seq_diagrams_sched for sequence diagrams illustrating the flow of events
|
||||
* when using the Scheduler.
|
||||
*
|
||||
* @section app_scheduler_req Requirements:
|
||||
*
|
||||
* @subsection main_context_logic Logic in main context:
|
||||
*
|
||||
* - Define an event handler for each type of event expected.
|
||||
* - Initialize the scheduler by calling the APP_SCHED_INIT() macro before entering the
|
||||
* application main loop.
|
||||
* - Call app_sched_execute() from the main loop each time the application wakes up because of an
|
||||
* event (typically when sd_app_evt_wait() returns).
|
||||
*
|
||||
* @subsection int_context_logic Logic in interrupt context:
|
||||
*
|
||||
* - In the interrupt handler, call app_sched_event_put()
|
||||
* with the appropriate data and event handler. This will insert an event into the
|
||||
* scheduler's queue. The app_sched_execute() function will pull this event and call its
|
||||
* handler in the main context.
|
||||
*
|
||||
* @if (PERIPHERAL)
|
||||
* For an example usage of the scheduler, see the implementations of
|
||||
* @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
|
||||
* @endif
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler.
|
||||
* @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events
|
||||
* that can be scheduled for execution).
|
||||
*
|
||||
* @return Required scheduler buffer size (in bytes).
|
||||
*/
|
||||
#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);
|
||||
|
||||
/**@brief Macro for initializing the event scheduler.
|
||||
*
|
||||
* @details It will also handle dimensioning and allocation of the memory buffer required by the
|
||||
* scheduler, making sure the buffer is correctly aligned.
|
||||
*
|
||||
* @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler.
|
||||
* @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events
|
||||
* that can be scheduled for execution).
|
||||
*
|
||||
* @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_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE) \
|
||||
do \
|
||||
{ \
|
||||
static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)), \
|
||||
sizeof(uint32_t))]; \
|
||||
uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF); \
|
||||
APP_ERROR_CHECK(ERR_CODE); \
|
||||
} while (0)
|
||||
|
||||
/**@brief Function for initializing the Scheduler.
|
||||
*
|
||||
* @details It must be called before entering the main loop.
|
||||
*
|
||||
* @param[in] max_event_size Maximum size of events to be passed through the scheduler.
|
||||
* @param[in] queue_size Number of entries in scheduler queue (i.e. the maximum number of
|
||||
* events that can be scheduled for execution).
|
||||
* @param[in] p_evt_buffer Pointer to memory buffer for holding the scheduler queue. It must
|
||||
* be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer
|
||||
* must be aligned to a 4 byte boundary.
|
||||
*
|
||||
* @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both
|
||||
* allocate the scheduler buffer, and also align the buffer correctly.
|
||||
*
|
||||
* @retval NRF_SUCCESS Successful initialization.
|
||||
* @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte
|
||||
* boundary).
|
||||
*/
|
||||
uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer);
|
||||
|
||||
/**@brief Function for executing all scheduled events.
|
||||
*
|
||||
* @details This function must be called from within the main loop. It will execute all events
|
||||
* scheduled since the last time it was called.
|
||||
*/
|
||||
void app_sched_execute(void);
|
||||
|
||||
/**@brief Function for scheduling an event.
|
||||
*
|
||||
* @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] handler Event handler to receive the event.
|
||||
*
|
||||
* @return NRF_SUCCESS on success, otherwise an error code.
|
||||
*/
|
||||
uint32_t app_sched_event_put(void const * p_event_data,
|
||||
uint16_t event_size,
|
||||
app_sched_event_handler_t handler);
|
||||
|
||||
/**@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);
|
||||
|
||||
/**@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);
|
||||
|
||||
/**@brief A function to resume a scheduler.
|
||||
*
|
||||
* @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__
|
||||
|
||||
/** @} */
|
1070
lib/sdk/components/libraries/timer/app_timer.c
Normal file
1070
lib/sdk/components/libraries/timer/app_timer.c
Normal file
File diff suppressed because it is too large
Load Diff
264
lib/sdk/components/libraries/timer/app_timer.h
Normal file
264
lib/sdk/components/libraries/timer/app_timer.h
Normal file
@ -0,0 +1,264 @@
|
||||
/**
|
||||
* 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
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @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 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.
|
||||
*
|
||||
* @details When calling app_timer_start() or app_timer_stop(), the timer operation is just queued,
|
||||
* and the software interrupt is triggered. The actual timer start/stop operation is
|
||||
* executed by the SWI0 interrupt handler. Since the SWI0 interrupt is running in APP_LOW,
|
||||
* if the application code calling the timer function is running in APP_LOW or APP_HIGH,
|
||||
* the timer operation will not be performed until the application handler has returned.
|
||||
* This will be the case, for example, when stopping a timer from a time-out handler when not using
|
||||
* 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
|
||||
* 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 "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>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#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 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.
|
||||
*
|
||||
* @param[in] MS Milliseconds.
|
||||
*
|
||||
* @return Number of timer ticks.
|
||||
*/
|
||||
#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.
|
||||
* Never declare a variable of this type, but use the macro @ref APP_TIMER_DEF instead.*/
|
||||
typedef app_timer_t * app_timer_id_t;
|
||||
|
||||
/**
|
||||
* @brief Create a timer identifier and statically allocate memory for the timer.
|
||||
*
|
||||
* @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 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 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
|
||||
{
|
||||
APP_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */
|
||||
APP_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */
|
||||
} app_timer_mode_t;
|
||||
|
||||
/**@brief Function for initializing the timer module.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the module was initialized successfully.
|
||||
*/
|
||||
ret_code_t app_timer_init(void);
|
||||
|
||||
/**@brief Function for creating a timer instance.
|
||||
*
|
||||
* @param[in] p_timer_id Pointer to timer identifier.
|
||||
* @param[in] mode Timer mode.
|
||||
* @param[in] timeout_handler Function to be executed when the timer expires.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the timer was successfully created.
|
||||
* @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
|
||||
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or
|
||||
* the timer is running.
|
||||
*
|
||||
* @note This function does the timer allocation in the caller's context. It is also not protected
|
||||
* by a critical region. Therefore care must be taken not to call it from several interrupt
|
||||
* levels simultaneously.
|
||||
* @note The function can be called again on the timer instance and will re-initialize the instance if
|
||||
* the timer is not running.
|
||||
* @attention The FreeRTOS and RTX app_timer implementation does not allow app_timer_create to
|
||||
* be called on the previously initialized instance.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param[in] timer_id Timer identifier.
|
||||
* @param[in] timeout_ticks Number of ticks (of RTC1, including prescaling) to time-out event
|
||||
* (minimum 5 ticks).
|
||||
* @param[in] p_context General purpose pointer. Will be passed to the time-out handler when
|
||||
* the timer expires.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the timer was successfully started.
|
||||
* @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
|
||||
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or the timer
|
||||
* has not been created.
|
||||
* @retval NRF_ERROR_NO_MEM If the timer operations queue was full.
|
||||
*
|
||||
* @note The minimum timeout_ticks value is 5.
|
||||
* @note For multiple active timers, time-outs occurring in close proximity to each other (in the
|
||||
* range of 1 to 3 ticks) will have a positive jitter of maximum 3 ticks.
|
||||
* @note When calling this method on a timer that is already running, the second start operation
|
||||
* is ignored.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param[in] timer_id Timer identifier.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the timer was successfully stopped.
|
||||
* @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
|
||||
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or the timer
|
||||
* has not been created.
|
||||
* @retval NRF_ERROR_NO_MEM If the timer operations queue was full.
|
||||
*/
|
||||
ret_code_t app_timer_stop(app_timer_id_t timer_id);
|
||||
|
||||
/**@brief Function for stopping all running timers.
|
||||
*
|
||||
* @retval NRF_SUCCESS If all timers were successfully stopped.
|
||||
* @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.
|
||||
*/
|
||||
ret_code_t app_timer_stop_all(void);
|
||||
|
||||
/**@brief Function for returning the current value of the RTC1 counter.
|
||||
*
|
||||
* @return Current value of the RTC1 counter.
|
||||
*/
|
||||
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().
|
||||
*
|
||||
* @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);
|
||||
|
||||
|
||||
/**@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__
|
||||
|
||||
/** @} */
|
167
lib/sdk/components/libraries/uart/app_uart.c
Normal file
167
lib/sdk/components/libraries/uart/app_uart.c
Normal file
@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 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_UART)
|
||||
#include "app_uart.h"
|
||||
#include "nrf_drv_uart.h"
|
||||
#include "nrf_assert.h"
|
||||
|
||||
static uint8_t tx_buffer[1];
|
||||
static uint8_t rx_buffer[1];
|
||||
static volatile bool rx_done;
|
||||
static app_uart_event_handler_t m_event_handler; /**< Event handler function. */
|
||||
static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE);
|
||||
|
||||
static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context)
|
||||
{
|
||||
if (p_event->type == NRF_DRV_UART_EVT_RX_DONE)
|
||||
{
|
||||
app_uart_evt_t app_uart_event;
|
||||
app_uart_event.evt_type = APP_UART_DATA;
|
||||
app_uart_event.data.value = p_event->data.rxtx.p_data[0];
|
||||
(void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
|
||||
rx_done = true;
|
||||
m_event_handler(&app_uart_event);
|
||||
}
|
||||
else if (p_event->type == NRF_DRV_UART_EVT_ERROR)
|
||||
{
|
||||
app_uart_evt_t app_uart_event;
|
||||
app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR;
|
||||
app_uart_event.data.error_communication = p_event->data.error.error_mask;
|
||||
(void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
|
||||
m_event_handler(&app_uart_event);
|
||||
}
|
||||
else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE)
|
||||
{
|
||||
// Last byte from FIFO transmitted, notify the application.
|
||||
// Notify that new data is available if this was first byte put in the buffer.
|
||||
app_uart_evt_t app_uart_event;
|
||||
app_uart_event.evt_type = APP_UART_TX_EMPTY;
|
||||
m_event_handler(&app_uart_event);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
|
||||
app_uart_buffers_t * p_buffers,
|
||||
app_uart_event_handler_t event_handler,
|
||||
app_irq_priority_t irq_priority)
|
||||
{
|
||||
nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
|
||||
config.baudrate = (nrf_uart_baudrate_t)p_comm_params->baud_rate;
|
||||
config.hwfc = (p_comm_params->flow_control == APP_UART_FLOW_CONTROL_DISABLED) ?
|
||||
NRF_UART_HWFC_DISABLED : NRF_UART_HWFC_ENABLED;
|
||||
config.interrupt_priority = irq_priority;
|
||||
config.parity = p_comm_params->use_parity ? NRF_UART_PARITY_INCLUDED : NRF_UART_PARITY_EXCLUDED;
|
||||
config.pselcts = p_comm_params->cts_pin_no;
|
||||
config.pselrts = p_comm_params->rts_pin_no;
|
||||
config.pselrxd = p_comm_params->rx_pin_no;
|
||||
config.pseltxd = p_comm_params->tx_pin_no;
|
||||
|
||||
m_event_handler = event_handler;
|
||||
|
||||
rx_done = false;
|
||||
|
||||
uint32_t err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
// Turn on receiver if RX pin is connected
|
||||
if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED)
|
||||
{
|
||||
#ifdef UARTE_PRESENT
|
||||
if (!config.use_easy_dma)
|
||||
#endif
|
||||
{
|
||||
nrf_drv_uart_rx_enable(&app_uart_inst);
|
||||
}
|
||||
|
||||
return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t app_uart_get(uint8_t * p_byte)
|
||||
{
|
||||
ASSERT(p_byte);
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
if (rx_done)
|
||||
{
|
||||
*p_byte = rx_buffer[0];
|
||||
rx_done = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t app_uart_put(uint8_t byte)
|
||||
{
|
||||
tx_buffer[0] = byte;
|
||||
ret_code_t ret = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
|
||||
if (NRF_ERROR_BUSY == ret)
|
||||
{
|
||||
return NRF_ERROR_NO_MEM;
|
||||
}
|
||||
else if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return NRF_ERROR_INTERNAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t app_uart_flush(void)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t app_uart_close(void)
|
||||
{
|
||||
nrf_drv_uart_uninit(&app_uart_inst);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
#endif //NRF_MODULE_ENABLED(APP_UART)
|
262
lib/sdk/components/libraries/uart/app_uart.h
Normal file
262
lib/sdk/components/libraries/uart/app_uart.h
Normal file
@ -0,0 +1,262 @@
|
||||
/**
|
||||
* 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 app_uart UART module
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief UART module interface.
|
||||
*/
|
||||
|
||||
#ifndef APP_UART_H__
|
||||
#define APP_UART_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "app_util_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */
|
||||
|
||||
/**@brief UART Flow Control modes for the peripheral.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
APP_UART_FLOW_CONTROL_DISABLED, /**< UART Hw Flow Control is disabled. */
|
||||
APP_UART_FLOW_CONTROL_ENABLED, /**< Standard UART Hw Flow Control is enabled. */
|
||||
} app_uart_flow_control_t;
|
||||
|
||||
/**@brief UART communication structure holding configuration settings for the peripheral.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t rx_pin_no; /**< RX pin number. */
|
||||
uint32_t tx_pin_no; /**< TX pin number. */
|
||||
uint32_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */
|
||||
uint32_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */
|
||||
app_uart_flow_control_t flow_control; /**< Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */
|
||||
bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */
|
||||
uint32_t baud_rate; /**< Baud rate configuration. */
|
||||
} app_uart_comm_params_t;
|
||||
|
||||
/**@brief UART buffer for transmitting/receiving data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * rx_buf; /**< Pointer to the RX buffer. */
|
||||
uint32_t rx_buf_size; /**< Size of the RX buffer. */
|
||||
uint8_t * tx_buf; /**< Pointer to the TX buffer. */
|
||||
uint32_t tx_buf_size; /**< Size of the TX buffer. */
|
||||
} app_uart_buffers_t;
|
||||
|
||||
/**@brief Enumeration which defines events used by the UART module upon data reception or error.
|
||||
*
|
||||
* @details The event type is used to indicate the type of additional information in the event
|
||||
* @ref app_uart_evt_t.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
APP_UART_DATA_READY, /**< An event indicating that UART data has been received. The data is available in the FIFO and can be fetched using @ref app_uart_get. */
|
||||
APP_UART_FIFO_ERROR, /**< An error in the FIFO module used by the app_uart module has occured. The FIFO error code is stored in app_uart_evt_t.data.error_code field. */
|
||||
APP_UART_COMMUNICATION_ERROR, /**< An communication error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field. */
|
||||
APP_UART_TX_EMPTY, /**< An event indicating that UART has completed transmission of all available data in the TX FIFO. */
|
||||
APP_UART_DATA, /**< An event indicating that UART data has been received, and data is present in data field. This event is only used when no FIFO is configured. */
|
||||
} app_uart_evt_type_t;
|
||||
|
||||
/**@brief Struct containing events from the UART module.
|
||||
*
|
||||
* @details The app_uart_evt_t is used to notify the application of asynchronous events when data
|
||||
* are received on the UART peripheral or in case an error occured during data reception.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
app_uart_evt_type_t evt_type; /**< Type of event. */
|
||||
union
|
||||
{
|
||||
uint32_t error_communication; /**< Field used if evt_type is: APP_UART_COMMUNICATION_ERROR. This field contains the value in the ERRORSRC register for the UART peripheral. The UART_ERRORSRC_x defines from nrf5x_bitfields.h can be used to parse the error code. See also the \nRFXX Series Reference Manual for specification. */
|
||||
uint32_t error_code; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
|
||||
uint8_t value; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
|
||||
} data;
|
||||
} app_uart_evt_t;
|
||||
|
||||
/**@brief Function for handling app_uart event callback.
|
||||
*
|
||||
* @details Upon an event in the app_uart module this callback function will be called to notify
|
||||
* the application about the event.
|
||||
*
|
||||
* @param[in] p_app_uart_event Pointer to UART event.
|
||||
*/
|
||||
typedef void (* app_uart_event_handler_t) (app_uart_evt_t * p_app_uart_event);
|
||||
|
||||
/**@brief Macro for safe initialization of the UART module in a single user instance when using
|
||||
* a FIFO together with UART.
|
||||
*
|
||||
* @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t
|
||||
* @param[in] RX_BUF_SIZE Size of desired RX buffer, must be a power of 2 or ZERO (No FIFO).
|
||||
* @param[in] TX_BUF_SIZE Size of desired TX buffer, must be a power of 2 or ZERO (No FIFO).
|
||||
* @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the
|
||||
* UART module.
|
||||
* @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler.
|
||||
* @param[out] ERR_CODE The return value of the UART initialization function will be
|
||||
* written to this parameter.
|
||||
*
|
||||
* @note Since this macro allocates a buffer and registers the module as a GPIOTE user when flow
|
||||
* control is enabled, it must only be called once.
|
||||
*/
|
||||
#define APP_UART_FIFO_INIT(P_COMM_PARAMS, RX_BUF_SIZE, TX_BUF_SIZE, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \
|
||||
do \
|
||||
{ \
|
||||
app_uart_buffers_t buffers; \
|
||||
static uint8_t rx_buf[RX_BUF_SIZE]; \
|
||||
static uint8_t tx_buf[TX_BUF_SIZE]; \
|
||||
\
|
||||
buffers.rx_buf = rx_buf; \
|
||||
buffers.rx_buf_size = sizeof (rx_buf); \
|
||||
buffers.tx_buf = tx_buf; \
|
||||
buffers.tx_buf_size = sizeof (tx_buf); \
|
||||
ERR_CODE = app_uart_init(P_COMM_PARAMS, &buffers, EVT_HANDLER, IRQ_PRIO); \
|
||||
} while (0)
|
||||
|
||||
/**@brief Macro for safe initialization of the UART module in a single user instance.
|
||||
*
|
||||
* @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t
|
||||
* @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the
|
||||
* UART module.
|
||||
* @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler.
|
||||
* @param[out] ERR_CODE The return value of the UART initialization function will be
|
||||
* written to this parameter.
|
||||
*
|
||||
* @note Since this macro allocates registers the module as a GPIOTE user when flow control is
|
||||
* enabled, it must only be called once.
|
||||
*/
|
||||
#define APP_UART_INIT(P_COMM_PARAMS, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \
|
||||
do \
|
||||
{ \
|
||||
ERR_CODE = app_uart_init(P_COMM_PARAMS, NULL, EVT_HANDLER, IRQ_PRIO); \
|
||||
} while (0)
|
||||
|
||||
/**@brief Function for initializing the UART module. Use this initialization when several instances of the UART
|
||||
* module are needed.
|
||||
*
|
||||
*
|
||||
* @note Normally single initialization should be done using the APP_UART_INIT() or
|
||||
* APP_UART_INIT_FIFO() macro depending on whether the FIFO should be used by the UART, as
|
||||
* that will allocate the buffers needed by the UART module (including aligning the buffer
|
||||
* correctly).
|
||||
|
||||
* @param[in] p_comm_params Pin and communication parameters.
|
||||
* @param[in] p_buffers RX and TX buffers, NULL is FIFO is not used.
|
||||
* @param[in] error_handler Function to be called in case of an error.
|
||||
* @param[in] irq_priority Interrupt priority level.
|
||||
*
|
||||
* @retval NRF_SUCCESS If successful initialization.
|
||||
* @retval NRF_ERROR_INVALID_LENGTH If a provided buffer is not a power of two.
|
||||
* @retval NRF_ERROR_NULL If one of the provided buffers is a NULL pointer.
|
||||
*
|
||||
* The below errors are propagated by the UART module to the caller upon registration when Hardware
|
||||
* Flow Control is enabled. When Hardware Flow Control is not used, these errors cannot occur.
|
||||
* @retval NRF_ERROR_INVALID_STATE The GPIOTE module is not in a valid state when registering
|
||||
* the UART module as a user.
|
||||
* @retval NRF_ERROR_INVALID_PARAM The UART module provides an invalid callback function when
|
||||
* registering the UART module as a user.
|
||||
* Or the value pointed to by *p_uart_uid is not a valid
|
||||
* GPIOTE number.
|
||||
* @retval NRF_ERROR_NO_MEM GPIOTE module has reached the maximum number of users.
|
||||
*/
|
||||
uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
|
||||
app_uart_buffers_t * p_buffers,
|
||||
app_uart_event_handler_t error_handler,
|
||||
app_irq_priority_t irq_priority);
|
||||
|
||||
/**@brief Function for getting a byte from the UART.
|
||||
*
|
||||
* @details This function will get the next byte from the RX buffer. If the RX buffer is empty
|
||||
* an error code will be returned and the app_uart module will generate an event upon
|
||||
* reception of the first byte which is added to the RX buffer.
|
||||
*
|
||||
* @param[out] p_byte Pointer to an address where next byte received on the UART will be copied.
|
||||
*
|
||||
* @retval NRF_SUCCESS If a byte has been received and pushed to the pointer provided.
|
||||
* @retval NRF_ERROR_NOT_FOUND If no byte is available in the RX buffer of the app_uart module.
|
||||
*/
|
||||
uint32_t app_uart_get(uint8_t * p_byte);
|
||||
|
||||
/**@brief Function for putting a byte on the UART.
|
||||
*
|
||||
* @details This call is non-blocking.
|
||||
*
|
||||
* @param[in] byte Byte to be transmitted on the UART.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the byte was successfully put on the TX buffer for transmission.
|
||||
* @retval NRF_ERROR_NO_MEM If no more space is available in the TX buffer.
|
||||
* NRF_ERROR_NO_MEM may occur if flow control is enabled and CTS signal
|
||||
* is high for a long period and the buffer fills up.
|
||||
* @retval NRF_ERROR_INTERNAL If UART driver reported error.
|
||||
*/
|
||||
uint32_t app_uart_put(uint8_t byte);
|
||||
|
||||
/**@brief Function for flushing the RX and TX buffers (Only valid if FIFO is used).
|
||||
* This function does nothing if FIFO is not used.
|
||||
*
|
||||
* @retval NRF_SUCCESS Flushing completed (Current implementation will always succeed).
|
||||
*/
|
||||
uint32_t app_uart_flush(void);
|
||||
|
||||
/**@brief Function for closing the UART module.
|
||||
*
|
||||
* @retval NRF_SUCCESS If successfully closed.
|
||||
* @retval NRF_ERROR_INVALID_PARAM If an invalid user id is provided or the user id differs from
|
||||
* the current active user.
|
||||
*/
|
||||
uint32_t app_uart_close(void);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //APP_UART_H__
|
||||
|
||||
/** @} */
|
143
lib/sdk/components/libraries/util/app_error.c
Normal file
143
lib/sdk/components/libraries/util/app_error.c
Normal file
@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 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_error Common application error handler
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief Common application error handler.
|
||||
*/
|
||||
|
||||
#include "nrf.h"
|
||||
#include <stdio.h>
|
||||
#include "app_error.h"
|
||||
#include "nordic_common.h"
|
||||
#include "sdk_errors.h"
|
||||
/**@brief Function for error handling, which is called when an error has occurred.
|
||||
*
|
||||
* @warning This handler is an example only and does not fit a final product. You need to analyze
|
||||
* how your product is supposed to react in case of error.
|
||||
*
|
||||
* @param[in] error_code Error code supplied to the handler.
|
||||
* @param[in] line_num Line number where the handler is called.
|
||||
* @param[in] p_file_name Pointer to the file name.
|
||||
*/
|
||||
|
||||
/*lint -save -e14 */
|
||||
void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
|
||||
{
|
||||
error_info_t error_info =
|
||||
{
|
||||
.line_num = line_num,
|
||||
.p_file_name = p_file_name,
|
||||
.err_code = error_code,
|
||||
};
|
||||
app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
|
||||
|
||||
UNUSED_VARIABLE(error_info);
|
||||
}
|
||||
|
||||
/*lint -save -e14 */
|
||||
void app_error_handler_bare(ret_code_t error_code)
|
||||
{
|
||||
error_info_t error_info =
|
||||
{
|
||||
.line_num = 0,
|
||||
.p_file_name = NULL,
|
||||
.err_code = error_code,
|
||||
};
|
||||
|
||||
app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
|
||||
|
||||
UNUSED_VARIABLE(error_info);
|
||||
}
|
||||
|
||||
|
||||
void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
|
||||
{
|
||||
/* static error variables - in order to prevent removal by optimizers */
|
||||
static volatile struct
|
||||
{
|
||||
uint32_t fault_id;
|
||||
uint32_t pc;
|
||||
uint32_t error_info;
|
||||
assert_info_t * p_assert_info;
|
||||
error_info_t * p_error_info;
|
||||
ret_code_t err_code;
|
||||
uint32_t line_num;
|
||||
const uint8_t * p_file_name;
|
||||
} m_error_data = {0};
|
||||
|
||||
// The following variable helps Keil keep the call stack visible, in addition, it can be set to
|
||||
// 0 in the debugger to continue executing code after the error check.
|
||||
volatile bool loop = true;
|
||||
UNUSED_VARIABLE(loop);
|
||||
|
||||
m_error_data.fault_id = id;
|
||||
m_error_data.pc = pc;
|
||||
m_error_data.error_info = info;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case NRF_FAULT_ID_SDK_ASSERT:
|
||||
m_error_data.p_assert_info = (assert_info_t *)info;
|
||||
m_error_data.line_num = m_error_data.p_assert_info->line_num;
|
||||
m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name;
|
||||
break;
|
||||
|
||||
case NRF_FAULT_ID_SDK_ERROR:
|
||||
m_error_data.p_error_info = (error_info_t *)info;
|
||||
m_error_data.err_code = m_error_data.p_error_info->err_code;
|
||||
m_error_data.line_num = m_error_data.p_error_info->line_num;
|
||||
m_error_data.p_file_name = m_error_data.p_error_info->p_file_name;
|
||||
break;
|
||||
}
|
||||
|
||||
UNUSED_VARIABLE(m_error_data);
|
||||
|
||||
// If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
|
||||
__disable_irq();
|
||||
while (loop);
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
/*lint -restore */
|
172
lib/sdk/components/libraries/util/app_error.h
Normal file
172
lib/sdk/components/libraries/util/app_error.h
Normal file
@ -0,0 +1,172 @@
|
||||
/**
|
||||
* 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 app_error Common application error handler
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief Common application error handler and macros for utilizing a common error handler.
|
||||
*/
|
||||
|
||||
#ifndef APP_ERROR_H__
|
||||
#define APP_ERROR_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf.h"
|
||||
#include "sdk_errors.h"
|
||||
#include "nordic_common.h"
|
||||
#include "app_error_weak.h"
|
||||
#ifdef ANT_STACK_SUPPORT_REQD
|
||||
#include "ant_error.h"
|
||||
#endif // ANT_STACK_SUPPORT_REQD
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NRF_FAULT_ID_SDK_RANGE_START 0x00004000 /**< The start of the range of error IDs defined in the SDK. */
|
||||
|
||||
/**@defgroup APP_ERROR_FAULT_IDS Fault ID types
|
||||
* @{ */
|
||||
#define NRF_FAULT_ID_SDK_ERROR NRF_FAULT_ID_SDK_RANGE_START + 1 /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */
|
||||
#define NRF_FAULT_ID_SDK_ASSERT NRF_FAULT_ID_SDK_RANGE_START + 2 /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */
|
||||
/**@} */
|
||||
|
||||
/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t line_num; /**< The line number where the error occurred. */
|
||||
uint8_t const * p_file_name; /**< The file in which the error occurred. */
|
||||
uint32_t err_code; /**< The error code representing the error that occurred. */
|
||||
} error_info_t;
|
||||
|
||||
/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t line_num; /**< The line number where the error occurred. */
|
||||
uint8_t const * p_file_name; /**< The file in which the error occurred. */
|
||||
} assert_info_t;
|
||||
|
||||
/**@brief Function for error handling, which is called when an error has occurred.
|
||||
*
|
||||
* @param[in] error_code Error code supplied to the handler.
|
||||
* @param[in] line_num Line number where the handler is called.
|
||||
* @param[in] p_file_name Pointer to the file name.
|
||||
*/
|
||||
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
|
||||
|
||||
/**@brief Function for error handling, which is called when an error has occurred.
|
||||
*
|
||||
* @param[in] error_code Error code supplied to the handler.
|
||||
*/
|
||||
void app_error_handler_bare(ret_code_t error_code);
|
||||
|
||||
/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes.
|
||||
*
|
||||
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
|
||||
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
|
||||
* unavailable.
|
||||
* @param[in] info Optional additional information regarding the fault. Refer to each fault
|
||||
* identifier for details.
|
||||
*/
|
||||
void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info);
|
||||
|
||||
|
||||
/**@brief Macro for calling error handler function.
|
||||
*
|
||||
* @param[in] ERR_CODE Error code supplied to the error handler.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#define APP_ERROR_HANDLER(ERR_CODE) \
|
||||
do \
|
||||
{ \
|
||||
app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define APP_ERROR_HANDLER(ERR_CODE) \
|
||||
do \
|
||||
{ \
|
||||
app_error_handler_bare((ERR_CODE)); \
|
||||
} while (0)
|
||||
#endif
|
||||
/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS.
|
||||
*
|
||||
* @param[in] ERR_CODE Error code supplied to the error handler.
|
||||
*/
|
||||
#define APP_ERROR_CHECK(ERR_CODE) \
|
||||
do \
|
||||
{ \
|
||||
const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \
|
||||
if (LOCAL_ERR_CODE != NRF_SUCCESS) \
|
||||
{ \
|
||||
APP_ERROR_HANDLER(LOCAL_ERR_CODE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**@brief Macro for calling error handler function if supplied boolean value is false.
|
||||
*
|
||||
* @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
|
||||
*/
|
||||
#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \
|
||||
do \
|
||||
{ \
|
||||
const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
|
||||
if (!LOCAL_BOOLEAN_VALUE) \
|
||||
{ \
|
||||
APP_ERROR_HANDLER(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // APP_ERROR_H__
|
||||
|
||||
/** @} */
|
85
lib/sdk/components/libraries/util/app_error_weak.h
Normal file
85
lib/sdk/components/libraries/util/app_error_weak.h
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 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.
|
||||
*
|
||||
*/
|
||||
#ifndef APP_ERROR_WEAK_H__
|
||||
#define APP_ERROR_WEAK_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @defgroup app_error Common application error handler
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief Common application error handler.
|
||||
*/
|
||||
|
||||
/**@brief Callback function for errors, asserts, and faults.
|
||||
*
|
||||
* @details This function is called every time an error is raised in app_error, nrf_assert, or
|
||||
* in the SoftDevice. Information about the error can be found in the @p info
|
||||
* parameter.
|
||||
*
|
||||
* See also @ref nrf_fault_handler_t for more details.
|
||||
*
|
||||
* @note The function is implemented as weak so that it can be redefined by a custom error
|
||||
* handler when needed.
|
||||
*
|
||||
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
|
||||
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
|
||||
* unavailable.
|
||||
* @param[in] info Optional additional information regarding the fault. The value of the @p id
|
||||
* parameter dictates how to interpret this parameter. Refer to the documentation
|
||||
* for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
|
||||
* details about interpreting @p info.
|
||||
*/
|
||||
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // APP_ERROR_WEAK_H__
|
1082
lib/sdk/components/libraries/util/app_util.h
Normal file
1082
lib/sdk/components/libraries/util/app_util.h
Normal file
File diff suppressed because it is too large
Load Diff
449
lib/sdk/components/libraries/util/app_util_bds.h
Normal file
449
lib/sdk/components/libraries/util/app_util_bds.h
Normal file
@ -0,0 +1,449 @@
|
||||
/**
|
||||
* 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_util Utility Functions and Definitions
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief Various types and definitions available to all applications.
|
||||
*/
|
||||
|
||||
#ifndef APP_UTIL_BDS_H__
|
||||
#define APP_UTIL_BDS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "compiler_abstraction.h"
|
||||
#include "app_util.h"
|
||||
#include "ble_srv_common.h"
|
||||
#include "nordic_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint8_t nibble_t;
|
||||
typedef uint32_t uint24_t;
|
||||
typedef uint64_t uint40_t;
|
||||
|
||||
/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * p_list; /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */
|
||||
uint8_t list_len; /**< Length of the byte array. */
|
||||
} regcertdatalist_t;
|
||||
|
||||
/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, meaning 4 bits for exponent (base 10) and 12 bits mantissa) */
|
||||
typedef struct
|
||||
{
|
||||
int8_t exponent; /**< Base 10 exponent, should be using only 4 bits */
|
||||
int16_t mantissa; /**< Mantissa, should be using only 12 bits */
|
||||
} sfloat_t;
|
||||
|
||||
/**@brief Date and Time structure. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
uint8_t hours;
|
||||
uint8_t minutes;
|
||||
uint8_t seconds;
|
||||
} ble_date_time_t;
|
||||
|
||||
|
||||
/**@brief Function for encoding a uint16 value.
|
||||
*
|
||||
* @param[in] p_value Value to be encoded.
|
||||
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
|
||||
*
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint16_encode(const uint16_t * p_value, uint8_t * p_encoded_data)
|
||||
{
|
||||
p_encoded_data[0] = (uint8_t) ((*p_value & 0x00FF) >> 0);
|
||||
p_encoded_data[1] = (uint8_t) ((*p_value & 0xFF00) >> 8);
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
static __INLINE uint8_t bds_int16_encode(const int16_t * p_value, uint8_t * p_encoded_data)
|
||||
{
|
||||
uint16_t tmp = *p_value;
|
||||
return bds_uint16_encode(&tmp, p_encoded_data);
|
||||
}
|
||||
|
||||
/**@brief Function for encoding a uint24 value.
|
||||
*
|
||||
* @param[in] p_value Value to be encoded.
|
||||
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
|
||||
*
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint24_encode(const uint32_t * p_value, uint8_t * p_encoded_data)
|
||||
{
|
||||
p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0);
|
||||
p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8);
|
||||
p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16);
|
||||
return (3);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for encoding a uint32 value.
|
||||
*
|
||||
* @param[in] p_value Value to be encoded.
|
||||
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
|
||||
*
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint32_encode(const uint32_t * p_value, uint8_t * p_encoded_data)
|
||||
{
|
||||
p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0);
|
||||
p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8);
|
||||
p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16);
|
||||
p_encoded_data[3] = (uint8_t) ((*p_value & 0xFF000000) >> 24);
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for encoding a uint40 value.
|
||||
*
|
||||
* @param[in] p_value Value to be encoded.
|
||||
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
|
||||
*
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint40_encode(const uint64_t * p_value, uint8_t * p_encoded_data)
|
||||
{
|
||||
p_encoded_data[0] = (uint8_t) ((*p_value & 0x00000000000000FF) >> 0);
|
||||
p_encoded_data[1] = (uint8_t) ((*p_value & 0x000000000000FF00) >> 8);
|
||||
p_encoded_data[2] = (uint8_t) ((*p_value & 0x0000000000FF0000) >> 16);
|
||||
p_encoded_data[3] = (uint8_t) ((*p_value & 0x00000000FF000000) >> 24);
|
||||
p_encoded_data[4] = (uint8_t) ((*p_value & 0x000000FF00000000) >> 32);
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**@brief Function for encoding a sfloat value.
|
||||
*
|
||||
* @param[in] p_value Value to be encoded.
|
||||
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
|
||||
*
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
static __INLINE uint8_t bds_sfloat_encode(const sfloat_t * p_value, uint8_t * p_encoded_data)
|
||||
{
|
||||
uint16_t encoded_val;
|
||||
|
||||
encoded_val = ((p_value->exponent << 12) & 0xF000) |
|
||||
((p_value->mantissa << 0) & 0x0FFF);
|
||||
|
||||
return(bds_uint16_encode(&encoded_val, p_encoded_data));
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for encoding a uint8_array value.
|
||||
*
|
||||
* @param[in] p_value Value to be encoded.
|
||||
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint8_array_encode(const uint8_array_t * p_value,
|
||||
uint8_t * p_encoded_data)
|
||||
{
|
||||
memcpy(p_encoded_data, p_value->p_data, p_value->size);
|
||||
return p_value->size;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for encoding a utf8_str value.
|
||||
*
|
||||
* @param[in] p_value Value to be encoded.
|
||||
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
|
||||
|
||||
*/
|
||||
static __INLINE uint8_t bds_ble_srv_utf8_str_encode(const ble_srv_utf8_str_t * p_value,
|
||||
uint8_t * p_encoded_data)
|
||||
{
|
||||
memcpy(p_encoded_data, p_value->p_str, p_value->length);
|
||||
return p_value->length;
|
||||
}
|
||||
|
||||
/**@brief Function for encoding a regcertdatalist value.
|
||||
*
|
||||
* @param[in] p_value Value to be encoded.
|
||||
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
|
||||
|
||||
*/
|
||||
static __INLINE uint8_t bds_regcertdatalist_encode(const regcertdatalist_t * p_value,
|
||||
uint8_t * p_encoded_data)
|
||||
{
|
||||
memcpy(p_encoded_data, p_value->p_list, p_value->list_len);
|
||||
return p_value->list_len;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a date_time value.
|
||||
*
|
||||
* @param[in] p_date_time pointer to the date_time structure to encode.
|
||||
* @param[in] p_encoded_data pointer to the encoded data
|
||||
* @return length of the encoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_ble_date_time_encode(const ble_date_time_t * p_date_time,
|
||||
uint8_t * p_encoded_data)
|
||||
{
|
||||
uint8_t len = bds_uint16_encode(&p_date_time->year, &p_encoded_data[0]);
|
||||
|
||||
p_encoded_data[len++] = p_date_time->month;
|
||||
p_encoded_data[len++] = p_date_time->day;
|
||||
p_encoded_data[len++] = p_date_time->hours;
|
||||
p_encoded_data[len++] = p_date_time->minutes;
|
||||
p_encoded_data[len++] = p_date_time->seconds;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a uint16 value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint16_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
uint16_t * p_decoded_val)
|
||||
{
|
||||
UNUSED_VARIABLE(len);
|
||||
*p_decoded_val = (((uint16_t)((uint8_t *)p_encoded_data)[0])) |
|
||||
(((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 );
|
||||
return (sizeof(uint16_t));
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a int16 value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_int16_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
int16_t * p_decoded_val)
|
||||
{
|
||||
UNUSED_VARIABLE(len);
|
||||
uint16_t tmp = 0;
|
||||
uint8_t retval = bds_uint16_decode(len, p_encoded_data, &tmp);
|
||||
*p_decoded_val = (int16_t)tmp;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a uint24 value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
*
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint24_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
uint32_t * p_decoded_val)
|
||||
{
|
||||
UNUSED_VARIABLE(len);
|
||||
*p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
|
||||
(((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
|
||||
(((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16);
|
||||
return (3);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a uint32 value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
*
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint32_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
uint32_t * p_decoded_val)
|
||||
{
|
||||
UNUSED_VARIABLE(len);
|
||||
*p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
|
||||
(((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
|
||||
(((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) |
|
||||
(((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 );
|
||||
return (sizeof(uint32_t));
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a uint40 value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
*
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint40_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
uint64_t * p_decoded_val)
|
||||
{
|
||||
UNUSED_VARIABLE(len);
|
||||
*p_decoded_val = (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
|
||||
(((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
|
||||
(((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
|
||||
(((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24 )|
|
||||
(((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 );
|
||||
return (40);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a sfloat value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
*
|
||||
* @return length of the decoded field.
|
||||
|
||||
*/
|
||||
static __INLINE uint8_t bds_sfloat_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
sfloat_t * p_decoded_val)
|
||||
{
|
||||
|
||||
p_decoded_val->exponent = 0;
|
||||
bds_uint16_decode(len, p_encoded_data, (uint16_t*)&p_decoded_val->mantissa);
|
||||
p_decoded_val->exponent = (uint8_t)((p_decoded_val->mantissa & 0xF000) >> 12);
|
||||
p_decoded_val->mantissa &= 0x0FFF;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a uint8_array value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
*
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
uint8_array_t * p_decoded_val)
|
||||
{
|
||||
memcpy(p_decoded_val->p_data, p_encoded_data, len);
|
||||
p_decoded_val->size = len;
|
||||
return p_decoded_val->size;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a utf8_str value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
*
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
ble_srv_utf8_str_t * p_decoded_val)
|
||||
{
|
||||
p_decoded_val->p_str = (uint8_t*)p_encoded_data;
|
||||
p_decoded_val->length = len;
|
||||
return p_decoded_val->length;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a regcertdatalist value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_decoded_val pointer to the decoded value
|
||||
*
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
regcertdatalist_t * p_decoded_val)
|
||||
{
|
||||
memcpy(p_decoded_val->p_list, p_encoded_data, len);
|
||||
p_decoded_val->list_len = len;
|
||||
return p_decoded_val->list_len;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for decoding a date_time value.
|
||||
*
|
||||
* @param[in] len length of the field to be decoded.
|
||||
* @param[in] p_encoded_data Buffer where the encoded data is stored.
|
||||
* @param[in] p_date_time pointer to the decoded value
|
||||
*
|
||||
* @return length of the decoded field.
|
||||
*/
|
||||
static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len,
|
||||
const uint8_t * p_encoded_data,
|
||||
ble_date_time_t * p_date_time)
|
||||
{
|
||||
UNUSED_VARIABLE(len);
|
||||
uint8_t pos = bds_uint16_decode(len, &p_encoded_data[0], &p_date_time->year);
|
||||
p_date_time->month = p_encoded_data[pos++];
|
||||
p_date_time->day = p_encoded_data[pos++];
|
||||
p_date_time->hours = p_encoded_data[pos++];
|
||||
p_date_time->minutes = p_encoded_data[pos++];
|
||||
p_date_time->seconds = p_encoded_data[pos++];
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // APP_UTIL_BDS_H__
|
||||
|
||||
/** @} */
|
127
lib/sdk/components/libraries/util/app_util_platform.c
Normal file
127
lib/sdk/components/libraries/util/app_util_platform.c
Normal file
@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 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 "app_util_platform.h"
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
/* Global nvic state instance, required by nrf_nvic.h */
|
||||
nrf_nvic_state_t nrf_nvic_state;
|
||||
#endif
|
||||
|
||||
static uint32_t m_in_critical_region = 0;
|
||||
|
||||
void app_util_disable_irq(void)
|
||||
{
|
||||
__disable_irq();
|
||||
m_in_critical_region++;
|
||||
}
|
||||
|
||||
void app_util_enable_irq(void)
|
||||
{
|
||||
m_in_critical_region--;
|
||||
if (m_in_critical_region == 0)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
void app_util_critical_region_enter(uint8_t *p_nested)
|
||||
{
|
||||
#if __CORTEX_M == (0x04U)
|
||||
ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
|
||||
#endif
|
||||
|
||||
#if defined(SOFTDEVICE_PRESENT)
|
||||
/* return value can be safely ignored */
|
||||
(void) sd_nvic_critical_region_enter(p_nested);
|
||||
#else
|
||||
app_util_disable_irq();
|
||||
#endif
|
||||
}
|
||||
|
||||
void app_util_critical_region_exit(uint8_t nested)
|
||||
{
|
||||
#if __CORTEX_M == (0x04U)
|
||||
ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
|
||||
#endif
|
||||
|
||||
#if defined(SOFTDEVICE_PRESENT)
|
||||
/* return value can be safely ignored */
|
||||
(void) sd_nvic_critical_region_exit(nested);
|
||||
#else
|
||||
app_util_enable_irq();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint8_t privilege_level_get(void)
|
||||
{
|
||||
#if __CORTEX_M == (0x00U) || defined(_WIN32) || defined(__unix) || defined(__APPLE__)
|
||||
/* the Cortex-M0 has no concept of privilege */
|
||||
return APP_LEVEL_PRIVILEGED;
|
||||
#elif __CORTEX_M == (0x04U)
|
||||
uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
|
||||
if (0 == isr_vector_num)
|
||||
{
|
||||
/* Thread Mode, check nPRIV */
|
||||
int32_t control = __get_CONTROL();
|
||||
return control & CONTROL_nPRIV_Msk ? APP_LEVEL_UNPRIVILEGED : APP_LEVEL_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handler Mode, always privileged */
|
||||
return APP_LEVEL_PRIVILEGED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint8_t current_int_priority_get(void)
|
||||
{
|
||||
uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
|
||||
if (isr_vector_num > 0)
|
||||
{
|
||||
int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET);
|
||||
return (NVIC_GetPriority((IRQn_Type)irq_type) & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
return APP_IRQ_PRIORITY_THREAD;
|
||||
}
|
||||
}
|
262
lib/sdk/components/libraries/util/app_util_platform.h
Normal file
262
lib/sdk/components/libraries/util/app_util_platform.h
Normal file
@ -0,0 +1,262 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 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_util_platform Utility Functions and Definitions (Platform)
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief Various types and definitions available to all applications when using SoftDevice.
|
||||
*/
|
||||
|
||||
#ifndef APP_UTIL_PLATFORM_H__
|
||||
#define APP_UTIL_PLATFORM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compiler_abstraction.h"
|
||||
#include "nrf.h"
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#include "nrf_soc.h"
|
||||
#include "nrf_nvic.h"
|
||||
#endif
|
||||
#include "nrf_assert.h"
|
||||
#include "app_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if __CORTEX_M == (0x00U)
|
||||
#define _PRIO_SD_HIGH 0
|
||||
#define _PRIO_APP_HIGH 1
|
||||
#define _PRIO_APP_MID 1
|
||||
#define _PRIO_SD_LOW 2
|
||||
#define _PRIO_APP_LOW 3
|
||||
#define _PRIO_APP_LOWEST 3
|
||||
#define _PRIO_THREAD 4
|
||||
#elif __CORTEX_M == (0x04U)
|
||||
#define _PRIO_SD_HIGH 0
|
||||
#define _PRIO_SD_MID 1
|
||||
#define _PRIO_APP_HIGH 2
|
||||
#define _PRIO_APP_MID 3
|
||||
#define _PRIO_SD_LOW 4
|
||||
#define _PRIO_SD_LOWEST 5
|
||||
#define _PRIO_APP_LOW 6
|
||||
#define _PRIO_APP_LOWEST 7
|
||||
#define _PRIO_THREAD 15
|
||||
#else
|
||||
#error "No platform defined"
|
||||
#endif
|
||||
|
||||
|
||||
//lint -save -e113 -e452
|
||||
/**@brief The interrupt priorities available to the application while the SoftDevice is active. */
|
||||
typedef enum
|
||||
{
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH,
|
||||
#else
|
||||
APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH,
|
||||
#endif
|
||||
APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH,
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW,
|
||||
#else
|
||||
APP_IRQ_PRIORITY_MID = _PRIO_APP_MID,
|
||||
#endif
|
||||
APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW,
|
||||
APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST,
|
||||
APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */
|
||||
} app_irq_priority_t;
|
||||
//lint -restore
|
||||
|
||||
|
||||
/*@brief The privilege levels available to applications in Thread Mode */
|
||||
typedef enum
|
||||
{
|
||||
APP_LEVEL_UNPRIVILEGED,
|
||||
APP_LEVEL_PRIVILEGED
|
||||
} app_level_t;
|
||||
|
||||
/**@cond NO_DOXYGEN */
|
||||
#define EXTERNAL_INT_VECTOR_OFFSET 16
|
||||
/**@endcond */
|
||||
|
||||
/**@brief Macro for setting a breakpoint.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
#define NRF_BREAKPOINT __builtin_trap()
|
||||
#else
|
||||
#define NRF_BREAKPOINT __BKPT(0)
|
||||
#endif
|
||||
|
||||
/** @brief Macro for setting a breakpoint.
|
||||
*
|
||||
* If it is possible to detect debugger presence then it is set only in that case.
|
||||
*
|
||||
*/
|
||||
#if __CORTEX_M == 0x04
|
||||
#define NRF_BREAKPOINT_COND do { \
|
||||
/* C_DEBUGEN == 1 -> Debugger Connected */ \
|
||||
if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) \
|
||||
{ \
|
||||
/* Generate breakpoint if debugger is connected */ \
|
||||
NRF_BREAKPOINT; \
|
||||
} \
|
||||
}while (0)
|
||||
#else
|
||||
#define NRF_BREAKPOINT_COND NRF_BREAKPOINT
|
||||
#endif // __CORTEX_M == 0x04
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#define PACKED(TYPE) __packed TYPE
|
||||
#define PACKED_STRUCT PACKED(struct)
|
||||
#elif defined ( __GNUC__ )
|
||||
#define PACKED __attribute__((packed))
|
||||
#define PACKED_STRUCT struct PACKED
|
||||
#elif defined (__ICCARM__)
|
||||
#define PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
|
||||
void app_util_critical_region_enter (uint8_t *p_nested);
|
||||
void app_util_critical_region_exit (uint8_t nested);
|
||||
|
||||
/**@brief Macro for entering a critical region.
|
||||
*
|
||||
* @note Due to implementation details, there must exist one and only one call to
|
||||
* CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
|
||||
* in the same scope.
|
||||
*/
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#define CRITICAL_REGION_ENTER() \
|
||||
{ \
|
||||
uint8_t __CR_NESTED = 0; \
|
||||
app_util_critical_region_enter(&__CR_NESTED);
|
||||
#else
|
||||
#define CRITICAL_REGION_ENTER() app_util_critical_region_enter(NULL)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for leaving a critical region.
|
||||
*
|
||||
* @note Due to implementation details, there must exist one and only one call to
|
||||
* CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
|
||||
* in the same scope.
|
||||
*/
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#define CRITICAL_REGION_EXIT() \
|
||||
app_util_critical_region_exit(__CR_NESTED); \
|
||||
}
|
||||
#else
|
||||
#define CRITICAL_REGION_EXIT() app_util_critical_region_exit(0)
|
||||
#endif
|
||||
|
||||
/* Workaround for Keil 4 */
|
||||
#ifndef IPSR_ISR_Msk
|
||||
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**@brief Macro to enable anonymous unions from a certain point in the code.
|
||||
*/
|
||||
#if defined(__CC_ARM)
|
||||
#define ANON_UNIONS_ENABLE _Pragma("push") \
|
||||
_Pragma("anon_unions")
|
||||
#elif defined(__ICCARM__)
|
||||
#define ANON_UNIONS_ENABLE _Pragma("language=extended")
|
||||
#else
|
||||
#define ANON_UNIONS_ENABLE
|
||||
// No action will be taken.
|
||||
// For GCC anonymous unions are enabled by default.
|
||||
#endif
|
||||
|
||||
/**@brief Macro to disable anonymous unions from a certain point in the code.
|
||||
* @note Call only after first calling @ref ANON_UNIONS_ENABLE.
|
||||
*/
|
||||
#if defined(__CC_ARM)
|
||||
#define ANON_UNIONS_DISABLE _Pragma("pop")
|
||||
#elif defined(__ICCARM__)
|
||||
#define ANON_UNIONS_DISABLE
|
||||
// for IAR leave anonymous unions enabled
|
||||
#else
|
||||
#define ANON_UNIONS_DISABLE
|
||||
// No action will be taken.
|
||||
// For GCC anonymous unions are enabled by default.
|
||||
#endif
|
||||
|
||||
/**@brief Macro for adding pragma directive only for GCC.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define GCC_PRAGMA(v) _Pragma(v)
|
||||
#else
|
||||
#define GCC_PRAGMA(v)
|
||||
#endif
|
||||
|
||||
/* Workaround for Keil 4 */
|
||||
#ifndef CONTROL_nPRIV_Msk
|
||||
#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
|
||||
#endif
|
||||
|
||||
/**@brief Function for finding the current interrupt level.
|
||||
*
|
||||
* @return Current interrupt level.
|
||||
* @retval APP_IRQ_PRIORITY_HIGH We are running in Application High interrupt level.
|
||||
* @retval APP_IRQ_PRIORITY_LOW We are running in Application Low interrupt level.
|
||||
* @retval APP_IRQ_PRIORITY_THREAD We are running in Thread Mode.
|
||||
*/
|
||||
uint8_t current_int_priority_get(void);
|
||||
|
||||
|
||||
/**@brief Function for finding out the current privilege level.
|
||||
*
|
||||
* @return Current privilege level.
|
||||
* @retval APP_LEVEL_UNPRIVILEGED We are running in unprivileged level.
|
||||
* @retval APP_LEVEL_PRIVILEGED We are running in privileged level.
|
||||
*/
|
||||
uint8_t privilege_level_get(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // APP_UTIL_PLATFORM_H__
|
||||
|
||||
/** @} */
|
211
lib/sdk/components/libraries/util/nordic_common.h
Normal file
211
lib/sdk/components/libraries/util/nordic_common.h
Normal file
@ -0,0 +1,211 @@
|
||||
/**
|
||||
* Copyright (c) 2008 - 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
|
||||
* @brief Common defines and macros for firmware developed by Nordic Semiconductor.
|
||||
*/
|
||||
|
||||
#ifndef NORDIC_COMMON_H__
|
||||
#define NORDIC_COMMON_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Check if selected module is enabled
|
||||
*
|
||||
* This is save function for driver enable checking.
|
||||
* Correct from Lint point of view (not using default of undefined value).
|
||||
*
|
||||
* Usage:
|
||||
* @code
|
||||
#if NRF_MODULE_ENABLED(UART)
|
||||
...
|
||||
#endif
|
||||
* @endcode
|
||||
*
|
||||
* @param module The module name.
|
||||
*
|
||||
* @retval 1 The macro <module>_ENABLE is defined and is non-zero.
|
||||
* @retval 0 The macro <module>_ENABLE is not defined or it equals zero.
|
||||
*
|
||||
* @note
|
||||
* This macro intentionally does not implement second expansion level.
|
||||
* The name of the module to be checked has to be given directly as a parameter.
|
||||
* And given parameter would be connected with @c _ENABLED postfix directly
|
||||
* without evaluating its value.
|
||||
*/
|
||||
//lint -emacro(491,NRF_MODULE_ENABLED) // Suppers warning 491 "non-standard use of 'defined' preprocessor operator"
|
||||
#define NRF_MODULE_ENABLED(module) \
|
||||
((defined(module ## _ENABLED) && (module ## _ENABLED)) ? 1 : 0)
|
||||
|
||||
/** The upper 8 bits of a 32 bit value */
|
||||
//lint -emacro(572,MSB_32) // Suppress warning 572 "Excessive shift value"
|
||||
#define MSB_32(a) (((a) & 0xFF000000) >> 24)
|
||||
/** The lower 8 bits (of a 32 bit value) */
|
||||
#define LSB_32(a) ((a) & 0x000000FF)
|
||||
|
||||
/** The upper 8 bits of a 16 bit value */
|
||||
//lint -emacro(572,MSB_16) // Suppress warning 572 "Excessive shift value"
|
||||
#define MSB_16(a) (((a) & 0xFF00) >> 8)
|
||||
/** The lower 8 bits (of a 16 bit value) */
|
||||
#define LSB_16(a) ((a) & 0x00FF)
|
||||
|
||||
/** Leaves the minimum of the two 32-bit arguments */
|
||||
/*lint -emacro(506, MIN) */ /* Suppress "Constant value Boolean */
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
/** Leaves the maximum of the two 32-bit arguments */
|
||||
/*lint -emacro(506, MAX) */ /* Suppress "Constant value Boolean */
|
||||
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||
|
||||
/**@brief Concatenates two parameters.
|
||||
*
|
||||
* It realizes two level expansion to make it sure that all the parameters
|
||||
* are actually expanded before gluing them together.
|
||||
*
|
||||
* @param p1 First parameter to concatenating
|
||||
* @param p2 Second parameter to concatenating
|
||||
*
|
||||
* @return Two parameters glued together.
|
||||
* They have to create correct C mnemonic in other case
|
||||
* preprocessor error would be generated.
|
||||
*
|
||||
* @sa CONCAT_3
|
||||
*/
|
||||
#define CONCAT_2(p1, p2) CONCAT_2_(p1, p2)
|
||||
/** Auxiliary macro used by @ref CONCAT_2 */
|
||||
#define CONCAT_2_(p1, p2) p1##p2
|
||||
|
||||
/**@brief Concatenates three parameters.
|
||||
*
|
||||
* It realizes two level expansion to make it sure that all the parameters
|
||||
* are actually expanded before gluing them together.
|
||||
*
|
||||
* @param p1 First parameter to concatenating
|
||||
* @param p2 Second parameter to concatenating
|
||||
* @param p3 Third parameter to concatenating
|
||||
*
|
||||
* @return Three parameters glued together.
|
||||
* They have to create correct C mnemonic in other case
|
||||
* preprocessor error would be generated.
|
||||
*
|
||||
* @sa CONCAT_2
|
||||
*/
|
||||
#define CONCAT_3(p1, p2, p3) CONCAT_3_(p1, p2, p3)
|
||||
/** Auxiliary macro used by @ref CONCAT_3 */
|
||||
#define CONCAT_3_(p1, p2, p3) p1##p2##p3
|
||||
|
||||
#define STRINGIFY_(val) #val
|
||||
/** Converts a macro argument into a character constant.
|
||||
*/
|
||||
#define STRINGIFY(val) STRINGIFY_(val)
|
||||
|
||||
/** Counts number of elements inside the array
|
||||
*/
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
/**@brief Set a bit in the uint32 word.
|
||||
*
|
||||
* @param[in] W Word whose bit is being set.
|
||||
* @param[in] B Bit number in the word to be set.
|
||||
*/
|
||||
#define SET_BIT(W, B) ((W) |= (uint32_t)(1U << (B)))
|
||||
|
||||
|
||||
/**@brief Clears a bit in the uint32 word.
|
||||
*
|
||||
* @param[in] W Word whose bit is to be cleared.
|
||||
* @param[in] B Bit number in the word to be cleared.
|
||||
*/
|
||||
#define CLR_BIT(W, B) ((W) &= (~(uint32_t)(1U << (B))))
|
||||
|
||||
|
||||
/**@brief Checks if a bit is set.
|
||||
*
|
||||
* @param[in] W Word whose bit is to be checked.
|
||||
* @param[in] B Bit number in the word to be checked.
|
||||
*
|
||||
* @retval 1 if bit is set.
|
||||
* @retval 0 if bit is not set.
|
||||
*/
|
||||
#define IS_SET(W, B) (((W) >> (B)) & 1)
|
||||
|
||||
#define BIT_0 0x01 /**< The value of bit 0 */
|
||||
#define BIT_1 0x02 /**< The value of bit 1 */
|
||||
#define BIT_2 0x04 /**< The value of bit 2 */
|
||||
#define BIT_3 0x08 /**< The value of bit 3 */
|
||||
#define BIT_4 0x10 /**< The value of bit 4 */
|
||||
#define BIT_5 0x20 /**< The value of bit 5 */
|
||||
#define BIT_6 0x40 /**< The value of bit 6 */
|
||||
#define BIT_7 0x80 /**< The value of bit 7 */
|
||||
#define BIT_8 0x0100 /**< The value of bit 8 */
|
||||
#define BIT_9 0x0200 /**< The value of bit 9 */
|
||||
#define BIT_10 0x0400 /**< The value of bit 10 */
|
||||
#define BIT_11 0x0800 /**< The value of bit 11 */
|
||||
#define BIT_12 0x1000 /**< The value of bit 12 */
|
||||
#define BIT_13 0x2000 /**< The value of bit 13 */
|
||||
#define BIT_14 0x4000 /**< The value of bit 14 */
|
||||
#define BIT_15 0x8000 /**< The value of bit 15 */
|
||||
#define BIT_16 0x00010000 /**< The value of bit 16 */
|
||||
#define BIT_17 0x00020000 /**< The value of bit 17 */
|
||||
#define BIT_18 0x00040000 /**< The value of bit 18 */
|
||||
#define BIT_19 0x00080000 /**< The value of bit 19 */
|
||||
#define BIT_20 0x00100000 /**< The value of bit 20 */
|
||||
#define BIT_21 0x00200000 /**< The value of bit 21 */
|
||||
#define BIT_22 0x00400000 /**< The value of bit 22 */
|
||||
#define BIT_23 0x00800000 /**< The value of bit 23 */
|
||||
#define BIT_24 0x01000000 /**< The value of bit 24 */
|
||||
#define BIT_25 0x02000000 /**< The value of bit 25 */
|
||||
#define BIT_26 0x04000000 /**< The value of bit 26 */
|
||||
#define BIT_27 0x08000000 /**< The value of bit 27 */
|
||||
#define BIT_28 0x10000000 /**< The value of bit 28 */
|
||||
#define BIT_29 0x20000000 /**< The value of bit 29 */
|
||||
#define BIT_30 0x40000000 /**< The value of bit 30 */
|
||||
#define BIT_31 0x80000000 /**< The value of bit 31 */
|
||||
|
||||
#define UNUSED_VARIABLE(X) ((void)(X))
|
||||
#define UNUSED_PARAMETER(X) UNUSED_VARIABLE(X)
|
||||
#define UNUSED_RETURN_VALUE(X) UNUSED_VARIABLE(X)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NORDIC_COMMON_H__
|
54
lib/sdk/components/libraries/util/nrf_assert.c
Normal file
54
lib/sdk/components/libraries/util/nrf_assert.c
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2006 - 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 "nrf_assert.h"
|
||||
#include "app_error.h"
|
||||
#include "nordic_common.h"
|
||||
|
||||
__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name)
|
||||
{
|
||||
assert_info_t assert_info =
|
||||
{
|
||||
.line_num = line_num,
|
||||
.p_file_name = file_name,
|
||||
};
|
||||
app_error_fault_handler(NRF_FAULT_ID_SDK_ASSERT, 0, (uint32_t)(&assert_info));
|
||||
|
||||
UNUSED_VARIABLE(assert_info);
|
||||
}
|
123
lib/sdk/components/libraries/util/nrf_assert.h
Normal file
123
lib/sdk/components/libraries/util/nrf_assert.h
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright (c) 2006 - 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
|
||||
* @brief Utilities for verifying program logic
|
||||
*/
|
||||
|
||||
#ifndef NRF_ASSERT_H_
|
||||
#define NRF_ASSERT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf.h"
|
||||
#include "app_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief Function for handling assertions.
|
||||
*
|
||||
*
|
||||
* @note
|
||||
* This function is called when an assertion has triggered.
|
||||
*
|
||||
* @note
|
||||
* This function is deprecated and will be removed in future releases.
|
||||
* Use app_error_fault_handler instead.
|
||||
*
|
||||
*
|
||||
* @post
|
||||
* All hardware is put into an idle non-emitting state (in particular the radio is highly
|
||||
* important to switch off since the radio might be in a state that makes it send
|
||||
* packets continiously while a typical final infinit ASSERT loop is executing).
|
||||
*
|
||||
*
|
||||
* @param line_num The line number where the assertion is called
|
||||
* @param file_name Pointer to the file name
|
||||
*/
|
||||
//lint -save -esym(14, assert_nrf_callback)
|
||||
void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name);
|
||||
//lint -restore
|
||||
|
||||
#if (defined(DEBUG_NRF) || defined(DEBUG_NRF_USER))
|
||||
#define NRF_ASSERT_PRESENT 1
|
||||
#else
|
||||
#define NRF_ASSERT_PRESENT 0
|
||||
#endif
|
||||
|
||||
//#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
|
||||
|
||||
/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */
|
||||
/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \
|
||||
|
||||
/** @brief Function for checking intended for production code.
|
||||
*
|
||||
* Check passes if "expr" evaluates to true. */
|
||||
|
||||
#ifdef _lint
|
||||
#define ASSERT(expr) \
|
||||
if (expr) \
|
||||
{ \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
while (1); \
|
||||
}
|
||||
#else //_lint
|
||||
#define ASSERT(expr) \
|
||||
if (NRF_ASSERT_PRESENT) \
|
||||
{ \
|
||||
if (expr) \
|
||||
{ \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_ASSERT_H_ */
|
147
lib/sdk/components/libraries/util/nrf_bitmask.h
Normal file
147
lib/sdk/components/libraries/util/nrf_bitmask.h
Normal file
@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Copyright (c) 2006 - 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.
|
||||
*
|
||||
*/
|
||||
#ifndef NRF_BITMASK_H
|
||||
#define NRF_BITMASK_H
|
||||
|
||||
#include "compiler_abstraction.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BITMASK_BYTE_GET(abs_bit) ((abs_bit)/8)
|
||||
#define BITMASK_RELBIT_GET(abs_bit) ((abs_bit) & 0x00000007)
|
||||
|
||||
/**
|
||||
* Function for checking if bit in the multi-byte bit mask is set.
|
||||
*
|
||||
* @param bit Bit index.
|
||||
* @param p_mask A pointer to mask with bit fields.
|
||||
*
|
||||
* @return 0 if bit is not set, positive value otherwise.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_bitmask_bit_is_set(uint32_t bit, void const * p_mask)
|
||||
{
|
||||
uint8_t const * p_mask8 = (uint8_t const *)p_mask;
|
||||
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
|
||||
bit = BITMASK_RELBIT_GET(bit);
|
||||
return (1 << bit) & p_mask8[byte_idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for setting a bit in the multi-byte bit mask.
|
||||
*
|
||||
* @param bit Bit index.
|
||||
* @param p_mask A pointer to mask with bit fields.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_bitmask_bit_set(uint32_t bit, void * p_mask)
|
||||
{
|
||||
uint8_t * p_mask8 = (uint8_t *)p_mask;
|
||||
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
|
||||
bit = BITMASK_RELBIT_GET(bit);
|
||||
p_mask8[byte_idx] |= (1 << bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for clearing a bit in the multi-byte bit mask.
|
||||
*
|
||||
* @param bit Bit index.
|
||||
* @param p_mask A pointer to mask with bit fields.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_bitmask_bit_clear(uint32_t bit, void * p_mask)
|
||||
{
|
||||
uint8_t * p_mask8 = (uint8_t *)p_mask;
|
||||
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
|
||||
bit = BITMASK_RELBIT_GET(bit);
|
||||
p_mask8[byte_idx] &= ~(1 << bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for performing bitwise OR operation on two multi-byte bit masks.
|
||||
*
|
||||
* @param p_mask1 A pointer to the first bit mask.
|
||||
* @param p_mask2 A pointer to the second bit mask.
|
||||
* @param p_mask_out A pointer to the output bit mask.
|
||||
* @param length Length of output mask in bytes.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_bitmask_masks_or(void const * p_mask1,
|
||||
void const * p_mask2,
|
||||
void * p_out_mask,
|
||||
uint32_t length)
|
||||
{
|
||||
uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
|
||||
uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
|
||||
uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
|
||||
uint32_t i;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
p_mask8_out[i] = p_mask8_1[i] | p_mask8_2[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for performing bitwise AND operation on two multi-byte bit masks.
|
||||
*
|
||||
* @param p_mask1 A pointer to the first bit mask.
|
||||
* @param p_mask2 A pointer to the second bit mask.
|
||||
* @param p_mask_out A pointer to the output bit mask.
|
||||
* @param length Length of output mask in bytes.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_bitmask_masks_and(void const * p_mask1,
|
||||
void const * p_mask2,
|
||||
void * p_out_mask,
|
||||
uint32_t length)
|
||||
{
|
||||
uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
|
||||
uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
|
||||
uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
|
||||
uint32_t i;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
p_mask8_out[i] = p_mask8_1[i] & p_mask8_2[i];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //NRF_BITMASK_H
|
77
lib/sdk/components/libraries/util/sdk_common.h
Normal file
77
lib/sdk/components/libraries/util/sdk_common.h
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/** @cond */
|
||||
/**@file
|
||||
*
|
||||
* @ingroup experimental_api
|
||||
* @defgroup sdk_common SDK Common Header
|
||||
* @brief All common headers needed for SDK examples will be included here so that application
|
||||
* developer does not have to include headers on him/herself.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef SDK_COMMON_H__
|
||||
#define SDK_COMMON_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "sdk_config.h"
|
||||
#include "nordic_common.h"
|
||||
#include "compiler_abstraction.h"
|
||||
#include "sdk_os.h"
|
||||
#include "sdk_errors.h"
|
||||
#include "app_util.h"
|
||||
#include "sdk_macros.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** @} */
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDK_COMMON_H__
|
||||
|
166
lib/sdk/components/libraries/util/sdk_errors.h
Normal file
166
lib/sdk/components/libraries/util/sdk_errors.h
Normal file
@ -0,0 +1,166 @@
|
||||
/**
|
||||
* 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 sdk_error SDK Error codes
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
* @{
|
||||
* @details Error codes are 32-bit unsigned integers with the most significant 16-bit reserved for
|
||||
* identifying the module where the error occurred while the least least significant LSB
|
||||
* are used to provide the cause or nature of error. Each module is assigned a 16-bit
|
||||
* unsigned integer. Which it will use to identify all errors that occurred in it. 16-bit
|
||||
* LSB range is with module id as the MSB in the 32-bit error code is reserved for the
|
||||
* module. As an example, if 0x8800 identifies a certain SDK module, all values from
|
||||
* 0x88000000 - 0x8800FFFF are reserved for this module.
|
||||
* It should be noted that common error reasons have been assigned values to make it
|
||||
* possible to decode error reason easily. As an example, lets module uninitialized has
|
||||
* been assigned an error code 0x000A0. Then, if application encounters an error code
|
||||
* 0xZZZZ00A0, it knows that it accessing a certain module without initializing it.
|
||||
* Apart from this, each module is allowed to define error codes that are not covered by
|
||||
* the common ones, however, these values are defined in a range that does not conflict
|
||||
* with common error values. For module, specific error however, it is possible that the
|
||||
* same error value is used by two different modules to indicated errors of very different
|
||||
* nature. If error is already defined by the NRF common error codes, these are reused.
|
||||
* A range is reserved for application as well, it can use this range for defining
|
||||
* application specific errors.
|
||||
*
|
||||
* @note Success code, NRF_SUCCESS, does not include any module identifier.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SDK_ERRORS_H__
|
||||
#define SDK_ERRORS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf_error.h"
|
||||
#include "sdk_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup sdk_err_base Base defined for SDK Modules
|
||||
* @{
|
||||
*/
|
||||
#define NRF_ERROR_SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */
|
||||
#define NRF_ERROR_SDK_COMMON_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x0080) /**< Base error value to be used for SDK error values. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup sdk_module_codes Codes reserved as identification for module where the error occurred.
|
||||
* @{
|
||||
*/
|
||||
#define NRF_ERROR_MEMORY_MANAGER_ERR_BASE (0x8100)
|
||||
#define NRF_ERROR_PERIPH_DRIVERS_ERR_BASE (0x8200)
|
||||
#define NRF_ERROR_GAZELLE_ERR_BASE (0x8300)
|
||||
#define NRF_ERROR_BLE_IPSP_ERR_BASE (0x8400)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup sdk_iot_errors Codes reserved as identification for IoT errors.
|
||||
* @{
|
||||
*/
|
||||
#define NRF_ERROR_IOT_ERR_BASE_START (0xA000)
|
||||
#define NRF_ERROR_IOT_ERR_BASE_STOP (0xAFFF)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup sdk_common_errors Codes reserved as identification for common errors.
|
||||
* @{
|
||||
*/
|
||||
#define NRF_ERROR_MODULE_NOT_INITIALZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0000)
|
||||
#define NRF_ERROR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0001)
|
||||
#define NRF_ERROR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0002)
|
||||
#define NRF_ERROR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0003)
|
||||
#define NRF_ERROR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0004)
|
||||
#define NRF_ERROR_MODULE_ALREADY_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0005)
|
||||
#define NRF_ERROR_STORAGE_FULL (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0006)
|
||||
#define NRF_ERROR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0010)
|
||||
#define NRF_ERROR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0011)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup drv_specific_errors Error / status codes specific to drivers.
|
||||
* @{
|
||||
*/
|
||||
#define NRF_ERROR_DRV_TWI_ERR_OVERRUN (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0000)
|
||||
#define NRF_ERROR_DRV_TWI_ERR_ANACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0001)
|
||||
#define NRF_ERROR_DRV_TWI_ERR_DNACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0002)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup ble_ipsp_errors IPSP codes
|
||||
* @brief Error and status codes specific to IPSP.
|
||||
* @{
|
||||
*/
|
||||
#define NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0000)
|
||||
#define NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0001)
|
||||
#define NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0002)
|
||||
#define NRF_ERROR_BLE_IPSP_PEER_REJECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0003)
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @brief API Result.
|
||||
*
|
||||
* @details Indicates success or failure of an API procedure. In case of failure, a comprehensive
|
||||
* error code indicating cause or reason for failure is provided.
|
||||
*
|
||||
* Though called an API result, it could used in Asynchronous notifications callback along
|
||||
* with asynchronous callback as event result. This mechanism is employed when an event
|
||||
* marks the end of procedure initiated using API. API result, in this case, will only be
|
||||
* an indicative of whether the procedure has been requested successfully.
|
||||
*/
|
||||
typedef uint32_t ret_code_t;
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDK_ERRORS_H__
|
191
lib/sdk/components/libraries/util/sdk_macros.h
Normal file
191
lib/sdk/components/libraries/util/sdk_macros.h
Normal file
@ -0,0 +1,191 @@
|
||||
/**
|
||||
* 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 sdk_common_macros SDK Common Header
|
||||
* @ingroup app_common
|
||||
* @brief Macros for parameter checking and similar tasks
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef SDK_MACROS_H__
|
||||
#define SDK_MACROS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
|
||||
* err_code if the statement is not true.
|
||||
*
|
||||
* @param[in] statement Statement to test.
|
||||
* @param[in] err_code Error value to return if test was invalid.
|
||||
*
|
||||
* @retval nothing, but will cause the exterior function to return @p err_code if @p statement
|
||||
* is false.
|
||||
*/
|
||||
#define VERIFY_TRUE(statement, err_code) \
|
||||
do \
|
||||
{ \
|
||||
if (!(statement)) \
|
||||
{ \
|
||||
return err_code; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
|
||||
* if the statement is not true.
|
||||
*
|
||||
* @param[in] statement Statement to test.
|
||||
*/
|
||||
#define VERIFY_TRUE_VOID(statement) VERIFY_TRUE((statement), )
|
||||
|
||||
|
||||
/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
|
||||
* err_code if the statement is not false.
|
||||
*
|
||||
* @param[in] statement Statement to test.
|
||||
* @param[in] err_code Error value to return if test was invalid.
|
||||
*
|
||||
* @retval nothing, but will cause the exterior function to return @p err_code if @p statement
|
||||
* is true.
|
||||
*/
|
||||
#define VERIFY_FALSE(statement, err_code) \
|
||||
do \
|
||||
{ \
|
||||
if ((statement)) \
|
||||
{ \
|
||||
return err_code; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
|
||||
* if the statement is not false.
|
||||
*
|
||||
* @param[in] statement Statement to test.
|
||||
*/
|
||||
#define VERIFY_FALSE_VOID(statement) VERIFY_FALSE((statement), )
|
||||
|
||||
|
||||
/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
|
||||
* function to return err_code if the err_code is not @ref NRF_SUCCESS.
|
||||
*
|
||||
* @param[in] err_code The error code to check.
|
||||
*/
|
||||
#ifdef DISABLE_PARAM_CHECK
|
||||
#define VERIFY_SUCCESS()
|
||||
#else
|
||||
#define VERIFY_SUCCESS(err_code) VERIFY_TRUE((err_code) == NRF_SUCCESS, (err_code))
|
||||
#endif /* DISABLE_PARAM_CHECK */
|
||||
|
||||
|
||||
/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
|
||||
* function to return if the err_code is not @ref NRF_SUCCESS.
|
||||
*
|
||||
* @param[in] err_code The error code to check.
|
||||
*/
|
||||
#ifdef DISABLE_PARAM_CHECK
|
||||
#define VERIFY_SUCCESS_VOID()
|
||||
#else
|
||||
#define VERIFY_SUCCESS_VOID(err_code) VERIFY_TRUE_VOID((err_code) == NRF_SUCCESS)
|
||||
#endif /* DISABLE_PARAM_CHECK */
|
||||
|
||||
|
||||
/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
|
||||
* return @ref NRF_ERROR_INVALID_STATE if not.
|
||||
*
|
||||
* @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
|
||||
* should be true if the module is initialized, false if not.
|
||||
*/
|
||||
#ifdef DISABLE_PARAM_CHECK
|
||||
#define VERIFY_MODULE_INITIALIZED()
|
||||
#else
|
||||
#define VERIFY_MODULE_INITIALIZED() VERIFY_TRUE((MODULE_INITIALIZED), NRF_ERROR_INVALID_STATE)
|
||||
#endif /* DISABLE_PARAM_CHECK */
|
||||
|
||||
|
||||
/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
|
||||
* return if not.
|
||||
*
|
||||
* @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
|
||||
* should be true if the module is initialized, false if not.
|
||||
*/
|
||||
#ifdef DISABLE_PARAM_CHECK
|
||||
#define VERIFY_MODULE_INITIALIZED_VOID()
|
||||
#else
|
||||
#define VERIFY_MODULE_INITIALIZED_VOID() VERIFY_TRUE_VOID((MODULE_INITIALIZED))
|
||||
#endif /* DISABLE_PARAM_CHECK */
|
||||
|
||||
|
||||
/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
|
||||
* return if not.
|
||||
*
|
||||
* @param[in] param The variable to check if is NULL.
|
||||
*/
|
||||
#ifdef DISABLE_PARAM_CHECK
|
||||
#define VERIFY_PARAM_NOT_NULL()
|
||||
#else
|
||||
#define VERIFY_PARAM_NOT_NULL(param) VERIFY_FALSE(((param) == NULL), NRF_ERROR_NULL)
|
||||
#endif /* DISABLE_PARAM_CHECK */
|
||||
|
||||
|
||||
/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
|
||||
* return if not.
|
||||
*
|
||||
* @param[in] param The variable to check if is NULL.
|
||||
*/
|
||||
#ifdef DISABLE_PARAM_CHECK
|
||||
#define VERIFY_PARAM_NOT_NULL_VOID()
|
||||
#else
|
||||
#define VERIFY_PARAM_NOT_NULL_VOID(param) VERIFY_FALSE_VOID(((param) == NULL))
|
||||
#endif /* DISABLE_PARAM_CHECK */
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDK_MACROS_H__
|
||||
|
220
lib/sdk/components/libraries/util/sdk_mapped_flags.c
Normal file
220
lib/sdk/components/libraries/util/sdk_mapped_flags.c
Normal file
@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 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_mapped_flags.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "compiler_abstraction.h"
|
||||
|
||||
|
||||
// Test whether the flag collection type is large enough to hold all the flags. If this fails,
|
||||
// reduce SDK_MAPPED_FLAGS_N_KEYS or increase the size of sdk_mapped_flags_t.
|
||||
STATIC_ASSERT((sizeof(sdk_mapped_flags_t) * SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE) >= SDK_MAPPED_FLAGS_N_KEYS);
|
||||
|
||||
|
||||
/**@brief Function for setting the state of a flag to true.
|
||||
*
|
||||
* @note This function does not check whether the index is valid.
|
||||
*
|
||||
* @param[in] p_flags The collection of flags to modify.
|
||||
* @param[in] index The index of the flag to modify.
|
||||
*/
|
||||
static __INLINE void sdk_mapped_flags_set_by_index(sdk_mapped_flags_t * p_flags, uint16_t index)
|
||||
{
|
||||
*p_flags |= (1U << index);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for setting the state of a flag to false.
|
||||
*
|
||||
* @note This function does not check whether the index is valid.
|
||||
*
|
||||
* @param[in] p_flags The collection of flags to modify.
|
||||
* @param[in] index The index of the flag to modify.
|
||||
*/
|
||||
static __INLINE void sdk_mapped_flags_clear_by_index(sdk_mapped_flags_t * p_flags, uint16_t index)
|
||||
{
|
||||
*p_flags &= ~(1U << index);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for getting the state of a flag.
|
||||
*
|
||||
* @note This function does not check whether the index is valid.
|
||||
*
|
||||
* @param[in] p_flags The collection of flags to read.
|
||||
* @param[in] index The index of the flag to get.
|
||||
*/
|
||||
static __INLINE bool sdk_mapped_flags_get_by_index(sdk_mapped_flags_t flags, uint16_t index)
|
||||
{
|
||||
return ((flags & (1 << index)) != 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags)
|
||||
{
|
||||
for (uint16_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
|
||||
{
|
||||
if (sdk_mapped_flags_get_by_index(flags, i))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return SDK_MAPPED_FLAGS_INVALID_INDEX;
|
||||
}
|
||||
|
||||
|
||||
void sdk_mapped_flags_update_by_key(uint16_t * p_keys,
|
||||
sdk_mapped_flags_t * p_flags,
|
||||
uint16_t key,
|
||||
bool value)
|
||||
{
|
||||
sdk_mapped_flags_bulk_update_by_key(p_keys, p_flags, 1, key, value);
|
||||
}
|
||||
|
||||
|
||||
void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys,
|
||||
sdk_mapped_flags_t * p_flags,
|
||||
uint32_t n_flag_collections,
|
||||
uint16_t key,
|
||||
bool value)
|
||||
{
|
||||
if ((p_keys != NULL) && (p_flags != NULL) && (n_flag_collections > 0))
|
||||
{
|
||||
for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
|
||||
{
|
||||
if (p_keys[i] == key)
|
||||
{
|
||||
for (uint32_t j = 0; j < n_flag_collections; j++)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
sdk_mapped_flags_set_by_index(&p_flags[j], i);
|
||||
}
|
||||
else
|
||||
{
|
||||
sdk_mapped_flags_clear_by_index(&p_flags[j], i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool sdk_mapped_flags_get_by_key_w_idx(uint16_t * p_keys,
|
||||
sdk_mapped_flags_t flags,
|
||||
uint16_t key,
|
||||
uint8_t * p_index)
|
||||
{
|
||||
if (p_keys != NULL)
|
||||
{
|
||||
for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
|
||||
{
|
||||
if (p_keys[i] == key)
|
||||
{
|
||||
if (p_index != NULL)
|
||||
{
|
||||
*p_index = i;
|
||||
}
|
||||
return sdk_mapped_flags_get_by_index(flags, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p_index != NULL)
|
||||
{
|
||||
*p_index = SDK_MAPPED_FLAGS_N_KEYS;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key)
|
||||
{
|
||||
if (p_keys != NULL)
|
||||
{
|
||||
for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
|
||||
{
|
||||
if (p_keys[i] == key)
|
||||
{
|
||||
return sdk_mapped_flags_get_by_index(flags, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys,
|
||||
sdk_mapped_flags_t flags)
|
||||
{
|
||||
sdk_mapped_flags_key_list_t key_list;
|
||||
key_list.len = 0;
|
||||
|
||||
if (p_keys != NULL)
|
||||
{
|
||||
for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
|
||||
{
|
||||
if (sdk_mapped_flags_get_by_index(flags, i))
|
||||
{
|
||||
key_list.flag_keys[key_list.len++] = p_keys[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return key_list;
|
||||
}
|
||||
|
||||
|
||||
uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags)
|
||||
{
|
||||
uint32_t n_flags_set = 0;
|
||||
|
||||
for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
|
||||
{
|
||||
if (sdk_mapped_flags_get_by_index(flags, i))
|
||||
{
|
||||
n_flags_set += 1;
|
||||
}
|
||||
}
|
||||
return n_flags_set;
|
||||
}
|
199
lib/sdk/components/libraries/util/sdk_mapped_flags.h
Normal file
199
lib/sdk/components/libraries/util/sdk_mapped_flags.h
Normal file
@ -0,0 +1,199 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 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.
|
||||
*
|
||||
*/
|
||||
#ifndef SDK_MAPPED_FLAGS_H__
|
||||
#define SDK_MAPPED_FLAGS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "app_util.h"
|
||||
#include "compiler_abstraction.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @defgroup sdk_mapped_flags Mapped flags
|
||||
* @ingroup app_common
|
||||
* @{
|
||||
* @brief Module for writing and reading flags that are associated
|
||||
* with keys.
|
||||
*
|
||||
* @details The flags are represented as bits in a bitmap called a <i>flag collection</i>. The keys
|
||||
* are uint16_t. Each flag collection contains all flags of the same type, one flag for
|
||||
* each key.
|
||||
*
|
||||
* The mapped flags module does not keep the flag states, nor the list of keys. These are
|
||||
* provided in the API calls. A key's index in the key list determines which bit in the
|
||||
* flag collection is associated with it. This module does not ever edit the key list, and
|
||||
* does not edit flags except in function calls that take the flag collection as a pointer.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SDK_MAPPED_FLAGS_N_KEYS 32 /**< The number of keys to keep flags for. This is also the number of flags in a flag collection. If changing this value, you might also need change the width of the sdk_mapped_flags_t type. */
|
||||
#define SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE 8 /**< The number of flags that fit in one byte. */
|
||||
#define SDK_MAPPED_FLAGS_INVALID_INDEX 0xFFFF /**< A flag index guaranteed to be invalid. */
|
||||
|
||||
typedef uint32_t sdk_mapped_flags_t; /**< The bitmap to hold flags. Each flag is one bit, and each bit represents the flag state associated with one key. */
|
||||
|
||||
|
||||
/**@brief Type used to present a subset of the registered keys.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t len; /**< The length of the list. */
|
||||
uint16_t flag_keys[SDK_MAPPED_FLAGS_N_KEYS]; /**< The list of keys. */
|
||||
} sdk_mapped_flags_key_list_t;
|
||||
|
||||
|
||||
/**@brief Function for getting the first index at which the flag is true in the provided
|
||||
* collection.
|
||||
*
|
||||
* @param[in] flags The flag collection to search for a flag set to true.
|
||||
*
|
||||
* @return The first index that has its flag set to true. If none were found, the
|
||||
* function returns @ref SDK_MAPPED_FLAGS_INVALID_INDEX.
|
||||
*/
|
||||
uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags);
|
||||
|
||||
|
||||
/**@brief Function for updating the state of a flag.
|
||||
*
|
||||
* @param[in] p_keys The list of associated keys (assumed to have a length of
|
||||
* @ref SDK_MAPPED_FLAGS_N_KEYS).
|
||||
* @param[out] p_flags The flag collection to modify.
|
||||
* @param[in] key The key to modify the flag of.
|
||||
* @param[in] value The state to set the flag to.
|
||||
*/
|
||||
void sdk_mapped_flags_update_by_key(uint16_t * p_keys,
|
||||
sdk_mapped_flags_t * p_flags,
|
||||
uint16_t key,
|
||||
bool value);
|
||||
|
||||
|
||||
/**@brief Function for updating the state of the same flag in multiple flag collections.
|
||||
*
|
||||
* @details The key and value are the same for all flag collections in the p_flags array.
|
||||
*
|
||||
* @param[in] p_keys The list of associated keys (assumed to have a length of
|
||||
* @ref SDK_MAPPED_FLAGS_N_KEYS).
|
||||
* @param[out] p_flags The flag collections to modify.
|
||||
* @param[out] n_flag_collections The number of flag collections in p_flags.
|
||||
* @param[in] key The key to modify the flag of.
|
||||
* @param[in] value The state to set the flag to.
|
||||
*/
|
||||
void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys,
|
||||
sdk_mapped_flags_t * p_flags,
|
||||
uint32_t n_flag_collections,
|
||||
uint16_t key,
|
||||
bool value);
|
||||
|
||||
|
||||
/**@brief Function for getting the state of a specific flag.
|
||||
*
|
||||
* @param[in] p_keys The list of associated keys (assumed to have a length of
|
||||
* @ref SDK_MAPPED_FLAGS_N_KEYS).
|
||||
* @param[in] flags The flag collection to read from.
|
||||
* @param[in] key The key to get the flag for.
|
||||
*
|
||||
* @return The state of the flag.
|
||||
*/
|
||||
bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key);
|
||||
|
||||
|
||||
/**@brief Function for getting the state of a specific flag.
|
||||
*
|
||||
* @param[in] p_keys The list of associated keys (assumed to have a length of
|
||||
* @ref SDK_MAPPED_FLAGS_N_KEYS).
|
||||
* @param[in] flags The flag collection from which to read.
|
||||
* @param[in] key The key for which to get the flag.
|
||||
* @param[out] p_index If not NULL, the index of the key.
|
||||
*
|
||||
* @return The state of the flag.
|
||||
*/
|
||||
bool sdk_mapped_flags_get_by_key_w_idx(uint16_t * p_keys,
|
||||
sdk_mapped_flags_t flags,
|
||||
uint16_t key,
|
||||
uint8_t * p_index);
|
||||
|
||||
|
||||
/**@brief Function for getting a list of all keys that have a specific flag set to true.
|
||||
*
|
||||
* @param[in] p_keys The list of associated keys (assumed to have a length of
|
||||
* @ref SDK_MAPPED_FLAGS_N_KEYS).
|
||||
* @param[in] flags The flag collection to search.
|
||||
*
|
||||
* @return The list of keys.
|
||||
*/
|
||||
sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys,
|
||||
sdk_mapped_flags_t flags);
|
||||
|
||||
|
||||
/**@brief Function for getting the number of keys that have a specific flag set to true.
|
||||
*
|
||||
* @param[in] flags The flag collection to search.
|
||||
*
|
||||
* @return The number of keys.
|
||||
*/
|
||||
uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags);
|
||||
|
||||
|
||||
/**@brief Function for querying whether any flags in the collection are set.
|
||||
*
|
||||
* @param[in] flags The flag collection to query.
|
||||
*
|
||||
* @retval true If one or more flags are set to true.
|
||||
* @retval false Otherwise.
|
||||
*/
|
||||
static __INLINE bool sdk_mapped_flags_any_set(sdk_mapped_flags_t flags)
|
||||
{
|
||||
return (flags != 0);
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SDK_MAPPED_FLAGS_H__ */
|
76
lib/sdk/components/libraries/util/sdk_os.h
Normal file
76
lib/sdk/components/libraries/util/sdk_os.h
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/** @cond */
|
||||
/**@file
|
||||
*
|
||||
* @defgroup sdk_os SDK OS Abstraction
|
||||
* @ingroup experimental_api
|
||||
* @details In order to made SDK modules independent of use of an embedded OS, and permit
|
||||
* application with varied task architecture, SDK abstracts the OS specific
|
||||
* elements here in order to make all other modules agnostic to the OS or task
|
||||
* architecture.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef SDK_OS_H__
|
||||
#define SDK_OS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SDK_MUTEX_DEFINE(X)
|
||||
#define SDK_MUTEX_INIT(X)
|
||||
#define SDK_MUTEX_LOCK(X)
|
||||
#define SDK_MUTEX_UNLOCK(X)
|
||||
|
||||
/**
|
||||
* @defgroup os_data_type Data types.
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDK_OS_H__
|
||||
|
86
lib/sdk/components/libraries/util/sdk_resources.h
Normal file
86
lib/sdk/components/libraries/util/sdk_resources.h
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 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
|
||||
* @brief Definition file for resource usage by SoftDevice, ESB and Gazell.
|
||||
*/
|
||||
|
||||
#ifndef APP_RESOURCES_H__
|
||||
#define APP_RESOURCES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#include "nrf_sd_def.h"
|
||||
#else
|
||||
#define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */
|
||||
#define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */
|
||||
#define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */
|
||||
#define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */
|
||||
#define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */
|
||||
#endif
|
||||
|
||||
#ifdef GAZELL_PRESENT
|
||||
#include "nrf_gzll_resources.h"
|
||||
#else
|
||||
#define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */
|
||||
#define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */
|
||||
#define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */
|
||||
#endif
|
||||
|
||||
#ifdef ESB_PRESENT
|
||||
#include "nrf_esb_resources.h"
|
||||
#else
|
||||
#define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */
|
||||
#define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */
|
||||
#define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */
|
||||
#endif
|
||||
|
||||
#define NRF_PPI_CHANNELS_USED (SD_PPI_CHANNELS_USED | GZLL_PPI_CHANNELS_USED | ESB_PPI_CHANNELS_USED)
|
||||
#define NRF_PPI_GROUPS_USED (SD_PPI_GROUPS_USED)
|
||||
#define NRF_SWI_USED (SD_SWI_USED | GZLL_SWI_USED | ESB_SWI_USED)
|
||||
#define NRF_TIMERS_USED (SD_TIMERS_USED | GZLL_TIMERS_USED | ESB_TIMERS_USED)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // APP_RESOURCES_H__
|
Reference in New Issue
Block a user