demo工程暂存 优化菜单界面UI和功能
This commit is contained in:
301
MCU/components/modules/common/include/co_list.h
Normal file
301
MCU/components/modules/common/include/co_list.h
Normal file
@ -0,0 +1,301 @@
|
||||
#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 "fr30xx.h"
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
///list type
|
||||
enum
|
||||
{
|
||||
POOL_LINKED_LIST = 0x00,
|
||||
RING_LINKED_LIST,
|
||||
LINK_TYPE_END
|
||||
};
|
||||
|
||||
/// 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;
|
||||
};
|
||||
|
||||
/// 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 Initialize a pool to default values, and initialize the relative free list.
|
||||
*
|
||||
* @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
|
||||
* @param elmt_cnt Nb of elements available in the pool
|
||||
* @param default_value Pointer to the default value of each element (may be NULL)
|
||||
* @param list_type Determine if the it is a ring list or not
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_pool_init(struct co_list *list,
|
||||
void *pool,
|
||||
size_t elmt_size,
|
||||
uint32_t elmt_cnt,
|
||||
void *default_value,
|
||||
uint8_t list_type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @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 Extract the second 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
|
||||
*** or only have one entry.
|
||||
****************************************************************************************
|
||||
*/
|
||||
struct co_list_hdr *co_list_pop_subfront(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.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC_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.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC_INLINE struct co_list_hdr *co_list_pick(const struct co_list *const list)
|
||||
{
|
||||
return(list->first);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Return following element of a list element.
|
||||
*
|
||||
* @param list_hdr Pointer to the list element.
|
||||
*
|
||||
* @return The pointer to the next element.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC_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_
|
65
MCU/components/modules/common/include/co_log.h
Normal file
65
MCU/components/modules/common/include/co_log.h
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef _CO_LOG_H
|
||||
#define _CO_LOG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define LOG_LEVEL_NONE (0) /*!< No log output */
|
||||
#define LOG_LEVEL_ERROR (1) /*!< Critical errors, software module can not recover on its own */
|
||||
#define LOG_LEVEL_WARNING (2) /*!< Error conditions from which recovery measures have been taken */
|
||||
#define LOG_LEVEL_INFO (3) /*!< Information messages which describe normal flow of events */
|
||||
#define LOG_LEVEL_DEBUG (4) /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
|
||||
#define LOG_LEVEL_VERBOSE (5) /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */
|
||||
|
||||
#ifndef LOG_LOCAL_LEVEL
|
||||
#define LOG_LOCAL_LEVEL LOG_LEVEL_NONE
|
||||
#endif
|
||||
|
||||
#ifdef LOG_ENABLE
|
||||
#define LOG_ERR(tag, ...) do { \
|
||||
if(LOG_LOCAL_LEVEL >= LOG_LEVEL_ERROR) { \
|
||||
log_printf_level("[ERR] "); \
|
||||
log_printf(tag,__FILE__, __LINE__,##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
#define LOG_WARN(tag, ...) do { \
|
||||
if(LOG_LOCAL_LEVEL >= LOG_LEVEL_WARNING) { \
|
||||
log_printf_level("[WARN] "); \
|
||||
log_printf(tag,__FILE__, __LINE__,##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
#define LOG_INFO(tag, ...) do { \
|
||||
if(LOG_LOCAL_LEVEL >= LOG_LEVEL_INFO) { \
|
||||
log_printf_level("[INFO] "); \
|
||||
log_printf(tag,__FILE__, __LINE__,##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
#define LOG_DBG(tag, ...) do { \
|
||||
if(LOG_LOCAL_LEVEL >= LOG_LEVEL_DEBUG) { \
|
||||
log_printf_level("[DBG] "); \
|
||||
log_printf(tag,__FILE__, __LINE__,##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
#define LOG_V(tag, ...) do { \
|
||||
if(LOG_LOCAL_LEVEL >= LOG_LEVEL_VERBOSE) { \
|
||||
log_printf_level("[V] "); \
|
||||
log_printf(tag,__FILE__, __LINE__,##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define LOG_ERR(tag, ...)
|
||||
#define LOG_WARN(tag, ...)
|
||||
#define LOG_INFO(tag, ...)
|
||||
#define LOG_DBG(tag, ...)
|
||||
#define LOG_V(tag, ...)
|
||||
#endif
|
||||
|
||||
void log_printf_level(const char *level);
|
||||
|
||||
void log_printf(const char* tag,
|
||||
const char* file_name,
|
||||
uint32_t line,
|
||||
const char *format, ...);
|
||||
|
||||
#endif // _CO_LOG_H
|
||||
|
288
MCU/components/modules/common/include/co_math.h
Normal file
288
MCU/components/modules/common/include/co_math.h
Normal file
@ -0,0 +1,288 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 "fr30xx.h"
|
||||
|
||||
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 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))
|
||||
|
||||
|
||||
/*
|
||||
* 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 0
|
||||
#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__)
|
||||
#else
|
||||
uint32_t i;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (val & CO_BIT(i))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to initialize the random seed.
|
||||
* @param[in] seed The seed number to use to generate the random sequence.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_random_init(uint32_t seed)
|
||||
{
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to get an 8 bit random number.
|
||||
* @return Random byte value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE 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.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_rand_hword(void)
|
||||
{
|
||||
return (uint16_t)(rand() & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to get an 32 bit random number.
|
||||
* @return Random word value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE 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 ? val*(-1) : val;
|
||||
}
|
||||
|
||||
/// @} CO_MATH
|
||||
|
||||
|
||||
#endif // _CO_MATH_H_
|
14
MCU/components/modules/common/include/co_util.h
Normal file
14
MCU/components/modules/common/include/co_util.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef _CO_UTIL_H
|
||||
#define _CO_UTIL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int ascii_strn2val( const char str[], char base, char n);
|
||||
|
||||
void co_delay_100us(uint32_t count);
|
||||
void co_delay_10us(uint32_t count);
|
||||
|
||||
void mul_64(uint32_t *low, uint32_t *high, uint32_t mul1, uint32_t mul2);
|
||||
uint32_t simple_div_64(uint32_t low, uint32_t high, uint32_t div);
|
||||
|
||||
#endif //_CO_UTIL_H
|
405
MCU/components/modules/common/src/co_list.c
Normal file
405
MCU/components/modules/common/src/co_list.c
Normal file
@ -0,0 +1,405 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_list.c
|
||||
*
|
||||
* @brief List management functions
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup CO_LIST
|
||||
* @{
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h> // for mem* functions
|
||||
#include <stdbool.h>
|
||||
#include "co_list.h" // common list definitions
|
||||
|
||||
/*
|
||||
* FUNCTION DEFINTIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_init(struct co_list *list)
|
||||
{
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
}
|
||||
|
||||
void co_list_pool_init(struct co_list *list,
|
||||
void *pool,
|
||||
size_t elmt_size,
|
||||
uint32_t elmt_cnt,
|
||||
void *default_value,
|
||||
uint8_t list_type)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
// initialize the free list relative to the pool
|
||||
co_list_init(list);
|
||||
|
||||
// Add each element of the pool to this list, and init them one by one
|
||||
for (i = 0; i < elmt_cnt; i++)
|
||||
{
|
||||
if (default_value)
|
||||
{
|
||||
memcpy(pool, default_value, elmt_size);
|
||||
}
|
||||
if((i == (elmt_cnt - 1)) && (list_type != POOL_LINKED_LIST))
|
||||
{
|
||||
struct co_list_hdr *list_hdr =(struct co_list_hdr *) pool;
|
||||
|
||||
// check if list is empty
|
||||
if (co_list_is_empty(list))
|
||||
{
|
||||
// list empty => pushed element is also head
|
||||
list->first = list_hdr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// list not empty => update next of last
|
||||
list->last->next = list_hdr;
|
||||
}
|
||||
|
||||
// add element at the end of the list
|
||||
list->last = list_hdr;
|
||||
list_hdr->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
co_list_push_back(list, (struct co_list_hdr *) pool);
|
||||
}
|
||||
|
||||
// move to the next pool element
|
||||
pool = (void *)((uint8_t *)pool + (uint32_t)elmt_size);
|
||||
}
|
||||
}
|
||||
|
||||
void co_list_push_back(struct co_list *list,
|
||||
struct co_list_hdr *list_hdr)
|
||||
{
|
||||
// check if list is empty
|
||||
if (co_list_is_empty(list))
|
||||
{
|
||||
// list empty => pushed element is also head
|
||||
list->first = list_hdr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// list not empty => update next of last
|
||||
list->last->next = list_hdr;
|
||||
}
|
||||
|
||||
// add element at the end of the list
|
||||
list->last = list_hdr;
|
||||
list_hdr->next = NULL;
|
||||
}
|
||||
|
||||
void co_list_push_back_sublist(struct co_list *list, struct co_list_hdr *first_hdr, struct co_list_hdr *last_hdr)
|
||||
{
|
||||
// check if list is empty
|
||||
if (co_list_is_empty(list))
|
||||
{
|
||||
// list empty => pushed element is also head
|
||||
list->first = first_hdr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// list not empty => update next of last
|
||||
list->last->next = first_hdr;
|
||||
}
|
||||
|
||||
// Update last pointer
|
||||
list->last = last_hdr;
|
||||
last_hdr->next = NULL;
|
||||
}
|
||||
|
||||
void co_list_push_front(struct co_list *list,
|
||||
struct co_list_hdr *list_hdr)
|
||||
{
|
||||
// check if list is empty
|
||||
if (co_list_is_empty(list))
|
||||
{
|
||||
// list empty => pushed element is also head
|
||||
list->last = list_hdr;
|
||||
}
|
||||
|
||||
// add element at the beginning of the list
|
||||
list_hdr->next = list->first;
|
||||
list->first = list_hdr;
|
||||
}
|
||||
|
||||
struct co_list_hdr *co_list_pop_front(struct co_list *list)
|
||||
{
|
||||
struct co_list_hdr *element;
|
||||
|
||||
// check if list is empty
|
||||
element = list->first;
|
||||
if (element != NULL)
|
||||
{
|
||||
|
||||
// The list isn't empty : extract the first element
|
||||
list->first = list->first->next;
|
||||
|
||||
if(list->first == NULL)
|
||||
{
|
||||
list->last = list->first;
|
||||
}
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
struct co_list_hdr *co_list_pop_subfront(struct co_list *list)
|
||||
{
|
||||
struct co_list_hdr *element;
|
||||
|
||||
// check if list is empty
|
||||
element = list->first;
|
||||
if (element != NULL)
|
||||
{
|
||||
element = list->first->next;
|
||||
if(element != NULL){
|
||||
// The list isn't empty : extract the first element
|
||||
list->first->next = list->first->next->next;
|
||||
if(list->first->next == NULL){
|
||||
list->last->next = list->first;
|
||||
}
|
||||
}
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool co_list_extract(struct co_list *list, struct co_list_hdr *list_hdr)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
struct co_list_hdr *prev = NULL;
|
||||
struct co_list_hdr *curr = list->first;
|
||||
|
||||
// Search for the element
|
||||
while(curr != NULL)
|
||||
{
|
||||
// Check element
|
||||
if(curr == list_hdr)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Move pointers
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
// Check if the element is first
|
||||
if(prev == NULL)
|
||||
{
|
||||
// Extract element
|
||||
list->first = list_hdr->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Extract element
|
||||
prev->next = list_hdr->next;
|
||||
}
|
||||
|
||||
// Check if the element is last
|
||||
if(list_hdr == list->last)
|
||||
{
|
||||
// Update last pointer
|
||||
list->last = prev;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
void co_list_extract_after(struct co_list *list, struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_rem_hdr)
|
||||
{
|
||||
// Check if the element is first
|
||||
if(elt_ref_hdr == NULL)
|
||||
{
|
||||
// The list isn't empty : extract the first element
|
||||
list->first = list->first->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Extract element
|
||||
elt_ref_hdr->next = elt_to_rem_hdr->next;
|
||||
}
|
||||
|
||||
// Check if the element is last
|
||||
if(elt_to_rem_hdr == list->last)
|
||||
{
|
||||
// Update last pointer
|
||||
list->last = elt_ref_hdr;
|
||||
}
|
||||
}
|
||||
|
||||
void co_list_extract_sublist(struct co_list *list, struct co_list_hdr *ref_hdr, struct co_list_hdr *last_hdr)
|
||||
{
|
||||
// Check if the element is first
|
||||
if(ref_hdr == NULL)
|
||||
{
|
||||
// Extract the elements
|
||||
list->first = last_hdr->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Extract the elements
|
||||
ref_hdr->next = last_hdr->next;
|
||||
}
|
||||
|
||||
// Check if the element is last
|
||||
if(last_hdr == list->last)
|
||||
{
|
||||
// Reference element becomes last
|
||||
list->last = ref_hdr;
|
||||
}
|
||||
}
|
||||
|
||||
bool co_list_find(struct co_list *list,
|
||||
struct co_list_hdr *list_hdr)
|
||||
{
|
||||
struct co_list_hdr *tmp_list_hdr;
|
||||
|
||||
// Go through the list to find the element
|
||||
tmp_list_hdr = list->first;
|
||||
|
||||
while ((tmp_list_hdr != list_hdr) && (tmp_list_hdr != NULL))
|
||||
{
|
||||
tmp_list_hdr = tmp_list_hdr->next;
|
||||
}
|
||||
|
||||
return (tmp_list_hdr == list_hdr);
|
||||
}
|
||||
|
||||
void co_list_merge(struct co_list *list1,
|
||||
struct co_list *list2)
|
||||
{
|
||||
// just copy list elements
|
||||
if(co_list_is_empty(list1))
|
||||
{
|
||||
list1->first = list2->first;
|
||||
list1->last = list2->last;
|
||||
}
|
||||
// merge lists
|
||||
else
|
||||
{
|
||||
// Append list2 to list1
|
||||
list1->last->next = list2->first;
|
||||
list1->last = list2->last;
|
||||
|
||||
}
|
||||
|
||||
// Empty list2
|
||||
list2->first = NULL;
|
||||
}
|
||||
|
||||
void co_list_insert_before(struct co_list *list,
|
||||
struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr)
|
||||
{
|
||||
// If no element referenced
|
||||
if(elt_ref_hdr == NULL)
|
||||
{
|
||||
co_list_push_front(list,elt_to_add_hdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct co_list_hdr *tmp_list_prev_hdr = NULL;
|
||||
struct co_list_hdr *tmp_list_curr_hdr;
|
||||
|
||||
// Go through the list to find the element
|
||||
tmp_list_curr_hdr = list->first;
|
||||
|
||||
while ((tmp_list_curr_hdr != elt_ref_hdr) && (tmp_list_curr_hdr != NULL))
|
||||
{
|
||||
// Save previous element
|
||||
tmp_list_prev_hdr = tmp_list_curr_hdr;
|
||||
// Get the next element of the list
|
||||
tmp_list_curr_hdr = tmp_list_curr_hdr->next;
|
||||
}
|
||||
// If only one element is available
|
||||
if(tmp_list_prev_hdr == NULL)
|
||||
{
|
||||
co_list_push_front(list,elt_to_add_hdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_list_prev_hdr->next = elt_to_add_hdr;
|
||||
elt_to_add_hdr->next = tmp_list_curr_hdr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void co_list_insert_after(struct co_list *list,
|
||||
struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr)
|
||||
{
|
||||
// If no element referenced
|
||||
if(elt_ref_hdr == NULL)
|
||||
{
|
||||
co_list_push_back(list,elt_to_add_hdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct co_list_hdr *tmp_list_curr_hdr;
|
||||
|
||||
// Go through the list to find the element
|
||||
tmp_list_curr_hdr = list->first;
|
||||
|
||||
while ((tmp_list_curr_hdr != elt_ref_hdr) && (tmp_list_curr_hdr != NULL))
|
||||
{
|
||||
// Get the next element of the list
|
||||
tmp_list_curr_hdr = tmp_list_curr_hdr->next;
|
||||
}
|
||||
// If only one element is available
|
||||
if(tmp_list_curr_hdr == NULL)
|
||||
{
|
||||
co_list_push_back(list,elt_to_add_hdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if the found element was the last of the list
|
||||
if (!tmp_list_curr_hdr->next)
|
||||
{
|
||||
// Update last pointer
|
||||
list->last = elt_to_add_hdr;
|
||||
}
|
||||
|
||||
elt_to_add_hdr->next = tmp_list_curr_hdr->next;
|
||||
tmp_list_curr_hdr->next = elt_to_add_hdr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t co_list_size(struct co_list *list)
|
||||
{
|
||||
uint16_t count = 0;
|
||||
struct co_list_hdr *tmp_list_hdr = list->first;
|
||||
|
||||
// browse list to count number of elements
|
||||
while (tmp_list_hdr != NULL)
|
||||
{
|
||||
tmp_list_hdr = tmp_list_hdr->next;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/// @} CO_LIST
|
28
MCU/components/modules/common/src/co_log.c
Normal file
28
MCU/components/modules/common/src/co_log.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "co_log.h"
|
||||
|
||||
void log_printf_level(const char *level)
|
||||
{
|
||||
#if defined(__ARMCC_VERSION) || defined(__CC_ARM)
|
||||
fputs(level, &__stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
void log_printf(const char* tag,
|
||||
const char* file_name,
|
||||
uint32_t line,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if(tag)
|
||||
printf("[%s] ",tag);
|
||||
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
208
MCU/components/modules/common/src/co_util.c
Normal file
208
MCU/components/modules/common/src/co_util.c
Normal file
@ -0,0 +1,208 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "system_fr30xx.h"
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Function : ascii_char2val ----add by chsheng, chsheng@accelsemi.com
|
||||
Return: -1=error
|
||||
Description:
|
||||
'a' -> 0xa 'A' -> 0xa
|
||||
-------------------------------------------------------------------------*/
|
||||
static char ascii_char2val(const char c)
|
||||
{
|
||||
if(c>='0' && c<='9')
|
||||
return c-'0';
|
||||
if((c>='a' && c<='f') || (c>='A' && c<='F'))
|
||||
return (c&0x7)+9;
|
||||
|
||||
return (char)(-1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Function : ascii_strn2val ----add by chsheng, chsheng@accelsemi.com
|
||||
Return: -1=error
|
||||
Description:
|
||||
str = "123" bas = 10 return 123
|
||||
str = "123" bas = 16 return 0x123
|
||||
-------------------------------------------------------------------------*/
|
||||
int ascii_strn2val( const char str[], char base, char n)
|
||||
{
|
||||
int val = 0;
|
||||
char v;
|
||||
while(n != 0){
|
||||
|
||||
v = ascii_char2val(*str);
|
||||
#if 0
|
||||
if (v == -1 || v >= base)
|
||||
return -1;
|
||||
#else
|
||||
if (v == (char)(-1) || v >= base)
|
||||
{
|
||||
if(val == 0) //to filter abormal beginning and ending
|
||||
{
|
||||
str ++;
|
||||
n --;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
val = val*base + v;
|
||||
|
||||
str++;
|
||||
n--;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
#ifdef __CC_ARM
|
||||
__RAM_CODE static __asm void cpu_delay(uint32_t ulCount)
|
||||
{
|
||||
PRESERVE8
|
||||
start
|
||||
subs r0, #1
|
||||
bne start
|
||||
bx lr
|
||||
}
|
||||
#endif // __CC_ARM
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__RAM_CODE static void cpu_delay(uint32_t ulCount)
|
||||
{
|
||||
__asm volatile(
|
||||
" 1: subs %0, #1 \n"
|
||||
" bne 1b \n"
|
||||
:
|
||||
:"r"(ulCount)
|
||||
:
|
||||
);
|
||||
}
|
||||
#endif // __GNUC__
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
__RAM_CODE static void cpu_delay(uint32_t ulCount)
|
||||
{
|
||||
__asm volatile(
|
||||
"loop: subs %0, #1 \n"
|
||||
"bne loop \n"
|
||||
:
|
||||
:"r"(ulCount)
|
||||
:
|
||||
);
|
||||
}
|
||||
#endif // __ICCARM__
|
||||
|
||||
__RAM_CODE void co_delay_100us(uint32_t num)
|
||||
{
|
||||
volatile uint32_t threshold;
|
||||
volatile uint8_t pclk_cfg;
|
||||
|
||||
if(num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
pclk_cfg = system_get_CoreClock() / 1000000;
|
||||
|
||||
threshold = 400 * num;
|
||||
if(pclk_cfg == 24) {
|
||||
threshold <<= 1;
|
||||
}
|
||||
else if(pclk_cfg == 48) {
|
||||
threshold <<= 2;
|
||||
}
|
||||
else if(pclk_cfg == 96) {
|
||||
threshold <<= 3;
|
||||
}
|
||||
else {
|
||||
threshold *= (pclk_cfg / 12);
|
||||
}
|
||||
|
||||
cpu_delay(threshold);
|
||||
}
|
||||
|
||||
__RAM_CODE void co_delay_10us(uint32_t num)
|
||||
{
|
||||
volatile uint32_t threshold;
|
||||
volatile uint8_t pclk_cfg;
|
||||
|
||||
if(num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
pclk_cfg = system_get_CoreClock() / 1000000;
|
||||
|
||||
threshold = 40 * num;
|
||||
if(pclk_cfg == 24) {
|
||||
threshold <<= 1;
|
||||
}
|
||||
else if(pclk_cfg == 48) {
|
||||
threshold <<= 2;
|
||||
}
|
||||
else if(pclk_cfg == 96) {
|
||||
threshold <<= 3;
|
||||
}
|
||||
else {
|
||||
threshold *= (pclk_cfg / 12);
|
||||
}
|
||||
|
||||
cpu_delay(threshold);
|
||||
}
|
||||
|
||||
#ifdef __CC_ARM
|
||||
__RAM_CODE __asm void mul_64(uint32_t *low, uint32_t *high, uint32_t mul1, uint32_t mul2)
|
||||
{
|
||||
PRESERVE8
|
||||
|
||||
push {r4, r5, lr}
|
||||
|
||||
umull r4, r5, r2, r3
|
||||
str r4, [r0]
|
||||
str r5, [r1]
|
||||
|
||||
pop {r4, r5, pc}
|
||||
}
|
||||
#endif // __CC_ARM
|
||||
#if defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)
|
||||
__RAM_CODE void mul_64(uint32_t *low, uint32_t *high, uint32_t mul1, uint32_t mul2)
|
||||
{
|
||||
__asm volatile(
|
||||
" umull r4, r5, %2, %3 \n"
|
||||
" str r4, [%0] \n"
|
||||
" str r5, [%1] \n"
|
||||
:
|
||||
: "r"(low), "r"(high), "r"(mul1), "r"(mul2)
|
||||
: "r4", "r5"
|
||||
);
|
||||
}
|
||||
#endif // defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
|
||||
/*
|
||||
* result = (high * (0xFFFFFFFF+1) + low) / div
|
||||
* 0xFFFFFFFF = a * div + b
|
||||
* low = c * div + d
|
||||
* sub = (high * (1 + b) + d) / div
|
||||
* result = a * high + c + sub
|
||||
*
|
||||
* limitation: high * (1 + b) + d should be no larger than 0xffffffff
|
||||
*/
|
||||
__RAM_CODE uint32_t simple_div_64(uint32_t low, uint32_t high, uint32_t div)
|
||||
{
|
||||
uint32_t a, b, c, d, sub;
|
||||
|
||||
c = low / div;
|
||||
|
||||
if(high == 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
a = 0xFFFFFFFF / div;
|
||||
b = 0xFFFFFFFF % div;
|
||||
d = low % div;
|
||||
sub = (high * (1 + b) + d) / div;
|
||||
|
||||
return (a * high + c + sub);
|
||||
}
|
Reference in New Issue
Block a user