This commit is contained in:
moyuhai
2026-06-11 13:04:09 +08:00
commit 966451d245
2022 changed files with 513671 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
/**
****************************************************************************************
*
* @file co_bt.h
*
* @brief This file contains the common Bluetooth defines, enumerations and structures
* definitions for use by all modules in RW stack.
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef CO_BT_H_
#define CO_BT_H_
/**
****************************************************************************************
* @addtogroup COMMON Common SW Block
* @ingroup ROOT
* @brief The Common RW SW Block.
*
* The COMMON is the block with Bluetooth definitions and structures shared
* to all the protocol stack blocks. This also contain software wide error code
* definitions, mathematical functions, help functions, list and buffer definitions.
*
* @{
****************************************************************************************
*/
/**
****************************************************************************************
* @addtogroup CO_BT Common Bluetooth defines
* @ingroup COMMON
* @brief Common Bluetooth definitions and structures.
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdbool.h> // standard boolean definitions
#include <stddef.h> // standard definitions
#include <stdint.h> // standard integer definitions
/*
* DEFINES
****************************************************************************************
*/
#include "co_bt_defines.h" // Bluetooth defines
#include "co_lmp.h" // Bluetooth LMP definitions
#include "co_hci.h" // Bluetooth HCI definitions
#include "co_error.h" // Bluetooth error codes definitions
/// @} CO_BT
#endif // CO_BT_H_
File diff suppressed because it is too large Load Diff
+643
View File
@@ -0,0 +1,643 @@
/**
****************************************************************************************
*
* @file co_buf.h
*
* @brief The Common Time module provides buffer used for manipulation of data for network
* protocol that uses encapsulation of header or trailing information.
* A buffer is a contiguous memory section used to store message information including
* several protocol layers.
* Since a unique buffer can be used by multiple layers, a mechanism monitors the
* buffer life cycle. Finally, if data usage information are kept within the buffer,
* it speeds up software to retrieve the execution context.
*
*
* Copyright (C) RivieraWaves 2009-2019
*
****************************************************************************************
*/
#ifndef _CO_BUF_H_
#define _CO_BUF_H_
/**
****************************************************************************************
* @defgroup CO_BUF Utilities
* @ingroup COMMON
* @brief Time utilities
*
* This module contains the Common time utilities functions and macros.
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdint.h> // standard definitions
#include <stddef.h> // standard definitions
#include "arch.h" // Arch defines
#include "co_list.h" // List manipulation
#include "co_utils.h" // Bit Field manipulation
/*
* MACRO DEFINITIONS
****************************************************************************************
*/
/*
* ENUMERATIONS DEFINITIONS
****************************************************************************************
*/
/// size of meta-data variables 32 bytes
#define CO_BUF_META_DATA_SIZE (32 >> 2)
/// Buffer Error status codes
enum co_buf_err
{
/// No Error
CO_BUF_ERR_NO_ERROR = 0x00,
/// Invalid parameter(s)
CO_BUF_ERR_INVALID_PARAM = 0x01,
/// Not enough resources
CO_BUF_ERR_INSUFFICIENT_RESOURCE = 0x02,
/// Resource is busy, operation cannot be performed
CO_BUF_ERR_RESOURCE_BUSY = 0x03,
};
/// Buffer meta-data bit field
enum co_buf_metadata_bf
{
/// Size of meta-data data frozen. This size has a step of 4 bytes
CO_BUF_METADATA_FROZEN_SIZE_LSB = 0,
CO_BUF_METADATA_FROZEN_SIZE_MASK = 0x0F,
/// If equals 1, a callback is executed before freeing the buffer.
CO_BUF_METADATA_FREE_CB_POS = 4,
CO_BUF_METADATA_FREE_CB_BIT = 0x10,
};
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Buffer structure
typedef struct co_buf
{
/// List header for chaining
co_list_hdr_t hdr;
/// Length of the data part
uint16_t data_len;
/// Prefix length available
uint16_t head_len;
/// Suffix length available
uint16_t tail_len;
/// Pool identifier (@see enum co_buf_pool_id)
uint8_t pool_id;
/// Acquisition counter
uint8_t acq_cnt;
/// Meta-data variable that can be used for multiple purposes
/// meta-data is always 32 bits aligned
uint32_t metadata[CO_BUF_META_DATA_SIZE];
/// Pattern used to verify that meta-data didnt overflow
uint8_t pattern;
/// Meta-data bit field (@see enum co_buf_metadata_bf)
uint8_t metadata_bf;
/// Padding
uint16_t padding;
/// Variable buffer array that contains header, data and tail payload
/// Length is buf_len = (head_len + data_len + tail_len)
uint8_t buf[__ARRAY_EMPTY];
} co_buf_t;
/**
****************************************************************************************
* @brief This function is called when all software modules has release the buffer.
*
* @param[in] p_env Pointer to environment that will be used as callback parameter.
****************************************************************************************
*/
typedef void (*co_buf_free_cb)(co_buf_t* p_buf, void* p_env);
/*
* CONSTANT DECLARATIONS
****************************************************************************************
*/
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Allocate a buffer and specify initial length of head, data and tail parts.
* When doing a buffer allocation, acquisition counter is equals to 1.
*
* If total length is lower than @see CO_BUF_SMALL_SIZE and small buffer pool is not empty:
* A buffer will be picked from small buffer pool.
* else if total length is lower than @see CO_BUF_BIG_SIZE and big buffer pool is not empty:
* A buffer will be picked from big buffer pool.
* else:
* the buffer will be dynamically allocated.
*
* @param[out] pp_buf Pointer to a variable that will contain the address of the allocated buffer.
* @param[in] head_len Initial Head Length.
* @param[in] data_len Initial Data Length.
* @param[in] tail_len Initial Tail Length.
*
* @return CO_BUF_ERR_NO_ERROR if buffer can be allocated.
* CO_BUF_ERR_INSUFFICIENT_RESOURCE if no more buffers are available.
****************************************************************************************
*/
uint8_t co_buf_alloc(co_buf_t** pp_buf, uint16_t head_len, uint16_t data_len, uint16_t tail_len);
/**
****************************************************************************************
* @brief Prepare a buffer and specify initial length of head, data and tail parts.
*
* Buffer pointer provided must have a total length greater or equals to head_len + data_len + tail_len
* When doing a buffer allocation, acquisition counter is equals to 1.
* Buffer isnt free by @see co_buf_release function when acquisition counter is equals to 0.
*
* @param[out] p_buf Pointer to buffer to prepare.
* @param[in] head_len Initial Head Length.
* @param[in] data_len Initial Data Length.
* @param[in] tail_len Initial Tail Length.
*
* @return CO_BUF_ERR_NO_ERROR if buffer can be allocated.
****************************************************************************************
*/
// uint8_t co_buf_prepare(co_buf_t* p_buf, uint16_t head_len, uint16_t data_len, uint16_t tail_len);
/**
****************************************************************************************
* @brief Function used to increment value of acquire counter of a buffer during processing
* of buffer content.
*
* @param[in] p_buf Pointer to acquired buffer
*
* @return CO_BUF_ERR_NO_ERROR if operation succeed
****************************************************************************************
*/
uint8_t co_buf_acquire(co_buf_t *p_buf);
/**
****************************************************************************************
* @brief Function used to release previously acquired buffer. The acquire counter for
* this buffer is decremented. If the acquire counter value becomes zero,
* the buffer is freed as no more entity is using the buffer anymore.
*
* if acquire counter becomes zero
* if a free callback has been configured using @see co_buf_cb_set:
* call the free callback
*
* if buffer comes from a buffer pool:
* buffer is pushed to the corresponding pool, and available for another
* software module
*
* else if buffer comes from dynamic memory:
* corresponding memory is free
*
* else if a buffer has been initialized with @see co_buf_prepare:
* nothing is done
*
* @note A software module shall not use a buffer after releasing it.
*
* @param[in] p_buf Pointer to acquired buffer.
*
* @return CO_BUF_ERR_NO_ERROR if buffer has been released.
* CO_BUF_ERR_INVALID_PARAM if buffer was free.
****************************************************************************************
*/
uint8_t co_buf_release(co_buf_t *p_buf);
/**
****************************************************************************************
* @brief Retrieve buffer data pointer.
*
* @param[in] p_buf Pointer to buffer
*
* @return Pointer to first byte of data field ; NULL if an error occurs
****************************************************************************************
*/
__INLINE uint8_t* co_buf_data(co_buf_t *p_buf)
{
uint8_t* p_ret = NULL;
if(p_buf)
{
p_ret = &(p_buf->buf[p_buf->head_len]);
}
return (p_ret);
}
/**
****************************************************************************************
* @brief Retrieve buffer data length.
*
* @param[in] p_buf Pointer to buffer
*
* @return Buffer data field size. 0 if an error occurs.
****************************************************************************************
*/
__INLINE uint16_t co_buf_data_len(const co_buf_t *p_buf)
{
uint16_t ret = 0;
if(p_buf)
{
ret = p_buf->data_len;
}
return (ret);
}
/**
****************************************************************************************
* @brief Retrieve buffer available prefix length.
*
* @param[in] p_buf Pointer to buffer
*
* @return Buffer data prefix size available. 0 if an error occurs.
****************************************************************************************
*/
__INLINE uint16_t co_buf_head_len(const co_buf_t *p_buf)
{
uint16_t ret = 0;
if(p_buf)
{
ret = p_buf->head_len;
}
return (ret);
}
/**
****************************************************************************************
* @brief Memory Size of the buffer
*
* @param[in] p_buf Pointer to buffer
*
* @return Memory size of the buffer
****************************************************************************************
*/
uint16_t co_buf_size(const co_buf_t *p_buf);
/**
****************************************************************************************
* @brief Retrieve buffer head pointer.
*
* @param[in] p_buf Pointer to buffer
*
* @return Pointer to first byte of tail field ; NULL if an error occurs
****************************************************************************************
*/
__INLINE uint8_t* co_buf_head(co_buf_t *p_buf)
{
uint8_t* p_ret = NULL;
if(p_buf)
{
p_ret = &(p_buf->buf[0]);
}
return (p_ret);
}
/**
****************************************************************************************
* @brief Prefix the data with a given header length, it is mandatory that data reserved
* length is less or equals to header length.
* Header length is reduced according to number of byte reserved.
*
* @param[in] p_buf Pointer to buffer
* @param[in] length Length of prefix data to reserve.
*
* @return CO_BUF_ERR_NO_ERROR if needed length has been reserved.
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than current length of head part.
****************************************************************************************
*/
uint8_t co_buf_head_reserve(co_buf_t *p_buf, uint16_t length);
/**
****************************************************************************************
* @brief Remove a data prefix of a specific length header length, it is mandatory that
* data released length is less or equals to data length.
* Header length is increased according to number of byte released.
*
* @param[in] p_buf Pointer to buffer
* @param[in] length Length of prefix data to release.
*
* @return CO_BUF_ERR_NO_ERROR if needed length has been released.
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than current length of data part.
****************************************************************************************
*/
uint8_t co_buf_head_release(co_buf_t *p_buf, uint16_t length);
/**
****************************************************************************************
* @brief Retrieve buffer tail pointer.
*
* @param[in] p_buf Pointer to buffer
*
* @return Pointer to first byte of tail field ; NULL if an error occurs
****************************************************************************************
*/
__INLINE uint8_t* co_buf_tail(co_buf_t *p_buf)
{
uint8_t* p_ret = NULL;
if(p_buf)
{
p_ret = &(p_buf->buf[p_buf->head_len + p_buf->data_len]);
}
return (p_ret);
}
/**
****************************************************************************************
* @brief Retrieve buffer available suffix length.
*
* @param[in] p_buf Pointer to buffer
*
* @return Buffer data suffix size available. 0 if an error occurs.
****************************************************************************************
*/
__INLINE uint16_t co_buf_tail_len(const co_buf_t *p_buf)
{
uint16_t ret = 0;
if(p_buf)
{
ret = p_buf->tail_len;
}
return (ret);
}
/**
****************************************************************************************
* @brief Prefix the data with a given tail length, it is mandatory that data reserved
* length is less or equals to header length.
* Tail length is reduced according to number of byte reserved.
*
* @param[in] p_buf Pointer to buffer
* @param[in] length Length of suffix data to reserve.
*
* @return CO_BUF_ERR_NO_ERROR if needed length has been reserved.
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than current length of tail part.
****************************************************************************************
*/
uint8_t co_buf_tail_reserve(co_buf_t *p_buf, uint16_t length);
/**
****************************************************************************************
* @brief Remove a data suffix of a specific length header length, it is mandatory that
* data released length is less or equals to data length.
* Tail length is increased according to number of byte released.
*
* @param[in] p_buf Pointer to buffer
* @param[in] length Length of suffix data to release.
*
* @return CO_BUF_ERR_NO_ERROR if needed length has been released.
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than current length of data part.
****************************************************************************************
*/
uint8_t co_buf_tail_release(co_buf_t *p_buf, uint16_t length);
/**
****************************************************************************************
* @brief Retrieve pointer to buffer meta-data. This pointer is 32-bit aligned, and
* corresponds to buffer meta-data start pointer plus blocked meta-data length
*
* @param[in] p_buf Pointer to buffer
*
* @return Pointer to the available meta-data pointer ;NULL if an error occurs
****************************************************************************************
*/
__INLINE uint8_t* co_buf_metadata(co_buf_t *p_buf)
{
uint8_t* p_ret = NULL;
if((p_buf) && (GETF(p_buf->metadata_bf, CO_BUF_METADATA_FROZEN_SIZE) < CO_BUF_META_DATA_SIZE))
{
p_ret = (uint8_t*) &(p_buf->metadata[GETF(p_buf->metadata_bf, CO_BUF_METADATA_FROZEN_SIZE)]);
}
return (p_ret);
}
/**
****************************************************************************************
* @brief Freeze some meta-data into the buffer, this update the meta-data
* pointer given by @see co_buf_metadata function .
* Frozen meta-data should not be updated. A software module that has frozen some
* meta-data must unblock it before using it or before releasing buffer.
*
* Length provided is aligned to 4 bytes in order to ensure that meta-data pointer
* is always 32-bits aligned. Length parameter cannot exceed remaining meta-data
* length.
*
* @param[in] p_buf Pointer to buffer
* @param[in] length Number of byte in buffer meta-data to freeze.
*
* @return CO_BUF_ERR_NO_ERROR if needed length has been frozen.
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than remaining meta-data size
****************************************************************************************
*/
uint8_t co_buf_metadata_freeze(co_buf_t *p_buf, uint8_t length);
/**
****************************************************************************************
* @brief Unfreeze some meta-data into the buffer, this update the meta-data
* pointer given by @see co_buf_metadata function.
* Length provided is aligned to 4 bytes in order to ensure that meta-data
* pointer is always 32-bits aligned.
*
* Length parameter cannot exceed meta-data frozen length
*
* @param[in] p_buf Pointer to buffer
* @param[in] length Number of byte in buffer meta-data to un-freeze.
*
* @return CO_BUF_ERR_NO_ERROR if needed length has been frozen.
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than frozen meta-data size
****************************************************************************************
*/
// uint8_t co_buf_metadata_unfreeze(co_buf_t *p_buf, uint8_t length);
/**
****************************************************************************************
* @brief Retrieve number of bytes in meta-data field that can be used by software layer
*
* @param[in] p_buf Pointer to buffer
*
* @return Number of byte in buffer meta-data remains 0 if an error occurs
****************************************************************************************
*/
__INLINE uint8_t co_buf_metadata_len(const co_buf_t *p_buf)
{
uint8_t ret = 0;
if(p_buf)
{
ret = (CO_BUF_META_DATA_SIZE - GETF(p_buf->metadata_bf, CO_BUF_METADATA_FROZEN_SIZE)) << 2;
}
return (ret);
}
/**
****************************************************************************************
* @brief Allocate a new buffer, specify initial length of head and tail parts, plus copy
* data of input buffer.
*
* @see m_buf_alloc function is used to allocate output buffer.
*
* @note meta-data isn't copied
*
* @param[in] p_buf_in Pointer to input buffer.
* @param[in] p_buf_out Pointer to output buffer.
* @param[in] length Length of data to copy
*
* @return CO_BUF_ERR_NO_ERROR if buffer can be allocated.
* CO_BUF_ERR_INSUFFICIENT_RESOURCE if no more buffers are available.
****************************************************************************************
*/
uint8_t co_buf_duplicate(const co_buf_t *p_buf_in, co_buf_t **pp_buf_out, uint16_t head_len, uint16_t tail_len);
/**
****************************************************************************************
* @brief Copy content of a buffer to another buffer.
*
* @param[in] p_buf_in Pointer to input buffer.
* @param[in] p_buf_out Pointer to output buffer.
* @param[in] length Length of data to copy
* @param[in] copy_meta_size Indicate size of meta-data to copy. It doesn't copy frozen data.
*
* @return CO_BUF_ERR_NO_ERROR if copy has been properly performed.
* CO_BUF_ERR_INVALID_PARAM if the output buffer data size is cannot accept input data length.
****************************************************************************************
*/
uint8_t co_buf_copy(const co_buf_t *p_buf_in, co_buf_t *p_buf_out, uint16_t length, uint8_t copy_meta_size);
/**
****************************************************************************************
* @brief Reuse a given buffer with keeping data information. This can be done only if
* buffer has been released by other software module. meta-data data can be
* considered empty if function execution succeeds.
*
* If this function succeeds it must be considered as an old buffer release and
* new buffer allocation.
* If function execution fails, the buffer is not considered as released
*
* @param[in] p_buf Pointer to the buffer.
*
* @return CO_BUF_ERR_NO_ERROR if buffer has been properly released and reused
* CO_BUF_ERR_RESOURCE_BUSY if buffer acquisition counter > 1
****************************************************************************************
*/
uint8_t co_buf_reuse(co_buf_t *p_buf);
/**
****************************************************************************************
* @brief Reuse a given buffer without keeping data information. This can be done only if
* buffer has been released by other software module. meta-data data can be
* considered empty if function execution succeeds.
*
* Size of header, data_ and trailing length must not exceed size of the buffer.
*
* If this function succeeds it must be considered as an old buffer release and
* new buffer allocation.
* If function execution fails, the buffer is not considered as released.
*
* @param[in] p_buf Pointer to the buffer.
* @param[in] head_len Initial Head Length.
* @param[in] data_len Initial Data Length.
* @param[in] tail_len Initial Tail Length.
*
* @return CO_BUF_ERR_NO_ERROR if buffer has been properly released and reused
* CO_BUF_ERR_RESOURCE_BUSY if buffer acquisition counter > 1
* CO_BUF_ERR_INVALID_PARAM if length fields exceed length of initial buffer
****************************************************************************************
*/
// uint8_t co_buf_reuse_full(co_buf_t *p_buf, uint16_t head_len, uint16_t data_len, uint16_t tail_len);
/**
****************************************************************************************
* @brief TThis function allows a software module to be informed when buffer is free.
* It freezes 8 bytes in buffer meta-data.
*
* This function shall be called only after a buffer allocation or reuse.
*
* @param[in] p_buf Pointer to the buffer.
* @param[in] cb_free Pointer to the function called when the buffer is free.
* @param[in] p_env Pointer to environment that will be used as callback parameter.
*
* @return CO_BUF_ERR_NO_ERROR callback has been properly set
* CO_BUF_ERR_RESOURCE_BUSY if some buffer meta-data already frozen
****************************************************************************************
*/
uint8_t co_buf_cb_free_set(co_buf_t *p_buf, co_buf_free_cb cb_free, void* p_env);
/**
****************************************************************************************
* @brief This function copies content of an input memory data to the data part of a
* buffer. The length field shall not exceed buffer data length.
*
* @param[in] p_buf Pointer to the buffer.
* @param[in] p_in Pointer to input data.
* @param[in] length Length of data to copy
*
* @return CO_BUF_ERR_NO_ERROR if copy has been properly performed.
* CO_BUF_ERR_INVALID_PARAM if data length fields < length parameter
****************************************************************************************
*/
uint8_t co_buf_copy_data_from_mem(co_buf_t *p_buf, const uint8_t *p_in, uint16_t length);
/**
****************************************************************************************
* @brief This function copies data part of a buffer into an output memory block.
* The length field shall not exceed buffer data length..
*
* @param[in] p_buf Pointer to the buffer.
* @param[in] p_out Pointer to output data.
* @param[in] length Length of data to copy
*
* @return CO_BUF_ERR_NO_ERROR if copy has been properly performed.
* CO_BUF_ERR_INVALID_PARAM if data length fields < length parameter
****************************************************************************************
*/
uint8_t co_buf_copy_data_to_mem(const co_buf_t *p_buf, uint8_t *p_out, uint16_t length);
/**
****************************************************************************************
* @brief Initialize Common buffer module.
*
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
* @param[in] p_big_pool Pointer to the Big pool memory Array
* @param[in] p_small_pool Pointer to the Small pool memory Array
****************************************************************************************
*/
void co_buf_init(uint8_t init_type, uint32_t* p_big_pool, uint32_t* p_small_pool);
/// @} CO_BUF
#endif // _CO_BUF_H_
+134
View File
@@ -0,0 +1,134 @@
/**
****************************************************************************************
*
* @file co_djob.h
*
* @brief Common delayed job definitions
*
* Copyright (C) RivieraWaves 2009-2019
*
****************************************************************************************
*/
#ifndef _CO_DJOB_H_
#define _CO_DJOB_H_
/**
****************************************************************************************
* @defgroup CO_DJOB Utilities
* @ingroup COMMON
* @brief Delayed job utilities
*
* This module contains the delayed job utilities functions and macros.
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdint.h> // standard definitions
#include <stddef.h> // standard definitions
#include "co_list.h" // common bt definitions
/*
* MACRO DEFINITIONS
****************************************************************************************
*/
/*
* ENUMERATIONS DEFINITIONS
****************************************************************************************
*/
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Job function to called into a background context
*
* @param[in] p_env Pointer to environment that will be used as callback parameter.
****************************************************************************************
*/
typedef void (*co_djob_cb)(void* p_env);
/// Job element structure
typedef struct co_djob
{
/// List element header
co_list_hdr_t hdr;
/// Pointer to environment that will be used as callback parameter.
void* p_env;
/// Callback to execute in background context
co_djob_cb cb;
} co_djob_t;
/*
* CONSTANT DECLARATIONS
****************************************************************************************
*/
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/*
****************************************************************************************
* Delayed Job functions
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Prepare Delayed job structure
*
* @param[in] p_djob Pointer to the delayed job structure
* @param[in] cb Callback to execute in background context
* @param[in] p_env Pointer to environment that will be used as callback parameter.
****************************************************************************************
*/
void co_djob_prepare(co_djob_t* p_djob, co_djob_cb cb, void* p_env);
/**
****************************************************************************************
* @brief Register to execute a job delayed in background
*
* @param[in] p_djob Pointer to the delayed job structure
****************************************************************************************
*/
void co_djob_reg(co_djob_t* p_djob);
/**
****************************************************************************************
* @brief Un-register a job that waits to be executed
*
* @param[in] p_djob Pointer to the delayed job structure
****************************************************************************************
*/
void co_djob_unreg(co_djob_t* p_djob);
/**
****************************************************************************************
* @brief Initialize Common delayed job module.
*
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
****************************************************************************************
*/
void co_djob_init(uint8_t init_type);
/// @} CO_DJOB
#endif // _CO_DJOB_H_
@@ -0,0 +1,349 @@
/**
****************************************************************************************
*
* @file co_endian.h
*
* @brief Common endianness conversion functions
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef _CO_ENDIAN_H_
#define _CO_ENDIAN_H_
#include <stdint.h> // standard integer definitions
#include "rwip_config.h" // stack configuration
#include "arch.h" // architectural platform definition
/**
****************************************************************************************
* @defgroup CO_ENDIAN Endianness
* @ingroup COMMON
* @brief Endianness conversion functions.
*
* This set of functions converts values between the local system
* and a external one. It is inspired from the <tt>htonl</tt>-like functions
* from the standard C library.
*
* Example:
* @code
* struct eth_header *header = get_header(); // get pointer on Eth II packet header
* uint16_t eth_id; // will contain the type of the packet
* eth_id = co_ntohs(header->eth_id); // retrieve the type with correct endianness
* @endcode
*
* @{
* ****************************************************************************************
* */
/**
****************************************************************************************
* @brief Swap bytes of an array of bytes
* .
* The swap is done in every case. Should not be called directly.
*
* @param[in] p_val_out The output value.
* @param[in] p_val_in The input value.
*
* @param[in] len number of bytes to swap
****************************************************************************************
*/
__INLINE void co_bswap(uint8_t* p_val_out, const uint8_t* p_val_in, uint16_t len)
{
while (len > 0)
{
len--;
*p_val_out = p_val_in[len];
p_val_out++;
}
}
/// @} CO_ENDIAN
/**
****************************************************************************************
* @brief Swap bytes of a 32 bits value.
* The swap is done in every case. Should not be called directly.
* @param[in] val32 The 32 bits value to swap.
* @return The 32 bit swapped value.
****************************************************************************************
*/
__INLINE uint32_t co_bswap32(uint32_t val32)
{
return (val32<<24) | ((val32<<8)&0xFF0000) | ((val32>>8)&0xFF00) | ((val32>>24)&0xFF);
}
/**
****************************************************************************************
* @brief Swap bytes of a 24 bits value.
* The swap is done in every case. Should not be called directly.
* @param[in] val24 The 24 bits value to swap.
* @return The 24 bit swapped value.
****************************************************************************************
*/
__INLINE uint32_t co_bswap24(uint32_t val24)
{
return ((val24<<16)&0xFF0000) | ((val24)&0xFF00) | ((val24>>16)&0xFF);
}
/**
****************************************************************************************
* @brief Swap bytes of a 16 bits value.
* The swap is done in every case. Should not be called directly.
* @param[in] val16 The 16 bit value to swap.
* @return The 16 bit swapped value.
****************************************************************************************
*/
__INLINE uint16_t co_bswap16(uint16_t val16)
{
return ((val16<<8)&0xFF00) | ((val16>>8)&0xFF);
}
/// @} CO_ENDIAN
/**
* ****************************************************************************************
* @defgroup CO_ENDIAN_NET Endianness (Network)
* @ingroup CO_ENDIAN
* @brief Endianness conversion functions for Network data
*
* Converts values between the local system and big-endian network data
* (e.g. IP, Ethernet, but NOT WLAN).
*
* The \b host term in the descriptions of these functions refers
* to the local system, i.e. \b application or \b embedded system.
* Therefore, these functions will behave differently depending on which
* side they are used. The reason of this terminology is to keep the
* same name than the standard C function.
*
* Behavior will depends on the endianness of the host:
* - little endian: swap bytes;
* - big endian: identity function.
*
* @{
* ****************************************************************************************
* */
/**
****************************************************************************************
* @brief Convert host to network long word.
*
* @param[in] hostlong Long word value to convert.
*
* @return The converted long word.
****************************************************************************************
*/
__INLINE uint32_t co_htonl(uint32_t hostlong)
{
#if (!CPU_LE)
return hostlong;
#else
return co_bswap32(hostlong);
#endif // CPU_LE
}
/**
****************************************************************************************
* @brief Convert host to network long 24-bit value.
*
* @param[in] val24 24-bit value to convert.
*
* @return The converted 24-but value.
****************************************************************************************
*/
__INLINE uint32_t co_hton24(uint32_t host24)
{
#if (!CPU_LE)
return host24;
#else
return co_bswap24(host24);
#endif // CPU_LE
}
/**
****************************************************************************************
* @brief Convert host to network short word.
*
* @param[in] hostshort Short word value to convert.
*
* @return The converted short word.
****************************************************************************************
*/
__INLINE uint16_t co_htons(uint16_t hostshort)
{
#if (!CPU_LE)
return hostshort;
#else
return co_bswap16(hostshort);
#endif // CPU_LE
}
/**
****************************************************************************************
* @brief Convert network to host long word.
*
* @param[in] netlong Long word value to convert.
*
* @return The converted long word.
****************************************************************************************
*/
__INLINE uint32_t co_ntohl(uint32_t netlong)
{
return co_htonl(netlong);
}
/**
****************************************************************************************
* @brief Convert network to host 24-bit value.
*
* @param[in] val24 24-bit to convert.
*
* @return The converted 24-bit value.
****************************************************************************************
*/
__INLINE uint32_t co_ntoh24(uint32_t val24)
{
return co_hton24(val24);
}
/**
****************************************************************************************
* @brief Convert network to host short word.
*
* @param[in] netshort Short word value to convert.
*
* @return The converted short word.
****************************************************************************************
*/
__INLINE uint16_t co_ntohs(uint16_t netshort)
{
return co_htons(netshort);
}
/// @} CO_ENDIAN_NET
/**
* ****************************************************************************************
* @defgroup CO_ENDIAN_BT Endianness (BT)
* @ingroup CO_ENDIAN
* @brief Endianness conversion functions for Bluetooth data (HCI and protocol)
*
* Converts values between the local system and little-endian Bluetooth data.
*
* The \b host term in the descriptions of these functions refers
* to the local system (check \ref CO_ENDIAN_NET "this comment").
*
* Behavior will depends on the endianness of the host:
* - little endian: identity function;
* - big endian: swap bytes.
*
* @addtogroup CO_ENDIAN_BT
* @{
* ****************************************************************************************
* */
/**
****************************************************************************************
* @brief Convert Bluetooth to host 24-bit value.
*
* @param[in] val24 24-bit to convert.
*
* @return The converted 24-bit value.
****************************************************************************************
*/
__INLINE uint32_t co_htob24(uint32_t val24)
{
#if (CPU_LE)
return val24;
#else
return co_hton24(val24);
#endif // CPU_LE
}
/**
****************************************************************************************
* @brief Convert host to Bluetooth long word.
*
* @param[in] hostlong Long word value to convert.
*
* @return The converted long word.
****************************************************************************************
*/
__INLINE uint32_t co_htobl(uint32_t hostlong)
{
#if (CPU_LE)
return hostlong;
#else
return co_bswap32(hostlong);
#endif // CPU_LE
}
/**
****************************************************************************************
* @brief Convert host to Bluetooth short word.
*
* @param[in] hostshort Short word value to convert.
*
* @return The converted short word.
****************************************************************************************
*/
__INLINE uint16_t co_htobs(uint16_t hostshort)
{
#if (CPU_LE)
return hostshort;
#else
return co_bswap16(hostshort);
#endif // CPU_LE
}
/**
****************************************************************************************
* @brief Convert Bluetooth to host 24-bit value.
*
* @param[in] val24 24-bit to convert.
*
* @return The converted 24-bit value.
****************************************************************************************
*/
__INLINE uint32_t co_btoh24(uint32_t val24)
{
return co_htob24(val24);
}
/**
****************************************************************************************
* @brief Convert Bluetooth to host long word.
*
* @param[in] btlong Long word value to convert.
*
* @return The converted long word.
****************************************************************************************
*/
__INLINE uint32_t co_btohl(uint32_t btlong)
{
return co_htobl(btlong);
}
/**
****************************************************************************************
* @brief Convert Bluetooth to host short word.
*
* @param[in] btshort Short word value to convert.
*
* @return The converted short word.
****************************************************************************************
*/
__INLINE uint16_t co_btohs(uint16_t btshort)
{
return co_htobs(btshort);
}
/// @} CO_ENDIAN
#endif // _CO_ENDIAN_H_
+116
View File
@@ -0,0 +1,116 @@
/**
****************************************************************************************
*
* @file co_error.h
*
* @brief List of codes for error in RW Software.
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef CO_ERROR_H_
#define CO_ERROR_H_
/**
****************************************************************************************
* @addtogroup CO_ERROR Error Codes
* @ingroup COMMON
* @brief Defines error codes in messages.
*
* @{
****************************************************************************************
*/
/*
* DEFINES
****************************************************************************************
*/
enum co_error
{
/*****************************************************
*** ERROR CODES ***
*****************************************************/
CO_ERROR_NO_ERROR = 0x00,
CO_ERROR_UNKNOWN_HCI_COMMAND = 0x01,
CO_ERROR_UNKNOWN_CONNECTION_ID = 0x02,
CO_ERROR_HARDWARE_FAILURE = 0x03,
CO_ERROR_PAGE_TIMEOUT = 0x04,
CO_ERROR_AUTH_FAILURE = 0x05,
CO_ERROR_PIN_MISSING = 0x06,
CO_ERROR_MEMORY_CAPA_EXCEED = 0x07,
CO_ERROR_CON_TIMEOUT = 0x08,
CO_ERROR_CON_LIMIT_EXCEED = 0x09,
CO_ERROR_SYNC_CON_LIMIT_DEV_EXCEED = 0x0A,
CO_ERROR_CON_ALREADY_EXISTS = 0x0B,
CO_ERROR_COMMAND_DISALLOWED = 0x0C,
CO_ERROR_CONN_REJ_LIMITED_RESOURCES = 0x0D,
CO_ERROR_CONN_REJ_SECURITY_REASONS = 0x0E,
CO_ERROR_CONN_REJ_UNACCEPTABLE_BDADDR = 0x0F,
CO_ERROR_CONN_ACCEPT_TIMEOUT_EXCEED = 0x10,
CO_ERROR_UNSUPPORTED = 0x11,
CO_ERROR_INVALID_HCI_PARAM = 0x12,
CO_ERROR_REMOTE_USER_TERM_CON = 0x13,
CO_ERROR_REMOTE_DEV_TERM_LOW_RESOURCES = 0x14,
CO_ERROR_REMOTE_DEV_POWER_OFF = 0x15,
CO_ERROR_CON_TERM_BY_LOCAL_HOST = 0x16,
CO_ERROR_REPEATED_ATTEMPTS = 0x17,
CO_ERROR_PAIRING_NOT_ALLOWED = 0x18,
CO_ERROR_UNKNOWN_LMP_PDU = 0x19,
CO_ERROR_UNSUPPORTED_REMOTE_FEATURE = 0x1A,
CO_ERROR_SCO_OFFSET_REJECTED = 0x1B,
CO_ERROR_SCO_INTERVAL_REJECTED = 0x1C,
CO_ERROR_SCO_AIR_MODE_REJECTED = 0x1D,
CO_ERROR_INVALID_LMP_PARAM = 0x1E,
CO_ERROR_UNSPECIFIED_ERROR = 0x1F,
CO_ERROR_UNSUPPORTED_LMP_PARAM_VALUE = 0x20,
CO_ERROR_ROLE_CHANGE_NOT_ALLOWED = 0x21,
CO_ERROR_LMP_RSP_TIMEOUT = 0x22,
CO_ERROR_LMP_COLLISION = 0x23,
CO_ERROR_LMP_PDU_NOT_ALLOWED = 0x24,
CO_ERROR_ENC_MODE_NOT_ACCEPT = 0x25,
CO_ERROR_LINK_KEY_CANT_CHANGE = 0x26,
CO_ERROR_QOS_NOT_SUPPORTED = 0x27,
CO_ERROR_INSTANT_PASSED = 0x28,
CO_ERROR_PAIRING_WITH_UNIT_KEY_NOT_SUP = 0x29,
CO_ERROR_DIFF_TRANSACTION_COLLISION = 0x2A,
CO_ERROR_QOS_UNACCEPTABLE_PARAM = 0x2C,
CO_ERROR_QOS_REJECTED = 0x2D,
CO_ERROR_CHANNEL_CLASS_NOT_SUP = 0x2E,
CO_ERROR_INSUFFICIENT_SECURITY = 0x2F,
CO_ERROR_PARAM_OUT_OF_MAND_RANGE = 0x30,
CO_ERROR_ROLE_SWITCH_PEND = 0x32, /* LM_ROLE_SWITCH_PENDING */
CO_ERROR_RESERVED_SLOT_VIOLATION = 0x34, /* LM_RESERVED_SLOT_VIOLATION */
CO_ERROR_ROLE_SWITCH_FAIL = 0x35, /* LM_ROLE_SWITCH_FAILED */
CO_ERROR_EIR_TOO_LARGE = 0x36, /* LM_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE */
CO_ERROR_SP_NOT_SUPPORTED_HOST = 0x37,
CO_ERROR_HOST_BUSY_PAIRING = 0x38,
CO_ERROR_CONTROLLER_BUSY = 0x3A,
CO_ERROR_UNACCEPTABLE_CONN_PARAM = 0x3B,
CO_ERROR_ADV_TO = 0x3C,
CO_ERROR_TERMINATED_MIC_FAILURE = 0x3D,
CO_ERROR_CONN_FAILED_TO_BE_EST = 0x3E,
CO_ERROR_CCA_REJ_USE_CLOCK_DRAG = 0x40,
CO_ERROR_TYPE0_SUBMAP_NOT_DEFINED = 0x41,
CO_ERROR_UNKNOWN_ADVERTISING_ID = 0x42,
CO_ERROR_LIMIT_REACHED = 0x43,
CO_ERROR_OPERATION_CANCELED_BY_HOST = 0x44,
CO_ERROR_PKT_TOO_LONG = 0x45,
CO_ERROR_UNDEFINED = 0xFF,
/*****************************************************
*** HW ERROR CODES ***
*****************************************************/
CO_ERROR_HW_UART_OUT_OF_SYNC = 0x00,
CO_ERROR_HW_MEM_ALLOC_FAIL = 0x01,
};
/// @} CO_ERROR
#endif // CO_ERROR_H_
File diff suppressed because it is too large Load Diff
+316
View File
@@ -0,0 +1,316 @@
/**
****************************************************************************************
*
* @file co_list.h
*
* @brief Common list structures definitions
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef _CO_LIST_H_
#define _CO_LIST_H_
/**
*****************************************************************************************
* @defgroup CO_LIST List management
* @ingroup COMMON
*
* @brief List management.
*
* This module contains the list structures and handling functions.
* @{
*****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdint.h> // standard definition
#include <stdbool.h> // boolean definition
#include <stddef.h> // for NULL and size_t
#include "rwip_config.h" // stack configuration
#include "compiler.h" // for __INLINE
/*
* DEFINES
****************************************************************************************
*/
/// structure of a list element header
/*@TRACE*/
struct co_list_hdr
{
/// Pointer to next co_list_hdr
struct co_list_hdr *next;
};
/// simplify type name of list element header
typedef struct co_list_hdr co_list_hdr_t;
/// structure of a list
struct co_list
{
/// pointer to first element of the list
struct co_list_hdr *first;
/// pointer to the last element
struct co_list_hdr *last;
#if (KE_PROFILING)
/// number of element in the list
uint32_t cnt;
/// max number of element in the list
uint32_t maxcnt;
/// min number of element in the list
uint32_t mincnt;
#endif //KE_PROFILING
};
/// simplify type name of list
typedef struct co_list co_list_t;
/*
* MACROS
****************************************************************************************
*/
/// pop a specific element from the list
#define CO_LIST_POP_ELT(list, elt) co_list_extract(&(list), &(elt->hdr));
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Initialize a list to defaults values.
*
* @param list Pointer to the list structure.
****************************************************************************************
*/
void co_list_init(struct co_list *list);
/**
****************************************************************************************
* @brief Construct a list of free elements representing a pool
*
* @param list Pointer to the list structure
* @param pool Pointer to the pool to be initialized
* @param elmt_size Size of one element of the pool (in bytes)
* @param elmt_cnt Number of elements available in the pool
****************************************************************************************
*/
void co_list_pool_init(struct co_list *list,
void *pool,
size_t elmt_size,
uint32_t elmt_cnt);
/**
****************************************************************************************
* @brief Add an element as last on the list.
*
* @param list Pointer to the list structure
* @param list_hdr Pointer to the header to add at the end of the list
*
****************************************************************************************
*/
void co_list_push_back(struct co_list *list, struct co_list_hdr *list_hdr);
/**
****************************************************************************************
* @brief Append a sequence of elements at the end of a list.
*
* Note: the elements to append shall be linked together
*
* @param list Pointer to the list structure
* @param first_hdr Pointer to the first element to append
* @param last_hdr Pointer to the last element to append
****************************************************************************************
*/
void co_list_push_back_sublist(struct co_list *list, struct co_list_hdr *first_hdr, struct co_list_hdr *last_hdr);
/**
****************************************************************************************
* @brief Add an element as first on the list.
*
* @param list Pointer to the list structure
* @param list_hdr Pointer to the header to add at the beginning of the list
****************************************************************************************
*/
void co_list_push_front(struct co_list *list, struct co_list_hdr *list_hdr);
/**
****************************************************************************************
* @brief Extract the first element of the list.
* @param list Pointer to the list structure
* @return The pointer to the element extracted, and NULL if the list is empty.
****************************************************************************************
*/
struct co_list_hdr *co_list_pop_front(struct co_list *list);
/**
****************************************************************************************
* @brief Search for a given element in the list, and extract it if found.
*
* @param list Pointer to the list structure
* @param list_hdr Element to extract
*
* @return true if the element is found in the list, false otherwise
****************************************************************************************
*/
bool co_list_extract(struct co_list *list, struct co_list_hdr *list_hdr);
/**
****************************************************************************************
* @brief Extract an element when the previous element is known
*
* Note: the element to remove shall follow immediately the reference within the list
*
* @param list Pointer to the list structure
* @param elt_ref_hdr Pointer to the referenced element (NULL if element to extract is the first in the list)
* @param elt_to_rem_hdr Pointer to the element to be extracted
****************************************************************************************
*/
void co_list_extract_after(struct co_list *list, struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_rem_hdr);
/**
****************************************************************************************
* @brief Extract a sub-list when the previous element is known
*
* Note: the elements to remove shall be linked together and follow immediately the reference element
*
* @param[in] list Pointer to the list structure
* @param[in] ref_hdr Pointer to the referenced element (NULL if first element to extract is first in the list)
* @param[in] last_hdr Pointer to the last element to extract ()
****************************************************************************************
*/
void co_list_extract_sublist(struct co_list *list, struct co_list_hdr *ref_hdr, struct co_list_hdr *last_hdr);
/**
****************************************************************************************
* @brief Searched a given element in the list.
*
* @param list Pointer to the list structure
* @param list_hdr Pointer to the searched element
*
* @return true if the element is found in the list, false otherwise
****************************************************************************************
*/
// bool co_list_find(struct co_list *list, struct co_list_hdr *list_hdr);
/**
****************************************************************************************
* @brief Merge two lists in a single one.
*
* This function appends the list pointed by list2 to the list pointed by list1. Once the
* merge is done, it empties list2.
*
* @param list1 Pointer to the destination list
* @param list2 Pointer to the list to append to list1
****************************************************************************************
*/
// void co_list_merge(struct co_list *list1, struct co_list *list2);
/**
****************************************************************************************
* @brief Insert a given element in the list before the referenced element.
*
* @param list Pointer to the list structure
* @param elt_ref_hdr Pointer to the referenced element
* @param elt_to_add_hdr Pointer to the element to be inserted
*
* @return true if the element is found in the list, false otherwise
****************************************************************************************
*/
void co_list_insert_before(struct co_list *list,
struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr);
/**
****************************************************************************************
* @brief Insert a given element in the list after the referenced element.
*
* @param list Pointer to the list structure
* @param elt_ref_hdr Pointer to the referenced element
* @param elt_to_add_hdr Pointer to the element to be inserted
*
* @return true if the element is found in the list, false otherwise
****************************************************************************************
*/
void co_list_insert_after(struct co_list *list,
struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr);
/**
****************************************************************************************
* @brief Count number of elements present in the list
*
* @param list Pointer to the list structure
*
* @return Number of elements present in the list
****************************************************************************************
*/
// uint16_t co_list_size(struct co_list *list);
/**
****************************************************************************************
* @brief Test if the list is empty.
* @param list Pointer to the list structure.
* @return true if the list is empty, false else otherwise.
****************************************************************************************
*/
__INLINE bool co_list_is_empty(const struct co_list *const list)
{
bool listempty;
listempty = (list->first == NULL);
return (listempty);
}
/**
****************************************************************************************
* @brief Pick the first element from the list without removing it.
*
* @param list Pointer to the list structure.
*
* @return First element address. Returns NULL pointer if the list is empty.
****************************************************************************************
*/
__INLINE struct co_list_hdr *co_list_pick(const struct co_list *const list)
{
return(list->first);
}
/**
****************************************************************************************
* @brief Pick last element from the list without removing it.
*
* @param list Pointer to the list structure.
*
* @return Last element address. Returns NULL pointer if the list is empty.
****************************************************************************************
*/
__INLINE struct co_list_hdr *co_list_tail(const struct co_list *const list)
{
return(list->last);
}
/**
****************************************************************************************
* @brief Return following element of a list element.
*
* @param list_hdr Pointer to the list element.
*
* @return The pointer to the next element.
****************************************************************************************
*/
__INLINE struct co_list_hdr *co_list_next(const struct co_list_hdr *const list_hdr)
{
return(list_hdr->next);
}
/// @} CO_LIST
#endif // _CO_LIST_H_
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+307
View File
@@ -0,0 +1,307 @@
/**
****************************************************************************************
*
* @file co_math.h
*
* @brief Common optimized math functions
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef _CO_MATH_H_
#define _CO_MATH_H_
/**
*****************************************************************************************
* @defgroup CO_MATH Math functions
* @ingroup COMMON
* @brief Optimized math functions and other computations.
*
* @{
*****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdint.h> // standard integer definitions
#include <stdbool.h> // boolean definitions
#include <stdlib.h> // standard library
#include "compiler.h" // for __INLINE
#include "arch.h" // for ASSERT_ERR
extern void srand (unsigned int seed);
extern int rand (void);
/*
* MACROS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Return value with one bit set.
*
* @param[in] pos Position of the bit to set.
*
* @return Value with one bit set. There is no return type since this is a macro and this
* will be resolved by the compiler upon assignment to an l-value.
****************************************************************************************
*/
#define CO_BIT(pos) (1UL<<(pos))
/**
****************************************************************************************
* @brief Return value bit into a bit field.
*
* @param[in] bf Bit Field
* @param[in] pos Position of the bit
*
* @return value of a bit into a bit field
****************************************************************************************
*/
#define CO_BIT_GET(bf, pos) (((((uint8_t*)bf)[((pos) >> 3)])>>((pos) & 0x7)) & 0x1)
/**
****************************************************************************************
* @brief Update value bit into a bit field.
*
* @param[in] bf Bit Field
* @param[in] pos Position of the bit
* @param[in] val New value of the bit (0 or 1)
****************************************************************************************
*/
#define CO_BIT_SET(bf, pos, val) (((uint8_t*)bf)[((pos) >> 3)]) = ((((uint8_t*)bf)[((pos) >> 3)]) & ~CO_BIT(((pos) & 0x7))) \
| (((val) & 0x1) << ((pos) & 0x7))
/**
****************************************************************************************
* @brief Align val on the multiple of 4 equal or nearest higher.
* @param[in] val Value to align.
* @return Value aligned.
****************************************************************************************
*/
#define CO_ALIGN4_HI(val) (((val)+3)&~3)
/**
****************************************************************************************
* @brief Align val on the multiple of 4 equal or nearest lower.
* @param[in] val Value to align.
* @return Value aligned.
****************************************************************************************
*/
#define CO_ALIGN4_LO(val) ((val)&~3)
/**
****************************************************************************************
* @brief Align val on the multiple of 2 equal or nearest higher.
* @param[in] val Value to align.
* @return Value aligned.
****************************************************************************************
*/
#define CO_ALIGN2_HI(val) (((val)+1)&~1)
/**
****************************************************************************************
* @brief Align val on the multiple of 2 equal or nearest lower.
* @param[in] val Value to align.
* @return Value aligned.
****************************************************************************************
*/
#define CO_ALIGN2_LO(val) ((val)&~1)
/**
****************************************************************************************
* Perform a division and ceil up the result
*
* @param[in] val Value to divide
* @param[in] div Divide value
* @return ceil(val/div)
****************************************************************************************
*/
#define CO_DIVIDE_CEIL(val, div) (((val) + ((div) - 1))/ (div))
/**
****************************************************************************************
* Perform a division and round the result
*
* @param[in] val Value to divide
* @param[in] div Divide value
* @return round(val/div)
****************************************************************************************
*/
#define CO_DIVIDE_ROUND(val, div) (((val) + ((div) >> 1))/ (div))
/**
****************************************************************************************
* Perform a modulo operation
*
* @param[in] val Dividend
* @param[in] div Divisor
* @return val/div)
****************************************************************************************
*/
//#define CO_MOD(val, div) ((val) % (div))
__INLINE uint32_t co_mod(uint32_t val, uint32_t div)
{
ASSERT_ERR(div);
return ((val) % (div));
}
#define CO_MOD(val, div) co_mod(val, div)
/*
* FUNCTION DEFINTIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Count leading zeros.
* @param[in] val Value to count the number of leading zeros on.
* @return Number of leading zeros when value is written as 32 bits.
****************************************************************************************
*/
__INLINE uint32_t co_clz(uint32_t val)
{
#if defined(__arm__)
return __builtin_clz(val);
#elif defined(__GNUC__)
if (val == 0)
{
return 32;
}
return __builtin_clz(val);
#else
uint32_t i;
for (i = 0; i < 32; i++)
{
if (val & CO_BIT(31 - i))
break;
}
return i;
#endif // defined(__arm__)
}
/**
****************************************************************************************
* @brief Count trailing zeros.
* @param[in] val Value to count the number of trailing zeros on.
* @return Number of trailing zeros when value is written as 32 bits.
****************************************************************************************
*/
__INLINE uint32_t co_ctz(uint32_t val)
{
#if defined(__arm__)
return __builtin_ctz(val);
#elif defined(__GNUC__)
if (val == 0)
{
return 32;
}
return __builtin_ctz(val);
#else
uint32_t i;
for (i = 0; i < 32; i++)
{
if (val & CO_BIT(i))
break;
}
return i;
#endif // defined(__arm__)
}
/**
****************************************************************************************
* @brief Function to initialize the random seed.
* @param[in] seed The seed number to use to generate the random sequence.
****************************************************************************************
*/
void co_random_init(uint32_t seed);
//{
// srand(seed);
//}
///**
// ****************************************************************************************
// * @brief Function to get an 8 bit random number.
// * @return Random byte value.
// ****************************************************************************************
// */
uint8_t co_rand_byte(void);
//{
// return (uint8_t)(rand() & 0xFF);
//}
///**
// ****************************************************************************************
// * @brief Function to get an 16 bit random number.
// * @return Random half word value.
// ****************************************************************************************
// */
uint16_t co_rand_hword(void);
//{
// return (uint16_t)(rand() & 0xFFFF);
//}
///**
// ****************************************************************************************
// * @brief Function to get an 32 bit random number.
// * @return Random word value.
// ****************************************************************************************
// */
uint32_t co_rand_word(void);
//{
// return (uint32_t)rand();
//}
/**
****************************************************************************************
* @brief Function to return the smallest of 2 unsigned 32 bits words.
* @return The smallest value.
****************************************************************************************
*/
__INLINE uint32_t co_min(uint32_t a, uint32_t b)
{
return a < b ? a : b;
}
/**
****************************************************************************************
* @brief Function to return the smallest of 2 signed 32 bits words.
* @return The smallest value.
****************************************************************************************
*/
__INLINE int32_t co_min_s(int32_t a, int32_t b)
{
return a < b ? a : b;
}
/**
****************************************************************************************
* @brief Function to return the greatest of 2 unsigned 32 bits words.
* @return The greatest value.
****************************************************************************************
*/
__INLINE uint32_t co_max(uint32_t a, uint32_t b)
{
return a > b ? a : b;
}
/**
****************************************************************************************
* @brief Function to return the absolute value of a signed integer.
* @return The absolute value.
****************************************************************************************
*/
__INLINE int co_abs(int val)
{
return (val < 0) ? (0 - val) : val;
}
/// @} CO_MATH
#endif // _CO_MATH_H_
+210
View File
@@ -0,0 +1,210 @@
/**
****************************************************************************************
*
* @file co_time.h
*
* @brief The Common Time module provides information about the device time and a
* scheduler for timers used by the different modules. It maintains a list of
* pending timers sorted by ascending expiration time. One timer is programmed
* at a given time. A callback is associated with each timer and is called upon
* expiration of the timer.
*
* Timers shall be used for non real time software.
*
* Copyright (C) RivieraWaves 2009-2019
*
****************************************************************************************
*/
#ifndef _CO_TIME_H_
#define _CO_TIME_H_
/**
****************************************************************************************
* @defgroup CO_TIME Utilities
* @ingroup COMMON
* @brief Time utilities
*
* This module contains the Common time utilities functions and macros.
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdint.h> // standard definitions
#include <stddef.h> // standard definitions
/*
* MACRO DEFINITIONS
****************************************************************************************
*/
/*
* ENUMERATIONS DEFINITIONS
****************************************************************************************
*/
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Function to called once timer expires
*
* @param[in] p_env Pointer to environment that will be used as callback parameter.
****************************************************************************************
*/
typedef void (*co_time_timer_cb)(void* p_env);
/// Timer structure
typedef struct co_time_timer
{
/// Pointer to next timer in timer list
struct co_time_timer * p_next;
/// Pointer to environment that will be used as callback parameter.
void* p_env;
/// Callback to execute in background context upon timer expiration
co_time_timer_cb cb;
/// Expiration time [0-31] part (in milliseconds)
uint32_t exp_time_ms_lsb;
/// Timer bit field (@see enum co_time_timer_bf)
uint32_t timer_bf;
} co_time_timer_t;
/// Time Structure
typedef struct co_time
{
/// Current time [0-31] part (in milliseconds)
uint32_t ms_lsb;
/// Current time [32-39] part (in milliseconds)
uint8_t ms_msb;
} co_time_t;
/*
* CONSTANT DECLARATIONS
****************************************************************************************
*/
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Initialize Common time module.
*
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
****************************************************************************************
*/
void co_time_init(uint8_t init_type);
/*
****************************************************************************************
* Time and timer functions
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Retrieve current time in milliseconds.
*
* Time value can be either Up-time of the device or Time since the device has been
* started for the first time.
*
* This depends if system is able to compensate power-off time to update internal time value
*
* @return current time in milliseconds.
*
****************************************************************************************
*/
co_time_t co_time_get(void);
/**
****************************************************************************************
* @brief Retrieve current time in milliseconds.
*
* Compensate device time. This compensation should be done after power-up of the device.
* The time compensation is automatically performed by device when wake-up from sleep mode.
* This function shall be called when no timer are programmed at device start-up.
*
* @param[in] delta_time_ms_lsb Delta time [0-31] part (in milliseconds)
* @param[in] delta_time_ms_msb Delta time [32-39] part (in milliseconds)
****************************************************************************************
*/
// void co_time_compensate(uint32_t delta_time_ms_lsb, uint8_t delta_time_ms_msb);
/**
****************************************************************************************
* @brief Initialize timer structure.
*
* @param[in] p_timer Pointer to the timer structure.
* @param[in] cb Function to be called upon timer expiration.
* @param[in] p_env Pointer to be passed to the callback
****************************************************************************************
*/
void co_time_timer_init(co_time_timer_t* p_timer, co_time_timer_cb cb, void* p_env);
/**
****************************************************************************************
* @brief Program a timer to be scheduled in the future.
* If timer is already programmed, it is restarted.
* If delay is less than 10ms, delay is set to 10ms.
*
* @param[in] p_timer Pointer to the timer structure.
* @param[in] delay_ms Duration before expiration of the timer (in milliseconds).
****************************************************************************************
*/
void co_time_timer_set(co_time_timer_t* p_timer, uint32_t delay_ms);
/**
****************************************************************************************
* @brief Program a timer to be scheduled in the future with duration greater than 49 days.
* If timer is already programmed, it is restarted.
* If delay is less than 10ms, delay is set to 10ms.
*
* @param[in] p_timer Pointer to the timer structure.
* @param[in] delay_ms_lsb Duration before expiration of the timer [0-31] part (in milliseconds)
* @param[in] delay_ms_msb Duration before expiration of the timer [32-39] part (in milliseconds)
****************************************************************************************
*/
// void co_time_timer_long_set(co_time_timer_t* p_timer, uint32_t delay_ms_lsb, uint8_t delay_ms_msb);
/**
****************************************************************************************
* @brief Program a timer to be scheduled periodically. If timer is already programmed,
* it is restarted.
* If period exceed maximum value, timer is programmed using maximum period.
* If period less than 10ms, period is set to 10ms.
*
* @param[in] p_timer Pointer to the timer structure.
* @param[in] period_ms Periodic duration (in milliseconds). Range [10, 48388607] max ~2 hours
****************************************************************************************
*/
// void co_time_timer_periodic_set(co_time_timer_t* p_timer, uint32_t period_ms);
/**
****************************************************************************************
* @brief Stop a programmed timer.
*
* @param[in] p_timer Pointer to the timer structure.
****************************************************************************************
*/
void co_time_timer_stop(co_time_timer_t* p_timer);
/// @} CO_TIME
#endif // _CO_TIME_H_
+721
View File
@@ -0,0 +1,721 @@
/**
****************************************************************************************
*
* @file co_utils.h
*
* @brief Common utilities definitions
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef _CO_UTILS_H_
#define _CO_UTILS_H_
/**
****************************************************************************************
* @defgroup CO_UTILS Utilities
* @ingroup COMMON
* @brief Common utilities
*
* This module contains the common utilities functions and macros.
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdint.h> // standard definitions
#include <stddef.h> // standard definitions
#include "co_bt.h" // common bt definitions
#include "rwip_config.h" // SW configuration
#include "rwip.h" // SW configuration
#include "compiler.h" // for inline functions
/*
* MACRO DEFINITIONS
****************************************************************************************
*/
/// Common constants - bit field definitions
#define BIT0 0x0001
#define BIT1 0x0002
#define BIT2 0x0004
#define BIT3 0x0008
#define BIT4 0x0010
#define BIT5 0x0020
#define BIT6 0x0040
#define BIT7 0x0080
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
/// Number of '1' bits in a byte
#define NB_ONE_BITS(byte) (one_bits[byte & 0x0F] + one_bits[byte >> 4])
/// Get the number of elements within an array, give also number of rows in a 2-D array
#define ARRAY_LEN(array) (sizeof((array))/sizeof((array)[0]))
/// Get the number of columns within a 2-D array
#define ARRAY_NB_COLUMNS(array) (sizeof((array[0]))/sizeof((array)[0][0]))
/// Macro for LMP message handler function declaration or definition
#define LMP_MSG_HANDLER(msg_name) int lmp_##msg_name##_handler(struct lmp_##msg_name const *param, \
ke_task_id_t const dest_id)
/// Macro for LMP message handler function declaration or definition
#define LLCP_MSG_HANDLER(msg_name) int llcp_##msg_name##_handler(struct llcp_##msg_name const *param, \
ke_task_id_t const dest_id)
/// Macro for HCI message handler function declaration or definition (for multi-instantiated tasks)
#define HCI_CMD_HANDLER_C(cmd_name, param_struct) int hci_##cmd_name##_cmd_lc_handler(param_struct const *param, \
ke_task_id_t const dest_id, \
uint16_t opcode)
/// Macro for HCI message handler function declaration or definition (with parameters)
#define HCI_CMD_HANDLER(cmd_name, param_struct) int hci_##cmd_name##_cmd_handler(param_struct const *param, \
uint16_t opcode)
/// Macro for HCI message handler function declaration or definition (with parameters)
#define HCI_CMD_HANDLER_TAB(task) const struct task##_hci_cmd_handler task##_hci_command_handler_tab[] =
/// MACRO to build a subversion field from the Minor and Release fields
#define CO_SUBVERSION_BUILD(minor, release) (((minor) << 8) | (release))
/// Macro to get a structure from one of its structure field
#define CONTAINER_OF(ptr, type, member) ((type *)( (char *)ptr - offsetof(type,member) ))
/// count number of bit into a long field
#define CO_BIT_CNT(val) (co_bit_cnt((uint8_t*) &(val), sizeof(val)))
/// Increment value and make sure it's never greater or equals max (else wrap to 0)
#define CO_VAL_INC(_val, _max) \
(_val) = (_val) + 1; \
if((_val) >= (_max)) (_val) = 0
/// Add value and make sure it's never greater or equals max (else wrap)
/// _add must be less that _max
#define CO_VAL_ADD(_val, _add, _max) \
(_val) = (_val) + (_add); \
if((_val) >= (_max)) (_val) -= (_max)
/// sub value and make sure it's never greater or equals max (else wrap)
/// _sub must be less that _max
#define CO_VAL_SUB(_val, _sub, _max) \
if((_val) < (_sub)) (_val) += _max; \
(_val) = (_val) - (_sub)
/*
* ENUMERATIONS DEFINITIONS
****************************************************************************************
*/
/// Status returned by generic packer-unpacker
enum CO_UTIL_PACK_STATUS
{
CO_UTIL_PACK_OK,
CO_UTIL_PACK_IN_BUF_OVFLW,
CO_UTIL_PACK_OUT_BUF_OVFLW,
CO_UTIL_PACK_WRONG_FORMAT,
CO_UTIL_PACK_ERROR,
};
/// Rate information
/*@TRACE*/
enum phy_rate
{
/// 1 Mbits/s Rate
CO_RATE_1MBPS = 0,
/// 2 Mbits/s Rate
CO_RATE_2MBPS = 1,
/// 125 Kbits/s Rate
CO_RATE_125KBPS = 2,
/// 500 Kbits/s Rate
CO_RATE_500KBPS = 3,
/// Undefined rate (used for reporting when no packet is received)
CO_RATE_UNDEF = 4,
CO_RATE_MAX = 4,
};
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/*
* CONSTANT DECLARATIONS
****************************************************************************************
*/
/// Number of '1' bits in values from 0 to 15, used to fasten bit counting
extern const unsigned char one_bits[16];
/// Conversion table Sleep Clock Accuracy to PPM
extern const uint16_t co_sca2ppm[];
/// NULL BD address
extern const struct bd_addr co_null_bdaddr;
/// Default BD address
extern struct bd_addr co_default_bdaddr;
/// NULL Key
extern const uint8_t co_null_key[KEY_LEN];
/// Table for converting rate to PHY
extern const uint8_t co_rate_to_phy[];
/// Table for converting PHY to rate (Warning: the coded PHY is converted to 125K by default)
extern const uint8_t co_phy_to_rate[];
/// Convert PHY mask (with one single bit set) to a value
extern const uint8_t co_phy_mask_to_value[];
/// Convert PHY a value to the corresponding mask bit
extern const uint8_t co_phy_value_to_mask[];
/// Convert Rate value to the corresponding PHY mask bit
extern const uint8_t co_rate_to_phy_mask[];
/// Convert PHY mask bit to the corresponding Rate value
extern const uint8_t co_phy_mask_to_rate[];
#if BLE_PWR_CTRL
/// Convert PHY rate value of power control to the corresponding PHY mask bit
extern const uint8_t co_phypwr_value_to_mask[];
/// Convert PHY mask bit of power control to the corresponding PHY rate value
extern const uint8_t co_phypwr_mask_to_value[];
/// Convert PHY rate value of power control to Rate value
extern const uint8_t co_phypwr_to_rate[];
/// Convert Rate value to PHY rate value of power control
extern const uint8_t co_rate_to_phypwr[];
/// Convert Rate value to PHY mask value of power control
extern const uint8_t co_rate_to_phypwr_mask[];
#endif // BLE_PWR_CTRL
/// Convert Rate value to byte duration in us
extern const uint8_t co_rate_to_byte_dur_us[];
/*
* OPERATIONS ON BT CLOCK
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Clocks addition with 2 operands
*
* @param[in] clock_a 1st operand value (in BT half-slots)
* @param[in] clock_b 2nd operand value (in BT half-slots)
* @return result operation result (in BT half-slots)
****************************************************************************************
*/
#define CLK_ADD_2(clock_a, clock_b) ((uint32_t)(((clock_a) + (clock_b)) & RWIP_MAX_CLOCK_TIME))
/**
****************************************************************************************
* @brief Clocks addition with 3 operands
*
* @param[in] clock_a 1st operand value (in BT half-slots)
* @param[in] clock_b 2nd operand value (in BT half-slots)
* @param[in] clock_c 3rd operand value (in BT half-slots)
* @return result operation result (in BT half-slots)
****************************************************************************************
*/
#define CLK_ADD_3(clock_a, clock_b, clock_c) ((uint32_t)(((clock_a) + (clock_b) + (clock_c)) & RWIP_MAX_CLOCK_TIME))
/**
****************************************************************************************
* @brief Clocks subtraction
*
* @param[in] clock_a 1st operand value (in BT half-slots)
* @param[in] clock_b 2nd operand value (in BT half-slots)
* @return result operation result (in BT half-slots)
****************************************************************************************
*/
#define CLK_SUB(clock_a, clock_b) ((uint32_t)(((clock_a) - (clock_b)) & RWIP_MAX_CLOCK_TIME))
/**
****************************************************************************************
* @brief Bluetooth timestamp Clocks subtraction
*
* @param[in] clock_a 1st operand value (in microseconds)
* @param[in] clock_b 2nd operand value (in microseconds)
* @return result operation result (in microseconds)
****************************************************************************************
*/
#define CLK_BTS_SUB(clock_a, clock_b) (((int32_t) ((clock_a) - (clock_b))))
/**
****************************************************************************************
* @brief Check if clock_a is lower than or equal to clock_b
*
* @param[in] clock_a Clock A value (in BT half-slots)
* @param[in] clock_b Clock B value (in BT half-slots)
* @return result True: clock_a lower than or equal to clock_b | False: else
****************************************************************************************
*/
#define CLK_BTS_LOWER_EQ(clock_a, clock_b) (CLK_BTS_SUB(clock_b, clock_a) < (RWIP_MAX_BTS_TIME >> 1))
/**
****************************************************************************************
* @brief Clocks time difference
*
* @param[in] clock_a 1st operand value (in BT half-slots)
* @param[in] clock_b 2nd operand value (in BT half-slots)
* @return result return the time difference from clock A to clock B
* - result < 0 => clock_b is in the past
* - result == 0 => clock_a is equal to clock_b
* - result > 0 => clock_b is in the future
****************************************************************************************
*/
#define CLK_DIFF(clock_a, clock_b) ( (CLK_SUB((clock_b), (clock_a)) > ((RWIP_MAX_CLOCK_TIME+1) >> 1)) ? \
((int32_t)((-CLK_SUB((clock_a), (clock_b))))) : ((int32_t)((CLK_SUB((clock_b), (clock_a))))) )
/// macro to extract a field from a value containing several fields
/// @param[in] __r bit field value
/// @param[in] __f field name
/// @return the value of the register masked and shifted
#define GETF(__r, __f) \
(( (__r) & (__f##_MASK) ) >> (__f##_LSB))
/// macro to set a field value into a value containing several fields.
/// @param[in] __r bit field value
/// @param[in] __f field name
/// @param[in] __v value to put in field
#define SETF(__r, __f, __v) \
do { \
ASSERT_INFO( ( ( ( (__v) << (__f##_LSB) ) & ( ~(__f##_MASK) ) ) ) == 0 ,(__f##_MASK), (__v)); \
__r = (((__r) & ~(__f##_MASK)) | (__v) << (__f##_LSB)); \
} while (0)
/// macro to extract a bit field from a value containing several fields
/// @param[in] __r bit field value
/// @param[in] __b bit field name
/// @return the value of the register masked and shifted
#define GETB(__r, __b) \
(( (__r) & (__b##_BIT) ) >> (__b##_POS))
/// macro to set a bit field value into a value containing several fields.
/// @param[in] __r bit field value
/// @param[in] __b bit field name
/// @param[in] __v value to put in field
#define SETB(__r, __b, __v) \
do { \
ASSERT_ERR( ( ( ( (__v ? 1 : 0) << (__b##_POS) ) & ( ~(__b##_BIT) ) ) ) == 0 ); \
__r = (((__r) & ~(__b##_BIT)) | (__v ? 1 : 0) << (__b##_POS)); \
} while (0)
/// macro to toggle a bit into a value containing several bits.
/// @param[in] __r bit field value
/// @param[in] __b bit field name
#define TOGB(__r, __b) \
do { \
__r = ((__r) ^ (__b##_BIT)); \
} while (0)
/**
****************************************************************************************
* @brief Check if clock_a is equal to clock_b
*
* @param[in] clock_a Clock A value (in BT half-slots)
* @param[in] clock_b Clock B value (in BT half-slots)
* @return result True: clock_a lower than or equal to clock_b | False: else
****************************************************************************************
*/
#define CLK_EQ(clock_a, clock_b) (clock_b == clock_a)
/**
****************************************************************************************
* @brief Check if clock_a is lower than or equal to clock_b
*
* @param[in] clock_a Clock A value (in BT half-slots)
* @param[in] clock_b Clock B value (in BT half-slots)
* @return result True: clock_a lower than or equal to clock_b | False: else
****************************************************************************************
*/
#define CLK_LOWER_EQ(clock_a, clock_b) (CLK_SUB(clock_b, clock_a) < (RWIP_MAX_CLOCK_TIME >> 1))
/**
****************************************************************************************
* @brief Check if clock A is lower than or equal to clock B (with half-us precision)
*
* @param[in] int_a Integer part of clock A (in BT half-slots)
* @param[in] fract_a Fractional part of clock A (in half-us) (range: 0 to 624)
* @param[in] int_b Integer part of clock B (in BT half-slots)
* @param[in] fract_b Fractional part of clock B (in half-us) (range: 0 to 624)
* @return result True: clock A lower than or equal to clock B | False: else
****************************************************************************************
*/
#define CLK_LOWER_EQ_HUS(int_a, fract_a, int_b, fract_b) ( CLK_GREATER_THAN(int_b, int_a) \
|| ( CLK_EQ(int_a, int_b) \
&& (fract_a <= fract_b) ) ) \
/**
****************************************************************************************
* @brief Check if clock_a is greater than clock_b
*
* @param[in] clock_a Clock A value (in BT half-slots)
* @param[in] clock_b Clock B value (in BT half-slots)
* @return result True: clock_a is greater than clock_b | False: else
****************************************************************************************
*/
#define CLK_GREATER_THAN(clock_a, clock_b) !(CLK_LOWER_EQ(clock_a, clock_b))
/**
****************************************************************************************
* @brief Check if clock A is greater than clock B (with half-us precision)
*
* @param[in] int_a Integer part of clock A (in BT half-slots)
* @param[in] fract_a Fractional part of clock A (in half-us) (range: 0 to 624)
* @param[in] int_b Integer part of clock B (in BT half-slots)
* @param[in] fract_b Fractional part of clock B (in half-us) (range: 0 to 624)
* @return result True: clock A greater than clock B | False: else
****************************************************************************************
*/
#define CLK_GREATER_THAN_HUS(int_a, fract_a, int_b, fract_b) ( CLK_GREATER_THAN(int_a, int_b) \
|| ( CLK_EQ(int_a, int_b) \
&& (fract_a > fract_b) ) ) \
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Read an aligned 32 bit word.
* @param[in] ptr32 The address of the first byte of the 32 bit word.
* @return The 32 bit value.
****************************************************************************************
*/
__INLINE uint32_t co_read32(void const *ptr32)
{
return *((uint32_t*)ptr32);
}
/**
****************************************************************************************
* @brief Read an aligned 16 bits word.
* @param[in] ptr16 The address of the first byte of the 16 bits word.
* @return The 16 bits value.
****************************************************************************************
*/
__INLINE uint16_t co_read16(void const *ptr16)
{
return *((uint16_t*)ptr16);
}
/**
****************************************************************************************
* @brief Write an aligned 32 bits word.
* @param[in] ptr32 The address of the first byte of the 32 bits word.
* @param[in] value The value to write.
****************************************************************************************
*/
__INLINE void co_write32(void const *ptr32, uint32_t value)
{
*(uint32_t*)ptr32 = value;
}
/**
****************************************************************************************
* @brief Write an aligned 16 bits word.
* @param[in] ptr16 The address of the first byte of the 16 bits word.
* @param[in] value The value to write.
****************************************************************************************
*/
__INLINE void co_write16(void const *ptr16, uint32_t value)
{
*(uint16_t*)ptr16 = value;
}
/**
****************************************************************************************
* @brief Write a 8 bits word.
* @param[in] ptr8 The address of the first byte of the 8 bits word.
* @param[in] value The value to write.
****************************************************************************************
*/
__INLINE void co_write8(void const *ptr8, uint32_t value)
{
*(uint8_t*)ptr8 = value;
}
/**
****************************************************************************************
* @brief Read a packed 16 bits word.
* @param[in] ptr16 The address of the first byte of the 16 bits word.
* @return The 16 bits value.
****************************************************************************************
*/
__INLINE uint16_t co_read16p(void const *ptr16)
{
uint16_t value = ((uint8_t *)ptr16)[0] | ((uint8_t *)ptr16)[1] << 8;
return value;
}
/**
****************************************************************************************
* @brief Read a packed 24 bits word.
* @param[in] ptr24 The address of the first byte of the 24 bits word.
* @return The 24 bits value.
****************************************************************************************
*/
__INLINE uint32_t co_read24p(void const *ptr24)
{
uint16_t addr_l, addr_h;
addr_l = co_read16p(ptr24);
addr_h = *((uint8_t *)ptr24 + 2) & 0x00FF;
return ((uint32_t)addr_l | (uint32_t)addr_h << 16);
}
/**
****************************************************************************************
* @brief Write a packed 24 bits word.
* @param[in] ptr24 The address of the first byte of the 24 bits word.
* @param[in] value The value to write.
****************************************************************************************
*/
__INLINE void co_write24p(void const *ptr24, uint32_t value)
{
uint8_t *ptr=(uint8_t*)ptr24;
*ptr++ = (uint8_t)(value&0xff);
*ptr++ = (uint8_t)((value&0xff00)>>8);
*ptr++ = (uint8_t)((value&0xff0000)>>16);
}
/**
****************************************************************************************
* @brief Read a packed 32 bits word.
* @param[in] ptr32 The address of the first byte of the 32 bits word.
* @return The 32 bits value.
****************************************************************************************
*/
__INLINE uint32_t co_read32p(void const *ptr32)
{
uint16_t addr_l, addr_h;
addr_l = co_read16p(ptr32);
addr_h = co_read16p((uint8_t *)ptr32 + 2);
return ((uint32_t)addr_l | (uint32_t)addr_h << 16);
}
/**
****************************************************************************************
* @brief Write a packed 32 bits word.
* @param[in] ptr32 The address of the first byte of the 32 bits word.
* @param[in] value The value to write.
****************************************************************************************
*/
__INLINE void co_write32p(void const *ptr32, uint32_t value)
{
uint8_t *ptr=(uint8_t*)ptr32;
*ptr++ = (uint8_t)(value&0xff);
*ptr++ = (uint8_t)((value&0xff00)>>8);
*ptr++ = (uint8_t)((value&0xff0000)>>16);
*ptr = (uint8_t)((value&0xff000000)>>24);
}
/**
****************************************************************************************
* @brief Write a packed 16 bits word.
* @param[in] ptr16 The address of the first byte of the 16 bits word.
* @param[in] value The value to write.
****************************************************************************************
*/
__INLINE void co_write16p(void const *ptr16, uint16_t value)
{
uint8_t *ptr=(uint8_t*)ptr16;
*ptr++ = value&0xff;
*ptr = (value&0xff00)>>8;
}
/**
****************************************************************************************
* Count number of bit set to 1 in a value with variable length
*
* @param[in] p_val Pointer to value
* @param[in] size Number of Bytes
* @return Number of bit counted
****************************************************************************************
*/
__INLINE uint8_t co_bit_cnt(const uint8_t* p_val, uint8_t size)
{
uint8_t nb_bit = 0;
while(size-- > 0)
{
nb_bit += NB_ONE_BITS(*p_val);
p_val++;
}
return (nb_bit);
}
#if (RW_DEBUG || DISPLAY_SUPPORT)
/**
****************************************************************************************
* @brief Convert bytes to hexadecimal string
*
* @param[out] dest Pointer to the destination string (must be 2x longer than input table)
* @param[in] src Pointer to the bytes table
* @param[in] nb_bytes Number of bytes to display in the string
****************************************************************************************
*/
void co_bytes_to_string(char* dest, uint8_t* src, uint8_t nb_bytes);
#endif //(RW_DEBUG || DISPLAY_SUPPORT)
/**
****************************************************************************************
* @brief Compares two Bluetooth device addresses
*
* This function checks if the two bd address are equal.
*
* @param[in] bd_address1 Pointer on the first bd address to be compared.
* @param[in] bd_address2 Pointer on the second bd address to be compared.
*
* @return result of the comparison (true: equal | false: different).
****************************************************************************************
*/
bool co_bdaddr_compare(struct bd_addr const *bd_address1, struct bd_addr const *bd_address2);
#if (BT_EMB_PRESENT)
/**
******************************************************************************
* @brief Convert an duration in baseband slot to a duration in number of ticks.
* @param[in] slot_cnt Duration in number of baseband slot
* @return Duration (in number of ticks).
******************************************************************************
*/
uint32_t co_slot_to_duration(uint32_t slot_cnt);
/**
******************************************************************************
* @brief Count the number of good channels in a map
* @param[in] map Channel Map (bit fields for the 79 BT RF channels)
* @return Number of good channels
******************************************************************************
*/
uint8_t co_nb_good_channels(const struct chnl_map* map);
#endif //BT_EMB_PRESENT
/**
****************************************************************************************
* @brief Pack parameters from a C structure to a packed buffer
*
* This function packs parameters according to a specific format. It takes care of the
* endianess, padding, required by the compiler.
*
* By default output format is LSB but it can be changed with first character of format string
* - < : LSB output format
* - > : MSB output format
*
* Format strings are the mechanism used to specify the expected layout when packing and unpacking data. They are built
* up from Format Characters, which specify the type of data being packed/unpacked.
* - B : byte - 8bits value
* - H : word - 16bits value
* - L : long - 32-bits value
* - D : 24 bits value
* - XXB: table of several bytes, where XX is the byte number, in decimal
* - XXG: Number of several bytes, where XX is the byte number, in decimal - subject to be swapped according to endianess
* - nB : table size over 1 byte, followed by the table of bytes
* - NB : table size over 2 bytes, followed by the table of bytes
*
* Example: "BBLH12BLnB" => 1 byte | 1 byte | 1 long | 1 short | 12-bytes table | 1 long | table size over 1 byte | n-bytes table
*
* Note: the function works in the same buffer
*
* @param[out] out Output Data Buffer
* @param[in] in Input Data Buffer
* @param[out] out_len Output size of packed data (in bytes)
* @param[in] in_len Input buffer size (in bytes)
* @param[in] format Parameters format
*
* @return Status of the packing operation
*****************************************************************************************
*/
uint8_t co_util_pack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format);
/**
****************************************************************************************
* @brief Unpack parameters from an unpacked buffer to a C structure
*
* This function unpacks parameters according to a specific format. It takes care of the
* endianess, padding, required by the compiler.
*
* By default input format is LSB but it can be changed with first character of format string
* - < : LSB input format
* - > : MSB input format
*
* Format strings are the mechanism used to specify the expected layout when packing and unpacking data. They are built
* up from Format Characters, which specify the type of data being packed/unpacked.
* - B : byte - 8bits value
* - H : word - 16bits value
* - L : long - 32-bits value
* - D : 24 bits value
* - XXB: table of several bytes, where XX is the byte number, in decimal
* - XXG: Number of several bytes, where XX is the byte number, in decimal - subject to be swapped according to endianess
* - nB : table size over 1 byte, followed by the table of bytes
* - NB : table size over 2 bytes, followed by the table of bytes
*
* Example: "BBLH12BLnB" => 1 byte | 1 byte | 1 long | 1 short | 12-bytes table | 1 long | table size over 1 byte | n-bytes table
*
* Note: the output buffer provided must be large enough to contain the unpacked data.
* Note2: if a NULL output buffer is provided, the function does not copy the unpacked parameters. It still parses the
* format string and input buffer to return the number of unpacked bytes. Can be used to compute the expected unpacked
* buffer size.
*
* @param[out] out Unpacked parameters buffer
* @param[in] in Packed parameters buffer
* @param[inout] out_len Input: buffer size / Output: size of unpacked data (in bytes)
* @param[in] in_len Size of the packed data (in bytes)
* @param[in] format Parameters format
*
* @return Status of the unpacking operation
*****************************************************************************************
*/
uint8_t co_util_unpack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format);
// void set_ble_mac_addr(struct bd_addr* addr);
// struct bd_addr* get_ble_mac_addr(void);
/// @} CO_UTILS
#endif // _CO_UTILS_H_
@@ -0,0 +1,46 @@
/**
****************************************************************************************
*
* @file co_version.h
*
* @brief Version definitions for BT5.1
*
* Copyright (C) RivieraWaves 2009-2018
*
*
****************************************************************************************
*/
#ifndef _CO_VERSION_H_
#define _CO_VERSION_H_
/**
****************************************************************************************
* @defgroup CO_VERSION Version Defines
* @ingroup COMMON
*
* @brief Bluetooth Controller Version definitions.
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "co_bt.h" // BT standard definitions
/// RWBT SW Major Version
#define RWBT_SW_VERSION_MAJOR (BT52_VERSION)
/// RWBT SW Minor Version
#define RWBT_SW_VERSION_MINOR 0
/// RWBT SW Build Version
#define RWBT_SW_VERSION_BUILD 4
/// RWBT SW Major Version
#define RWBT_SW_VERSION_SUB_BUILD 0
/// @} CO_VERSION
#endif // _CO_VERSION_H_