openmv/lib/stai/libstai/include/ll_aton_NN_interface.h
iabdalkader e95a19c963 lib: Add STAI library and ML backend.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2025-06-10 11:53:31 +02:00

613 lines
27 KiB
C

/**
******************************************************************************
* @file ll_aton_NN_interface.h
* @author SRA Artificial Intelligence & Embedded Architectures
* @brief Interface that defines a NN generated by the AtoNN Compiler.
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#ifndef __LL_ATON_NN_INTERFACE_H
#define __LL_ATON_NN_INTERFACE_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "ll_aton_config.h"
#include "ll_aton_attributes.h"
#include "ll_aton_util.h"
/* this is needed to avoid some compilers (e.g. KEIL) that observe a strict semantic about conversion of
* pointers to integers in cost initializers
*/
typedef union
{
unsigned char *p;
uintptr_t i;
} __LL_address_t;
typedef void (*EpochBlock_FuncPtr_t)(const void *epoch_block);
typedef enum LL_ATON_RT_RetValues
{
LL_ATON_RT_NO_WFE = 0,
LL_ATON_RT_WFE,
LL_ATON_RT_DONE,
} LL_ATON_RT_RetValues_t;
typedef enum LL_ATON_RT_Callbacktype
{
LL_ATON_RT_Callbacktype_PRE_START, /**< Callback called before start_epoch_block */
LL_ATON_RT_Callbacktype_POST_START, /**< Callback called after start_epoch_block */
LL_ATON_RT_Callbacktype_PRE_END, /**< Callback called before end_epoch_block */
LL_ATON_RT_Callbacktype_POST_END, /**< Callback called after end_epoch_block */
LL_ATON_RT_Callbacktype_NN_Init, /**< Callback called after `LL_ATON_RT_Init_Network`,
* NOTE: 3rd parameter passed is `NULL` */
LL_ATON_RT_Callbacktype_NN_DeInit, /**< Callback called after `LL_ATON_RT_DeInit_Network`,
* NOTE: 3rd parameter passed is `NULL` */
LL_ATON_RT_Callbacktype_RT_Init, /**< Callback called after `LL_ATON_RT_RuntimeInit` */
LL_ATON_RT_Callbacktype_RT_Deinit, /**< Callback called before `LL_ATON_RT_RuntimeDeInit` */
} LL_ATON_RT_Callbacktype_t;
typedef enum LL_ATON_User_IO_Result
{
LL_ATON_User_IO_NOERROR, /**< */
LL_ATON_User_IO_WRONG_ALIGN, /**< */
LL_ATON_User_IO_WRONG_SIZE, /**< */
LL_ATON_User_IO_WRONG_INDEX, /**< */
} LL_ATON_User_IO_Result_t;
typedef enum
{
EpochBlock_Flags_NONE = 0x0, /**< */
EpochBlock_Flags_epoch_start = (0x1 << 0), /**< First EpochBlock of an Epoch */
EpochBlock_Flags_epoch_end = (0x1 << 1), /**< Last EpochBlock of an Epoch */
EpochBlock_Flags_blob = (0x1 << 2), /**< Item is an Epoch Blob */
EpochBlock_Flags_last_eb = (0x1 << 3), /**< Last EpochBlock */
EpochBlock_Flags_pure_hw = (0x1 << 4), /**< Pure HW EpochBlock */
EpochBlock_Flags_pure_sw = (0x1 << 5), /**< Pure SW EpochBlock */
EpochBlock_Flags_hybrid = (0x1 << 6), /**< Hybrid EpochBlock (i.e. mixed HW/SW) */
EpochBlock_Flags_internal = (0x1 << 7), /**< ATON lib internal EpochBlock (used to implement hybrid epochs) */
} EpochBlock_Flags_t;
typedef struct
{
EpochBlock_FuncPtr_t start_epoch_block; /**< Method to execute the EpochBlock */
EpochBlock_FuncPtr_t end_epoch_block; /**< Method to be executed when the EpochBlock ends */
uintptr_t blob_address; /**< Blob address (in case this EpochBlock represents an epoch blob) */
uint32_t wait_mask; /**< Mask needed to check when an EpochBlock ends
* - if epoch blob: number (not bitmask) of epoch controller unit to use
* - otherwise: bitmask with all output streaming engines to wait for before ending epoch */
uint16_t flags; /**< EpochBlock flags */
#ifdef LL_ATON_EB_DBG_INFO
int16_t epoch_num; /**< Epoch number / First epoch number within blob */
int16_t last_epoch_num; /**< Epoch number / Last epoch number within blob */
uint32_t in_streng_mask; /**< Debug information about input streaming engines used in epoch */
uint32_t out_streng_mask; /**< Debug information about output streaming engines used in epoch */
uint64_t estimated_npu_cycles; /**< Debug information estimates for NPU cycles in epoch w/o memory penalty */
uint64_t estimated_tot_cycles; /**< Debug information estimates for NPU cycles in epoch w/ memory penalty */
#endif // LL_ATON_EB_DBG_INFO
} EpochBlock_ItemTypeDef;
/**
* @brief Checks if the pointed element is the last one of an array of `const EpochBlock_ItemTypeDef`
*
*/
static inline bool EpochBlock_IsLastEpochBlock(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Checks if the pointed element is the first EpochBlock of an Epoch
*
*/
static inline bool EpochBlock_IsEpochStart(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Checks if the pointed element is the last EpochBlock of an Epoch
*
*/
static inline bool EpochBlock_IsEpochEnd(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Checks if the pointed element is the an Epoch Blob
*
*/
static inline bool EpochBlock_IsEpochBlob(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Checks if the pointed element is pure SW epoch
*
*/
static inline bool EpochBlock_IsEpochPureSW(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Checks if the pointed element is a pure HW or mixed SW/HW epoch
*
*/
static inline bool EpochBlock_IsEpochPureHW(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Checks if the pointed element is a hybrid epoch
*
*/
static inline bool EpochBlock_IsEpochHybrid(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Checks if the pointed element is an internal epoch
*
*/
static inline bool EpochBlock_IsEpochInternal(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Returns the Epoch controller id to use
*
*/
static inline uint32_t EpochBlock_EpochControllerUnit(const EpochBlock_ItemTypeDef *eb);
/**
* @brief Returns the address of the configuration of the epoch controller (the blob address)
*
*/
static inline uintptr_t EpochBlock_EpochBlobAddr(const EpochBlock_ItemTypeDef *eb);
/**
* @brief ATON buffer types definition
*/
typedef enum
{
DataType_UNDEFINED = 0,
DataType_FLOAT = 1,
DataType_UINT8 = 2,
DataType_INT8 = 3,
DataType_UINT16 = 4,
DataType_INT16 = 5,
DataType_INT32 = 6,
DataType_INT64 = 7,
DataType_STRING = 8,
DataType_BOOL = 9,
DataType_FLOAT16 = 10,
DataType_DOUBLE = 11,
DataType_UINT32 = 12,
DataType_UINT64 = 13,
DataType_COMPLEX64 = 14,
DataType_COMPLEX128 = 15,
DataType_BFLOAT16 = 16,
DataType_FXP = 100 // AtoNN specific
} Buffer_DataType_TypeDef;
/**
* @brief ATON buffer Channel position
*/
typedef enum
{
CHPos_UNDEFINED = 0, /**< No channel present */
CHPos_First = 1, /**< Channel First ( ...B C H W )*/
CHPos_Last = 2, /**< Channel Last ( ...B H W C ) */
CHPos_Mixed = 3, /**< Channel with Batch(b) ( ...B C/b H W b ) */
} Buffer_CHPos_TypeDef;
/**
* @brief ATON buffer definition
*/
typedef struct
{
const char *name; /**< Buffer name. NULL if end of list */
__LL_address_t addr_base; /**< Buffer base address */
uint32_t offset_start; /**< Offset of the buffer start address from the base address */
uint32_t offset_end; /**< Offset of the buffer end address from the base address
* (first bytes address beyond buffer length) */
uint32_t offset_limit; /**< Offset of the limiter address from the base address,
* (needed for configuring streaming engines) */
uint8_t is_user_allocated; /**< */
uint8_t is_param; /**< */
uint16_t epoch; /**< */
uint32_t batch; /**< */
const uint32_t *mem_shape; /**< shape as seen by the user in memory (only valid for input/output buffers) */
uint16_t mem_ndims; /**< Number of dimensions of mem_shape (Length of mem_shape) */
Buffer_CHPos_TypeDef chpos; /**< Position of channels dimension in mem shape */
Buffer_DataType_TypeDef type; /**< */
int8_t Qm; /**< */
int8_t Qn; /**< */
uint8_t Qunsigned; /**< */
uint8_t ndims; /**< */
uint8_t nbits; /**< */
uint8_t per_channel; /**< */
const uint32_t *shape; /**< */
const float *scale; /**< */
const int16_t *offset; /**< This can become int8 or uint8 based on the Qunsigned field.
* (This field Must have the same format of the quantized value) */
} LL_Buffer_InfoTypeDef;
/**
* @brief returns the base address of the mem pool the buffer is allocated in
*
*/
static inline unsigned char *LL_Buffer_addr_base(const LL_Buffer_InfoTypeDef *buf);
/**
* @brief returns the start address of the buffer
*
*/
static inline unsigned char *LL_Buffer_addr_start(const LL_Buffer_InfoTypeDef *buf);
/**
* @brief returns the end address of the buffer
*
*/
static inline unsigned char *LL_Buffer_addr_end(const LL_Buffer_InfoTypeDef *buf);
/**
* @brief returns the limit address of the buffer
*
*/
static inline unsigned char *LL_Buffer_addr_limit(const LL_Buffer_InfoTypeDef *buf);
/**
* @brief returns the length of the buffer
*
*/
static inline uint32_t LL_Buffer_len(const LL_Buffer_InfoTypeDef *buf);
/**
* @brief returns the buffer elements number of bits
*
*/
static inline uint32_t LL_Buffer_bits(const LL_Buffer_InfoTypeDef *buf);
/** @defgroup ATONN_COMPILER Functions autogenerated by the AtoNN compiler
* @{
*/
/**
* @brief Initialize a Network internal structures for the Epoch Controller
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @retval returns if the action succeded or an error occured
*/
extern bool LL_ATON_EC_Network_Init_Default(void);
/**
* @brief Update a Network internal structures for the Epoch Controller before the execution of an Inference
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @retval returns if the action succeded or an error occured
*/
extern bool LL_ATON_EC_Inference_Init_Default(void);
/**
* @brief Sets user allocated inputs (one at a time)
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @param num zero base index of the input buffer to set
* @param buffer pointer to the area used to store this input
* @param size size of the memory reserved for this input
*/
extern LL_ATON_User_IO_Result_t LL_ATON_Set_User_Input_Buffer_Default(uint32_t num, void *buffer, uint32_t size);
/**
* @brief Gets user allocated inputs (one at a time)
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @param num zero base index of the input buffer to get
* @retval returns a pointer to the specified user allocated input
*/
extern void *LL_ATON_Get_User_Input_Buffer_Default(uint32_t num);
/**
* @brief Sets user allocated outputs (one at a time)
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @param num zero base index of the output buffer to set
* @param buffer pointer to the area used to store this output
* @param size size of the memory reserved for this output
*/
extern LL_ATON_User_IO_Result_t LL_ATON_Set_User_Output_Buffer_Default(uint32_t num, void *buffer, uint32_t size);
/**
* @brief Gets user allocated inputs (one at a time)
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @param num zero base index of the output buffer to get
* @retval returns a pointer to the specified user allocated output
*/
extern void *LL_ATON_Get_User_Output_Buffer_Default(uint32_t num);
/**
* @brief Returns an array of structures describing the epoch blocks of the NN to execute
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @retval returns a pointer to an array of `const EpochBlock_ItemTypeDef`,
* if `flags` contain `EpochBlock_Flags_last_eb` identifies the last (empty) EpochBlock (i.e. we are done)
* (see helper function `EpochBlock_IsLastEpochBlock()`)
*/
extern const EpochBlock_ItemTypeDef *LL_ATON_EpochBlockItems_Default(void);
/**
* @brief Returns an array of structures describing input buffers
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @retval returns a pointer to the array of LL_Buffer_InfoTypeDef, name is NULL for the last one
*/
extern const LL_Buffer_InfoTypeDef *LL_ATON_Output_Buffers_Info_Default(void);
/**
* @brief Returns an array of structures describing output buffers
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @retval Returns a pointer to the array of LL_Buffer_InfoTypeDef, name is NULL for the last one
*/
extern const LL_Buffer_InfoTypeDef *LL_ATON_Input_Buffers_Info_Default(void);
/**
* @brief Returns an array of structures describing epoch output transient buffers
* @note This function is generated by the AtoNN compiler when called without a network name
* (i.e. without option `--network-name`)
* @note Use macro `LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name)` instead when the network has been generated
* (by the AtoNN compiler) with a network name (i.e. with option `--network-name`)
* @retval Returns a pointer to the array of LL_Buffer_InfoTypeDef, name is NULL for the last one
*/
extern const LL_Buffer_InfoTypeDef *LL_ATON_Internal_Buffers_Info_Default(void);
/**
* @brief Declare the function prototypes for named NN interface functions generated by the AtoNN compiler
* @param network_name name of the network as provided by option `--network-name`
*/
#define LL_ATON_DECLARE_NAMED_NN_PROTOS(network_name) \
extern bool LL_ATON_EC_Network_Init_##network_name(void); \
extern bool LL_ATON_EC_Inference_Init_##network_name(void); \
extern LL_ATON_User_IO_Result_t LL_ATON_Set_User_Input_Buffer_##network_name(uint32_t num, void *buffer, \
uint32_t size); \
extern void *LL_ATON_Get_User_Input_Buffer_##network_name(uint32_t num); \
extern LL_ATON_User_IO_Result_t LL_ATON_Set_User_Output_Buffer_##network_name(uint32_t num, void *buffer, \
uint32_t size); \
extern void *LL_ATON_Get_User_Output_Buffer_##network_name(uint32_t num); \
extern const EpochBlock_ItemTypeDef *LL_ATON_EpochBlockItems_##network_name(void); \
extern const LL_Buffer_InfoTypeDef *LL_ATON_Output_Buffers_Info_##network_name(void); \
extern const LL_Buffer_InfoTypeDef *LL_ATON_Input_Buffers_Info_##network_name(void); \
extern const LL_Buffer_InfoTypeDef *LL_ATON_Internal_Buffers_Info_##network_name(void);
/**
* @brief Type definitions for NN interface functions
*/
typedef bool (*NN_EC_Hook_TypeDef)(void);
typedef LL_ATON_User_IO_Result_t (*NN_InputSetter_TypeDef)(uint32_t num, void *buffer, uint32_t size);
typedef void *(*NN_InputGetter_TypeDef)(uint32_t num);
typedef LL_ATON_User_IO_Result_t (*NN_OutputSetter_TypeDef)(uint32_t num, void *buffer, uint32_t size);
typedef void *(*NN_OutputGetter_TypeDef)(uint32_t num);
typedef const EpochBlock_ItemTypeDef *(*NN_EpochBlockItems_TypeDef)(void);
typedef const LL_Buffer_InfoTypeDef *(*NN_Buffers_Info_TypeDef)(void);
typedef void (*TraceRuntime_FuncPtr_t)(LL_ATON_RT_Callbacktype_t ctype);
struct __nn_instance_struct; // forward declaration
typedef struct __nn_instance_struct NN_Instance_TypeDef;
typedef void (*TraceEpochBlock_FuncPtr_t)(LL_ATON_RT_Callbacktype_t ctype, const NN_Instance_TypeDef *nn_instance,
const EpochBlock_ItemTypeDef *epoch_block);
typedef struct
{
const char *network_name;
NN_EC_Hook_TypeDef ec_network_init;
NN_EC_Hook_TypeDef ec_inference_init;
NN_InputSetter_TypeDef input_setter;
NN_InputGetter_TypeDef input_getter;
NN_OutputSetter_TypeDef output_setter;
NN_OutputGetter_TypeDef output_getter;
NN_EpochBlockItems_TypeDef epoch_block_items;
NN_Buffers_Info_TypeDef output_buffers_info;
NN_Buffers_Info_TypeDef input_buffers_info;
NN_Buffers_Info_TypeDef internal_buffers_info;
} NN_Interface_TypeDef;
typedef struct
{
const EpochBlock_ItemTypeDef *volatile current_epoch_block; // pointer to current epoch block
const EpochBlock_ItemTypeDef *volatile first_epoch_block; // pointer to first epoch block in current epoch list
const EpochBlock_ItemTypeDef *volatile next_epoch_block; // pointer to epoch block to be inserted
const EpochBlock_ItemTypeDef *volatile saved_current_epoch_block; // pointer to saved current epoch list
const EpochBlock_ItemTypeDef
*volatile saved_first_epoch_block; // pointer to saved first epoch block in current epoch list
bool inference_started; // inference has been started
#if (LL_ATON_RT_MODE == LL_ATON_RT_ASYNC)
volatile uint32_t triggered_events; // currently triggered events/IRQs in current epoch
volatile bool current_epoch_block_started; // has current epoch block already been started
#endif // (LL_ATON_RT_MODE == LL_ATON_RT_ASYNC)
#ifndef NDEBUG
volatile uint32_t
nr_of_epoch_blocks; // number of epoch blocks in network (includes also terminating empty epoch block)
volatile uint32_t saved_nr_of_epoch_blocks; // number of epoch blocks in saved network (includes also terminating
// empty epoch block)
#endif // NDEBUG
TraceEpochBlock_FuncPtr_t epoch_callback_function; // epoch callback function
#if defined(LL_ATON_RT_RELOC)
uint32_t inst_reloc;
#endif
} NN_Execution_State_TypeDef;
struct __nn_instance_struct
{
const NN_Interface_TypeDef *network;
NN_Execution_State_TypeDef exec_state;
};
/**
* @brief Declare and fill a constant named NN interface object
* @param nn_if_name name of the network as provided by option `--network-name`
*/
#define LL_ATON_DECLARE_NAMED_NN_INTERFACE(nn_if_name) \
LL_ATON_DECLARE_NAMED_NN_PROTOS(nn_if_name); \
\
static const NN_Interface_TypeDef NN_Interface_##nn_if_name = { \
.network_name = #nn_if_name, \
.ec_network_init = &LL_ATON_EC_Network_Init_##nn_if_name, \
.ec_inference_init = &LL_ATON_EC_Inference_Init_##nn_if_name, \
.input_setter = &LL_ATON_Set_User_Input_Buffer_##nn_if_name, \
.input_getter = &LL_ATON_Get_User_Input_Buffer_##nn_if_name, \
.output_setter = &LL_ATON_Set_User_Output_Buffer_##nn_if_name, \
.output_getter = &LL_ATON_Get_User_Output_Buffer_##nn_if_name, \
.epoch_block_items = &LL_ATON_EpochBlockItems_##nn_if_name, \
.output_buffers_info = &LL_ATON_Output_Buffers_Info_##nn_if_name, \
.input_buffers_info = &LL_ATON_Input_Buffers_Info_##nn_if_name, \
.internal_buffers_info = &LL_ATON_Internal_Buffers_Info_##nn_if_name}
/**
* @brief Declare and fill a non-constant named NN execution instance
* @param nn_exec_name typically name of the network as provided by option `--network-name`
* @param _nn_if_name pointer to network interface
*/
#define LL_ATON_DECLARE_NAMED_NN_INSTANCE(nn_exec_name, _nn_if_name) \
static NN_Instance_TypeDef NN_Instance_##nn_exec_name = {.network = _nn_if_name, .exec_state = {0}}
/**
* @brief Declare and fill a non-constant named NN execution instance and constant network interface,
* which get linked together (by this macro).
* @param nn_name name of the network as provided by option `--network-name`
*/
#define LL_ATON_DECLARE_NAMED_NN_INSTANCE_AND_INTERFACE(nn_name) \
LL_ATON_DECLARE_NAMED_NN_INTERFACE(nn_name); \
LL_ATON_DECLARE_NAMED_NN_INSTANCE(nn_name, &NN_Interface_##nn_name);
/**
* @}
*/
static inline bool EpochBlock_IsLastEpochBlock(const EpochBlock_ItemTypeDef *eb)
{
return ((eb->flags & EpochBlock_Flags_last_eb) != 0);
}
static inline bool EpochBlock_IsEpochStart(const EpochBlock_ItemTypeDef *eb)
{
return ((eb->flags & EpochBlock_Flags_epoch_start) != 0);
}
static inline bool EpochBlock_IsEpochEnd(const EpochBlock_ItemTypeDef *eb)
{
return ((eb->flags & EpochBlock_Flags_epoch_end) != 0);
}
static inline bool EpochBlock_IsEpochBlob(const EpochBlock_ItemTypeDef *eb)
{
return ((eb->flags & EpochBlock_Flags_blob) != 0);
}
static inline bool EpochBlock_IsEpochPureSW(const EpochBlock_ItemTypeDef *eb)
{
return ((eb->flags & EpochBlock_Flags_pure_sw) != 0);
}
static inline bool EpochBlock_IsEpochPureHW(const EpochBlock_ItemTypeDef *eb)
{
return ((eb->flags & EpochBlock_Flags_pure_hw) != 0);
}
static inline bool EpochBlock_IsEpochHybrid(const EpochBlock_ItemTypeDef *eb)
{
return ((eb->flags & EpochBlock_Flags_hybrid) != 0);
}
static inline bool EpochBlock_IsEpochInternal(const EpochBlock_ItemTypeDef *eb)
{
return ((eb->flags & EpochBlock_Flags_internal) != 0);
}
static inline uint32_t EpochBlock_EpochControllerUnit(const EpochBlock_ItemTypeDef *eb)
{
LL_ATON_ASSERT(EpochBlock_IsEpochBlob(eb));
return eb->wait_mask;
}
static inline uintptr_t EpochBlock_EpochBlobAddr(const EpochBlock_ItemTypeDef *eb)
{
LL_ATON_ASSERT(EpochBlock_IsEpochBlob(eb));
return eb->blob_address;
}
static inline unsigned char *LL_Buffer_addr_base(const LL_Buffer_InfoTypeDef *buf)
{
if (buf->is_user_allocated)
{
unsigned char **tmp = (unsigned char **)buf->addr_base.p;
return *tmp;
}
return buf->addr_base.p;
}
static inline unsigned char *LL_Buffer_addr_start(const LL_Buffer_InfoTypeDef *buf)
{
return LL_Buffer_addr_base(buf) + buf->offset_start;
}
static inline unsigned char *LL_Buffer_addr_end(const LL_Buffer_InfoTypeDef *buf)
{
return LL_Buffer_addr_base(buf) + buf->offset_end;
}
static inline unsigned char *LL_Buffer_addr_limit(const LL_Buffer_InfoTypeDef *buf)
{
return LL_Buffer_addr_base(buf) + buf->offset_limit;
}
static inline uint32_t LL_Buffer_len(const LL_Buffer_InfoTypeDef *buf)
{
return buf->offset_end - buf->offset_start;
}
static inline uint32_t LL_Buffer_bits(const LL_Buffer_InfoTypeDef *buf)
{
return buf->Qm + buf->Qn + (buf->Qunsigned ? 0 : 1);
}
#ifdef __cplusplus
}
#endif
#endif
/**
* @}
*/