diff --git a/datalink814_ge/src/util/circ_queue.c b/datalink814_ge/src/util/circ_queue.c new file mode 100644 index 0000000..fc6364f --- /dev/null +++ b/datalink814_ge/src/util/circ_queue.c @@ -0,0 +1,141 @@ +/*****************************************************************************/ +/** + * Description: A simple circular FIFO bounded queue + * + * Author: Fan Hao + * Date: 2023-02-23 10:29 + * LastEditors: Fan Hao + * LastEditTime: 2023-02-23 13:18 + * Revisions: Rev 0.0 + * History: + * [2023-02-23]: Initial Version. + * + * Copyright(c) 2023 Beijing Institute of Technology. + * Lab of Communication and Networking + * NOTE: Forked from https://github.com/chrismerck/rpa_queue.git + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#include "circ_queue.h" +#include "common.h" +#include +#include +#include + +inline bool isCircQueueFull(CIRC_QUEUE *queue) +{ + ASSERT(queue != NULL); + return ((queue)->nelts == (queue)->bounds); +} + +inline bool isCircQueueEmpty(CIRC_QUEUE *queue) +{ + ASSERT(queue != NULL); + return ((queue)->nelts == 0); +} + +void CircQueueFree(CIRC_QUEUE *queue) +{ + ASSERT(queue != NULL); + if (queue->data) + free(queue->data); + free(queue); +} + +/** + * Initialize the CIRC_QUEUE. + */ +bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity) +{ + ASSERT(q != NULL); + CIRC_QUEUE *queue; + queue = malloc(sizeof(CIRC_QUEUE)); + if (!queue) + { + return false; + } + *q = queue; + memset(queue, 0, sizeof(CIRC_QUEUE)); + + /* Set all the data in the queue to NULL */ + queue->data = malloc(queueCapacity * sizeof(void *)); + if (queue->data == NULL) + { + goto error; + } + queue->bounds = queueCapacity; + queue->nelts = 0; + queue->in = 0; + queue->out = 0; + return true; +error: + free(queue); + return false; +} + +/** + * Push new data onto the queue. + */ +bool CircQueuePush(CIRC_QUEUE *queue, void *data) +{ + ASSERT(queue != NULL); + + if (isCircQueueFull(queue)) + { + return false; + } + + queue->data[queue->in] = data; + queue->in++; + if (queue->in >= queue->bounds) + { + queue->in -= queue->bounds; + } + queue->nelts++; + + return true; +} + +/** + * Return current number of element in queue. + */ +inline uint32_t CircQueueSize(CIRC_QUEUE *queue) +{ + return queue->nelts; +} + +/** + * Retrieves the next item from the queue. + */ +bool CircQueuePop(CIRC_QUEUE *queue, void **data) +{ + ASSERT(queue != NULL); + + if (isCircQueueEmpty(queue)) + { + return false; + } + + *data = queue->data[queue->out]; + queue->nelts--; + + queue->out++; + if (queue->out >= queue->bounds) + { + queue->out -= queue->bounds; + } + return true; +} diff --git a/datalink814_ge/src/util/circ_queue.h b/datalink814_ge/src/util/circ_queue.h new file mode 100644 index 0000000..a6dc655 --- /dev/null +++ b/datalink814_ge/src/util/circ_queue.h @@ -0,0 +1,111 @@ +/*****************************************************************************/ +/** + * Description: A simple circular FIFO bounded queue + * + * Author: Fan Hao + * Date: 2023-02-23 10:29 + * LastEditors: Fan Hao + * LastEditTime: 2023-02-23 12:53 + * Revisions: Rev 0.0 + * History: + * [2023-02-23]: Initial Version. + * + * Copyright(c) 2023 Beijing Institute of Technology. + * Lab of Communication and Networking + * NOTE: Forked from https://github.com/chrismerck/rpa_queue.git + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +******************************************************************************/ + +#ifndef CIRC_QUEUE_H +#define CIRC_QUEUE_H + +#include +#include +#include + + +/** + * opaque structure + */ +typedef struct { + void **data; + volatile uint32_t nelts; /**< # elements */ + uint32_t in; /**< next empty location */ + uint32_t out; /**< next filled location */ + uint32_t bounds;/**< max size of queue */ +} CIRC_QUEUE; + + + +/** + * create a FIFO queue + * @param queue The new queue + * @param queue_capacity maximum size of the queue + * @param a pool to allocate queue from + */ +bool CircQueueCreate(CIRC_QUEUE **queue, uint32_t queue_capacity); + +/** free queue memory -- call after destroy + * @note we do not free in destroy() to follow pthreads convention +*/ +void CircQueueFree(CIRC_QUEUE * queue); + +/** + * Detects when the CIRC_QUEUE is full. This utility function is expected + * to be called from within critical sections, and is not threadsafe. + */ +bool isCircQueueFull(CIRC_QUEUE *queue); + +/** + * Detects when the CIRC_QUEUE is empty. This utility function is expected + * to be called from within critical sections, and is not threadsafe. + */ +bool isCircQueueEmpty(CIRC_QUEUE *queue); + +/** + * push/add an object to the queue, blocking if the queue is already full + * + * @param queue the queue + * @param data the data + * @returns RPA_EINTR the blocking was interrupted (try again) + * @returns RPA_EOF the queue has been terminated + * @returns RPA_SUCCESS on a successful push + */ +bool CircQueuePush(CIRC_QUEUE *queue, void *data); + + +/** + * pop/get an object from the queue, blocking if the queue is already empty + * + * @param queue the queue + * @param data the data + * @returns RPA_EINTR the blocking was interrupted (try again) + * @returns RPA_EOF if the queue has been terminated + * @returns RPA_SUCCESS on a successful pop + */ +bool CircQueuePop(CIRC_QUEUE *queue, void **data); + +/** + * returns the size of the queue. + * + * @warning this is not threadsafe, and is intended for reporting/monitoring + * of the queue. + * @param queue the queue + * @returns the size of the queue + */ +uint32_t CircQueueSize(CIRC_QUEUE *queue); + +#endif /* CIRC_QUEUE_H */ diff --git a/df_datalink/src/include/list.h b/df_datalink/src/include/list.h index 517a51c..45f2c19 100644 --- a/df_datalink/src/include/list.h +++ b/df_datalink/src/include/list.h @@ -1,327 +1,118 @@ -/***************************************************************************//** - * @file list.h - * @brief List library header - * @author Mihail Chindris (mihail.chindris@analog.com) -******************************************************************************** - * @copyright - * Copyright 2020(c) Analog Devices, Inc. - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - Neither the name of Analog Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - The use of this software may or may not infringe the patent rights - * of one or more patent holders. This license does not release you - * from the requirement that you obtain separate licenses from these - * patent holders to use this software. - * - Use of the software either in source or binary form, must be run - * on or directly connected to an Analog Devices Inc. component. - * - * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -******************************************************************************** - * - * @section list_details Library description - * This library handles double linked lists and it expose inseart, - * read, get and delete functions. \n - * It also can be accesed using it member functions which wrapp function for - * usual list types.\n - * @subsection example Sample code - * @code{.c} - * // -- Use a generic list - * struct list_desc *list1; - * struct iterator *it; - * uint32_t a; - * // Create list list1 - * list_init(&list1, LIST_DEFAULT, NULL); - * // Add items to the list - * list_add_last(list1, 1); - * list_add_last(list1, 2); - * list_add_last(list1, 3); - * // Here the list will be: 1 -> 2 - > 3 - * - * list_read_last(list1, &a); - * printf("Last: %d\n", a); - * // 3 will be printed - * // Create an iterator on the end of the list - * iterator_init(&it, list1, 0); - * // Move the iterator backword with one position - * iterator_move(it, -1); - * // Read the data at the current position - * iterator_read(it, &a); - * printf("Current: %d\n", a); - * // 2 will be printed - * iterator_remove(it); - * list_remove(list1); - * - * // -- Use a popular list - * struct list_desc *stack; - * // Create a FIFO list - * list_init(&stack, LIST_STACK, NULL); - * // Put elements in the list - * stack->push(stack, 1); - * stack->push(stack, 2); - * stack->push(stack, 3); - * // Read from the stack - * stack->pop(stack, &a); - * printf("Last: %d\n", a); - * // 3 will be printed - * list_remove(stack); - * @endcode -*******************************************************************************/ -#ifndef _LIST_H_ -#define _LIST_H_ +// +// list.h +// +// Copyright (c) 2010 TJ Holowaychuk +// -/******************************************************************************/ -/***************************** Include Files **********************************/ -/******************************************************************************/ +#ifndef __LIST_H__ +#define __LIST_H__ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include #include -#include -/******************************************************************************/ -/*************************** Types Declarations *******************************/ -/******************************************************************************/ + /* + * list_t iterator direction. + */ -/** - * @struct list_desc - * @brief Structure storing the list and function wrapper for usual list types - * - * With this structure the funtionalities of usual list types - * ( \ref adapter_type ) can be accesed with the functions referenced in this - * structure. - * For example: - * @code{.c} - * my_queue->push(my_queue, my_data); - * @endcode - */ -struct list_desc; + typedef enum + { + LIST_HEAD, + LIST_TAIL + } list_direction_t; -/** - * @struct list_iterator - * @brief Structure used to iterate through the list using Iterator functions. - */ -struct iterator; + /* + * list_t node struct. + */ -/** - * @brief Prototype of the compare function. - * - * The function used to compare the elements of the liste when doing - * operations on an ordered list. - * @param data1 - First element to be compared - * @param data2 - Second element to be compared - * @return - * - -1 - If data1 < data2 - * - 0 - If data1 == data2 - * - 1 - If data1 > data2 - */ -typedef int32_t (*f_cmp)(void *data1, void *data2); + typedef struct list_node + { + struct list_node *prev; + struct list_node *next; + void *val; + } list_node_t; -/** - * @name Generic functions - * Each function interacting with the list have one of the following formats.\n - * Aditionaly they may have one more parametere for specific functionalities.\n - * In the Iterator functions, the list reference is replaced by the iterator's - * one. - * @{ - */ + /* + * list_t struct. + */ -/** - * @brief Add an element in the list. - * - * The element of the list is created and the data field is stored in it. - * @param list_desc - Reference to the list. Created by \ref list_init. - * @param data - Data to store in a list element - * @return - * - 0 : On success - * - -1 : Otherwise - */ -typedef int32_t (*f_add)(struct list_desc *list_desc, void *data); + typedef struct + { + list_node_t *head; + list_node_t *tail; + uint32_t len; + void (*free)(void *val); + int8_t (*compare)(void *a, void *b); + } list_t; -/** - * @brief Edit an element in the list. The content is replaced by new_data. - * @param list_desc - Reference to the list. Created by \ref list_init. - * @param new_data - New data to replace the old one - * @return - * - 0 : On success - * - -1 : Otherwise - */ -typedef int32_t (*f_edit)(struct list_desc *list_desc, void *new_data); + /* + * list_t iterator struct. + */ -/** - * @brief Read an element from the list. - * @param list_desc - Reference to the list. Created by \ref list_init. - * @param result - If not null, result is filled with: - * @param data - Content of the list element, NULL if some error occur. - * @return \n - * - 0 : On success - * - -1 : Otherwise - * @note If the content of an element can be 0 then the result must be checked - * to see if the functions has succeded - */ -typedef int32_t (*f_read)(struct list_desc *list_desc, void **data); + typedef struct + { + list_node_t *next; + list_direction_t direction; + } list_iterator_t; -/** - * @brief Read and remove an element from the list. - * @param list_desc - Reference to the list. Created by \ref list_init. - * @param result - If not null, result is filled with: - * @param data - Content of the list element, NULL if some error occur. - * @return - * - 0 : On success - * - -1 : Otherwise - */ -typedef int32_t (*f_get)(struct list_desc *list_desc, void **data); + // Node prototypes. -/** @} */ + list_node_t * + list_node_new(void *val); -/** - * @enum adapter_type - * @brief Selects functionalities for functions in \ref list_desc - */ -enum adapter_type { - /** Default type is LIST_STACK */ - LIST_DEFAULT, - /** - * Functions for a FIFO list (First-in first-out). Elements are inserted - * in one end and extracted from the other end. - * - \e Push: Insert element - * - \e Pop: Get next element (Read and remove) - * - \e Top_next: Read next element - * - \e Back: Read first element - * - \e Swap: Edit the content of the next element - */ - LIST_QUEUE, - /** - * Functions for a LIFO list (Last-in first-out). Elements are inserted - * and extracted only from the same end. - * - \e Push: Insert element - * - \e Pop: Get top element (Read and remove) - * - \e Top_next: Read top element - * - \e Back: Read bottom element - * - \e Swap: Edit the content of the top element - */ - LIST_STACK, - /** - * Functions for ordered list. The order of element is determinated - * usinge the \ref f_cmp. - * - \e Push: Insert element - * - \e Pop: Get lowest element (Read and remove) - * - \e Top_next: Read lowest element - * - \e Back: Read the biggest element - * - \e Swap: Edit the lowest element - */ - LIST_PRIORITY_LIST -}; + // list_t prototypes. -struct list_desc { - /** Refer to \ref adapter_type */ - f_add push; - /** Refer to \ref adapter_type */ - f_get pop; - /** Refer to \ref adapter_type */ - f_read top_next; - /** Refer to \ref adapter_type */ - f_read back; - /** Refer to \ref adapter_type */ - f_edit swap; - /** Structure storing the list internal parameters */ - void *priv_desc; -}; + list_t * + list_new(void); -/******************************************************************************/ -/************************ Functions Declarations ******************************/ -/******************************************************************************/ + list_node_t * + list_rpush(list_t *self, list_node_t *node); -int32_t list_init(struct list_desc **list_desc, - enum adapter_type type, - f_cmp comparator); -int32_t list_remove(struct list_desc *list_desc); -int32_t list_get_size(struct list_desc *list_desc, - uint32_t *out_size); + list_node_t * + list_lpush(list_t *self, list_node_t *node); -/** - * @name Iterator functions - * An iterator is used to iterate through the list. For a list, any number of - * iterators can be created. All must be removed before removing a list. - * @{ - */ -int32_t iterator_init(struct iterator **iter, - struct list_desc *list_desc, - bool start); -int32_t iterator_remove(struct iterator *iter); -int32_t iterator_move(struct iterator *iter, int32_t steps); -int32_t iterator_move_to_idx(struct iterator *iter, int32_t idx); -int32_t iterator_find(struct iterator *iter, void *cmp_data); -int32_t iterator_insert(struct iterator *iter, void *data, - bool after); -int32_t iterator_edit(struct iterator *iter, void *new_data); -int32_t iterator_read(struct iterator *iter, void **data); -int32_t iterator_get(struct iterator *iter, void **data); -/** @}*/ + list_node_t * + list_find(list_t *self, void *val); -/** - * @name Operations on the ends of the list - * These functions will operate on the first or last element of the list - * @{ - */ -int32_t list_add_first(struct list_desc *list_desc, void *data); -int32_t list_edit_first(struct list_desc *list_desc, - void *new_data); -int32_t list_read_first(struct list_desc *list_desc, void **data); -int32_t list_get_first(struct list_desc *list_desc, void **data); + list_node_t * + list_at(list_t *self, int index); -int32_t list_add_last(struct list_desc *list_desc, void *data); -int32_t list_edit_last(struct list_desc *list_desc, void *new_data); -int32_t list_read_last(struct list_desc *list_desc, void **data); -int32_t list_get_last(struct list_desc *list_desc, void **data); -/** @}*/ + list_node_t * + list_rpop(list_t *self); -/** - * @name Operations by index - * These functions use an index to identify the element in the list. - * @{ - */ -int32_t list_add_idx(struct list_desc *list_desc, void *data, - uint32_t idx); -int32_t list_edit_idx(struct list_desc *list_desc, void *new_data, - uint32_t idx); -int32_t list_read_idx(struct list_desc *list_desc, void **data, - uint32_t idx); -int32_t list_get_idx(struct list_desc *list_desc, void **data, - uint32_t idx); -/** @}*/ + list_node_t * + list_lpop(list_t *self); -/** - * @name Operations by comparation - * These functions use the specified \ref f_cmp at \ref list_init to identify - * the element this will operate on. - * @{ - */ -int32_t list_add_find(struct list_desc *list_desc, void *data); -int32_t list_edit_find(struct list_desc *list_desc, void *new_data, - void *cmp_data); -int32_t list_read_find(struct list_desc *list_desc, void **data, - void *cmp_data); -int32_t list_get_find(struct list_desc *list_desc, void **data, - void *cmp_data); -/** @}*/ + void + list_remove(list_t *self, list_node_t *node); -#endif // _LIST_H_ + void + list_clear(list_t *self); + + void + list_destroy(list_t *self); + + // list_t iterator prototypes. + + list_iterator_t * + list_iterator_new(list_t *list, list_direction_t direction); + + list_iterator_t * + list_iterator_new_from_node(list_node_t *node, list_direction_t direction); + + list_node_t * + list_iterator_next(list_iterator_t *self); + + void + list_iterator_destroy(list_iterator_t *self); + +#ifdef __cplusplus +} +#endif + +#endif /* __CLIBS_LIST_H__ */ diff --git a/df_datalink/src/include/util.h b/df_datalink/src/include/util.h index befac68..a4a4608 100644 --- a/df_datalink/src/include/util.h +++ b/df_datalink/src/include/util.h @@ -2,7 +2,7 @@ * @file util.h * @brief Implementation of utility functions. * @author DBogdan (dragos.bogdan@analog.com) - ******************************************************************************** +******************************************************************************** * Copyright 2018(c) Analog Devices, Inc. * * All rights reserved. @@ -35,9 +35,9 @@ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************/ -#ifndef _UTIL_H_ -#define _UTIL_H_ +*******************************************************************************/ +#ifndef __UTIL_H_ +#define __UTIL_H_ /******************************************************************************/ /***************************** Include Files **********************************/ @@ -55,8 +55,6 @@ #define CRC8_INIT 0x00 #define BIT(x) (1 << (x)) -#define ASSERT_BIT(x, ofst) (x | BIT(ofst)) -#define DEASSERT_BIT(x, ofst) (x & (~BIT(ofst))) #define ARRAY_SIZE(x) \ (sizeof(x) / sizeof((x)[0])) @@ -194,4 +192,4 @@ int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVa bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly); int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal); bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly); -#endif // UTIL_H_ +#endif // __UTIL_H_ diff --git a/df_datalink/src/util/crc.c b/df_datalink/src/util/crc.c index c0934b7..d460215 100644 --- a/df_datalink/src/util/crc.c +++ b/df_datalink/src/util/crc.c @@ -22,42 +22,45 @@ #ifdef __CRC_LSB // CRC-16-CCITT G(X)=X16+X12+X5+1 // Reversed -static const uint16_t crc16_1021_lsb_lut[256] = { - 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, - 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, - 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, - 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, - 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, - 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, - 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, - 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, - 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, - 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, - 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, - 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, - 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, - 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, - 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, - 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, - 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, - 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, - 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, - 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, - 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, - 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, - 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, - 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, - 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, - 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, - 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, - 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, - 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, - 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, - 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, - 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78}; +static const uint16_t crc16_1021_lsb_lut[256] = +{ + 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, + 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, + 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, + 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, + 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, + 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, + 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, + 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, + 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, + 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, + 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, + 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, + 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, + 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, + 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, + 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, + 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, + 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, + 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, + 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, + 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, + 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, + 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, + 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, + 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, + 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, + 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, + 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, + 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, + 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, + 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, + 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 +}; // CRC-16-MAXIM G(X)=X16+X15+X2+1 -const uint16_t crc16_8005_lsb_lut[256] = { +const uint16_t crc16_8005_lsb_lut[256] = +{ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, @@ -89,10 +92,12 @@ const uint16_t crc16_8005_lsb_lut[256] = { 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, - 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040}; + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; // CRC-8-MAXIM G(X)=X8+X5+X4+1 -const uint8_t crc8_31_lsb_lut[256] = { +const uint8_t crc8_31_lsb_lut[256] = +{ 0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83, 0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41, 0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E, @@ -124,45 +129,49 @@ const uint8_t crc8_31_lsb_lut[256] = { 0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A, 0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8, 0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7, - 0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35}; + 0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35 +}; #else // CRC-16-CCITT G(X)=X16+X12+X5+1 -static const uint16_t crc16_1021_msb_lut[256] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, - 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, - 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, - 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, - 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, - 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, - 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, - 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, - 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, - 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, - 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, - 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, - 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, - 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, - 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, - 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, - 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, - 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, - 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, - 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, - 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, - 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, - 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0}; +static const uint16_t crc16_1021_msb_lut[256] = +{ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; // CRC-16-MAXIM G(X)=X16+X15+X2+1 -const uint16_t crc16_8005_msb_lut[256] = { +const uint16_t crc16_8005_msb_lut[256] = +{ 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, @@ -194,10 +203,12 @@ const uint16_t crc16_8005_msb_lut[256] = { 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, - 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202}; + 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202 +}; // CRC-8-MAXIM G(X)=X8+X5+X4+1 -const uint8_t crc8_31_msb_lut[256] = { +const uint8_t crc8_31_msb_lut[256] = +{ 0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97, 0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E, 0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4, @@ -229,10 +240,11 @@ const uint8_t crc8_31_msb_lut[256] = { 0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56, 0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF, 0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15, - 0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC}; + 0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC +}; #endif -/* CRC lookup table algorithm +/* CRC lookup table algorithm #define CRC_BIT_NUM 8u/16u/32u/64u #define BITS_IN_BYTE 8u uint8_t dataBuff[ARRAY_SIZE] = { 0x32, 0x33, …}; diff --git a/df_datalink/src/util/list.c b/df_datalink/src/util/list.c index 21ea676..119fa89 100644 --- a/df_datalink/src/util/list.c +++ b/df_datalink/src/util/list.c @@ -1,887 +1,342 @@ -/******************************************************************************* -//** - * @file list.c - * @brief List library implementation - * @author Mihail Chindris (mihail.chindris@analog.com) -******************************************************************************** - * Copyright 2020(c) Analog Devices, Inc. - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - Neither the name of Analog Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - The use of this software may or may not infringe the patent rights - * of one or more patent holders. This license does not release you - * from the requirement that you obtain separate licenses from these - * patent holders to use this software. - * - Use of the software either in source or binary form, must be run - * on or directly connected to an Analog Devices Inc. component. - * - * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ +#ifndef LIST_MALLOC +#define LIST_MALLOC malloc +#endif -/******************************************************************************/ -/***************************** Include Files **********************************/ -/******************************************************************************/ +#ifndef LIST_FREE +#define LIST_FREE free +#endif +// +// list.c +// +// Copyright (c) 2010 TJ Holowaychuk +// + +#include #include "list.h" -#include "error.h" -#include -/******************************************************************************/ -/*************************** Types Declarations *******************************/ -/******************************************************************************/ - -/** - * @struct list_elem - * @brief Format of each element of the list +/* + * Allocates a new list_node_t. NULL on failure. */ -struct list_elem -{ - /** User data */ - void *data; - /** Reference to previous element */ - struct list_elem *prev; - /** Reference to next element */ - struct list_elem *next; -}; -/** - * @struct list_iterator - * @brief Structure used to iterate through the list +list_node_t * +list_node_new(void *val) +{ + list_node_t *self; + if (!(self = LIST_MALLOC(sizeof(list_node_t)))) + return NULL; + self->prev = NULL; + self->next = NULL; + self->val = val; + return self; +} + +/* + * Allocate a new list_t. NULL on failure. */ -struct iterator -{ - /** List reference */ - struct _list_desc *list; - /** Current element reference */ - struct list_elem *elem; -}; -/** - * @struct _list_desc - * @brief List descriptor +list_t * +list_new(void) +{ + list_t *self; + if (!(self = LIST_MALLOC(sizeof(list_t)))) + return NULL; + self->head = NULL; + self->tail = NULL; + self->free = NULL; + self->compare = NULL; + self->len = 0; + return self; +} + +/* + * Remove all the node in list. + * @self: Pointer to the list */ -struct _list_desc -{ - /** Reference to first element in the list */ - struct list_elem *first; - /** Reference to last element in the list*/ - struct list_elem *last; - /** Number of elements in the list */ - uint32_t nb_elements; - /** Function used to compare elements */ - f_cmp comparator; - /** Number of current active iterators */ - uint32_t nb_iterators; - /** Internal list iterator */ - struct iterator l_it; -}; -/** @brief Default function used to compare element in the list ( \ref f_cmp) */ -static int32_t default_comparator(void *data1, void *data2) +void list_clear(list_t *self) { - return (int32_t)((int32_t *)data1 - (int32_t *)data2); + uint32_t len = self->len; + list_node_t *next; + list_node_t *curr = self->head; + + while (len) + { + next = curr->next; + if (self->free) + self->free(curr->val); + LIST_FREE(curr); + curr = next; + len--; + } } -/** - * @brief Creates a new list elements an configure its value - * @param data - To set list_elem.data - * @param prev - To set list_elem.prev - * @param next - To set list_elem.next - * @return Address of the new element or NULL if allocation fails. +/* + * Free the list. + * @self: Pointer to the list */ -static inline struct list_elem *create_element(void *data, - struct list_elem *prev, - struct list_elem *next) + +void list_destroy(list_t *self) { - struct list_elem *elem; - - elem = (struct list_elem *)calloc(1, sizeof(*elem)); - if (!elem) - return NULL; - elem->data = data; - elem->prev = prev; - elem->next = next; - - return (elem); + list_clear(self); + LIST_FREE(self); } -/** - * @brief Updates the necesary link on the list elements to add or remove one - * @param prev - Low element - * @param elem - Middle element - * @param next - High element +/* + * Append the given node to the list + * and return the node, NULL on failure. + * @self: Pointer to the list for popping node + * @node: the node to push */ -static inline void update_links(struct list_elem *prev, struct list_elem *elem, - struct list_elem *next) + +list_node_t * +list_rpush(list_t *self, list_node_t *node) { - if (prev) - prev->next = elem ? elem : next; - if (elem) - { - elem->prev = prev; - elem->next = next; - } - if (next) - next->prev = elem ? elem : prev; + if (!node) + return NULL; + + if (self->len) + { + node->prev = self->tail; + node->next = NULL; + self->tail->next = node; + self->tail = node; + } + else + { + self->head = self->tail = node; + node->prev = node->next = NULL; + } + + ++self->len; + return node; } -/** - * @brief Update according to modification the list descriptor - * @param list - List reference - * @param new_first - New first element - * @param new_last - New last element +/* + * Return / detach the last node in the list, or NULL. + * @self: Pointer to the list for popping node */ -static inline void update_desc(struct _list_desc *list, - struct list_elem *new_first, - struct list_elem *new_last) + +list_node_t * +list_rpop(list_t *self) { - if (new_first == list->first) - { - list->last = new_last; - if (new_first == NULL || new_last == NULL) - list->first = new_last; - } - else - { /* if (new_last == list->last) */ - list->first = new_first; - if (new_last == NULL || new_first == NULL) - list->last = new_first; - } + if (!self->len) + return NULL; + + list_node_t *node = self->tail; + + if (--self->len) + { + (self->tail = node->prev)->next = NULL; + } + else + { + self->tail = self->head = NULL; + } + + node->next = node->prev = NULL; + return node; } -/** - * @brief Set the adapter functions acording to the adapter type - * @param ad - Reference of the adapter - * @param type - Type of the adapter +/* + * Return / detach the first node in the list, or NULL. + * @self: Pointer to the list for popping node */ -static inline void set_adapter(struct list_desc *ad, enum adapter_type type) + +list_node_t * +list_lpop(list_t *self) { - switch (type) - { - case LIST_PRIORITY_LIST: - ad->push = list_add_find; - ad->pop = list_get_first; - ad->top_next = list_read_first; - ad->back = list_read_last; - ad->swap = list_edit_first; - break; - case LIST_QUEUE: - ad->push = list_add_last; - ad->pop = list_get_first; - ad->top_next = list_read_first; - ad->back = list_read_last; - ad->swap = list_edit_first; - break; - case LIST_DEFAULT: - case LIST_STACK: - default: - ad->push = list_add_last; - ad->pop = list_get_last; - ad->top_next = list_read_last; - ad->back = list_read_first; - ad->swap = list_edit_last; - break; - } + if (!self->len) + return NULL; + + list_node_t *node = self->head; + + if (--self->len) + { + (self->head = node->next)->prev = NULL; + } + else + { + self->head = self->tail = NULL; + } + + node->next = node->prev = NULL; + return node; } -/** - * @brief Create a new empty list - * @param list_desc - Where to store the reference of the new created list - * @param type - Type of adapter to use. - * @param comparator - Used to compare item when using an ordered list or when - * using the \em find functions. - * @return - * - \ref SUCCESS : On success - * - \ref FAILURE : Otherwise +/* + * Prepend the given node to the list + * and return the node, NULL on failure. + * @self: Pointer to the list for pushing node + * @node: the node to push */ -int32_t list_init(struct list_desc **list_desc, enum adapter_type type, - f_cmp comparator) + +list_node_t * +list_lpush(list_t *self, list_node_t *node) { - struct list_desc *l_desc; - struct _list_desc *list; + if (!node) + return NULL; - if (!list_desc) - return FAILURE; - l_desc = (struct list_desc *)calloc(1, sizeof(*l_desc)); - if (!l_desc) - return FAILURE; - list = (struct _list_desc *)calloc(1, sizeof(*list)); - if (!list) - { - free(l_desc); - return FAILURE; - } + if (self->len) + { + node->next = self->head; + node->prev = NULL; + self->head->prev = node; + self->head = node; + } + else + { + self->head = self->tail = node; + node->prev = node->next = NULL; + } - *list_desc = l_desc; - l_desc->priv_desc = list; - list->comparator = comparator ? comparator : default_comparator; - - /* Configure wrapper */ - set_adapter(l_desc, type); - list->l_it.list = list; - - return SUCCESS; + ++self->len; + return node; } -/** - * @brief Remove the created list. - * - * All its elements will be cleared and the data inside each will be lost. If - * not all iterators have been removed, the list will not be removed. - * @param list_desc - Reference to the list - * @return - * - \ref SUCCESS : On success - * - \ref FAILURE : Otherwise +/* + * Return the node associated to val or NULL. + * @self: Pointer to the list for finding given value + * @val: Value to find */ -int32_t list_remove(struct list_desc *list_desc) + +list_node_t * +list_find(list_t *self, void *val) { - void *data; - struct _list_desc *list; + list_iterator_t *it = list_iterator_new(self, LIST_HEAD); + list_node_t *node; - if (!list_desc) - return FAILURE; + while ((node = list_iterator_next(it))) + { + if (self->compare) + { + if (self->compare(val, node->val) == 0) + { + list_iterator_destroy(it); + return node; + } + } + else + { + if (val == node->val) + { + list_iterator_destroy(it); + return node; + } + } + } - list = list_desc->priv_desc; - if (list->nb_iterators != 0) - return FAILURE; - - /* Remove all the elements */ - while (SUCCESS == list_get_first(list_desc, &data)) - ; - free(list_desc->priv_desc); - free(list_desc); - - return SUCCESS; + list_iterator_destroy(it); + return NULL; } -/** - * @brief Get the number of elements inside the list - * @param list_desc - List reference - * @param out_size - Where to store the number of elements - * @return - * - \ref SUCCESS : On success - * - \ref FAILURE : Otherwise +/* + * Return the node at the given index or NULL. + * @self: Pointer to the list for finding given index + * @index: the index of node in the list */ -int32_t list_get_size(struct list_desc *list_desc, uint32_t *out_size) + +list_node_t * +list_at(list_t *self, int index) { - struct _list_desc *list; + list_direction_t direction = LIST_HEAD; - if (!list_desc || !out_size) - return FAILURE; + if (index < 0) + { + direction = LIST_TAIL; + index = ~index; + } - list = list_desc->priv_desc; - *out_size = list->nb_elements; + if ((unsigned)index < self->len) + { + list_iterator_t *it = list_iterator_new(self, direction); + list_node_t *node = list_iterator_next(it); + while (index--) + node = list_iterator_next(it); + list_iterator_destroy(it); + return node; + } - return SUCCESS; + return NULL; } -/** @brief Add element at the begining of the list. Refer to \ref f_add */ -int32_t list_add_first(struct list_desc *list_desc, void *data) -{ - struct list_elem *prev; - struct list_elem *next; - struct list_elem *elem; - struct _list_desc *list; - - if (!list_desc) - return FAILURE; - - list = list_desc->priv_desc; - - prev = NULL; - next = list->first; - elem = create_element(data, prev, next); - if (!elem) - return FAILURE; - - update_links(prev, elem, next); - - update_desc(list, elem, list->last); - - list->nb_elements++; - - return SUCCESS; -} - -/** @brief Add element at the end of the list. Refer to \ref f_add */ -int32_t list_add_last(struct list_desc *list_desc, void *data) -{ - struct list_elem *prev; - struct list_elem *next; - struct list_elem *elem; - struct _list_desc *list; - - if (!list_desc) - return FAILURE; - list = list_desc->priv_desc; - - prev = list->last; - next = NULL; - elem = create_element(data, prev, next); - if (!elem) - return FAILURE; - - update_links(prev, elem, next); - - update_desc(list, list->first, elem); - - list->nb_elements++; - - return SUCCESS; -} - -/** @brief Add element at the specified idx. Refer to \ref f_add */ -int32_t list_add_idx(struct list_desc *list_desc, void *data, uint32_t idx) -{ - struct _list_desc *list; - - if (!list_desc) - return FAILURE; - list = list_desc->priv_desc; - - /* If there are no elements the creation of an iterator will fail */ - if (list->nb_elements == 0 || idx == 0) - return list_add_first(list_desc, data); - if (list->nb_elements == idx) - return list_add_last(list_desc, data); - - list->l_it.elem = list->first; - if (SUCCESS != iterator_move(&(list->l_it), idx)) - return FAILURE; - - return iterator_insert(&(list->l_it), data, 0); -} - -/** @brief Add element in ascending order. Refer to \ref f_add */ -int32_t list_add_find(struct list_desc *list_desc, void *data) -{ - struct list_elem *elem; - struct _list_desc *list; - - if (!list_desc) - return FAILURE; - list = list_desc->priv_desc; - - /* Based on place iterator */ - elem = list->first; - while (elem) - { - if (0 < list->comparator(elem->data, data)) - break; - elem = elem->next; - } - if (elem == NULL) - { - list->l_it.elem = list->last; - return iterator_insert(&(list->l_it), data, 1); - } - else - { - list->l_it.elem = elem; - return iterator_insert(&(list->l_it), data, 0); - } -} - -/** @brief Edit the first element of the list. Refer to \ref f_edit */ -int32_t list_edit_first(struct list_desc *list_desc, void *new_data) -{ - struct _list_desc *list; - - if (!list_desc) - return FAILURE; - - list = list_desc->priv_desc; - list->first->data = new_data; - - return SUCCESS; -} - -/** @brief Edit the last element of the list. Refer to \ref f_edit */ -int32_t list_edit_last(struct list_desc *list_desc, void *new_data) -{ - struct _list_desc *list; - - if (!list_desc) - return FAILURE; - - list = list_desc->priv_desc; - list->last->data = new_data; - - return SUCCESS; -} - -/** @brief Edit the element at the specified idx. Refer to \ref f_edit */ -int32_t list_edit_idx(struct list_desc *list_desc, void *new_data, uint32_t idx) -{ - struct _list_desc *list; - - if (!list_desc) - return FAILURE; - list = list_desc->priv_desc; - - list->l_it.elem = list->first; - if (SUCCESS != iterator_move(&(list->l_it), idx)) - return FAILURE; - - return iterator_edit(&(list->l_it), new_data); -} - -/** @brief Edit the element which match with cmp_data. Refer to \ref f_edit */ -int32_t list_edit_find(struct list_desc *list_desc, void *new_data, - void *cmp_data) -{ - struct _list_desc *list; - - if (!list_desc) - return FAILURE; - list = list_desc->priv_desc; - - list->l_it.elem = list->first; - if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) - return FAILURE; - - return iterator_edit(&(list->l_it), new_data); -} - -/** @brief Read the first element of the list. Refer to \ref f_read */ -int32_t list_read_first(struct list_desc *list_desc, void **data) -{ - struct _list_desc *list; - - if (!list_desc || !data) - return FAILURE; - - *data = NULL; - list = list_desc->priv_desc; - if (!list->first) - return FAILURE; - - *data = list->first->data; - - return SUCCESS; -} - -/** @brief Read the last element of the list. Refer to \ref f_read */ -int32_t list_read_last(struct list_desc *list_desc, void **data) -{ - struct _list_desc *list; - - if (!list_desc || !data) - return FAILURE; - - *data = NULL; - list = list_desc->priv_desc; - if (!list->last) - return FAILURE; - - *data = list->last->data; - - return SUCCESS; -} - -/** @brief Read the element at the specified idx. Refer to \ref f_read */ -int32_t list_read_idx(struct list_desc *list_desc, void **data, uint32_t idx) -{ - struct _list_desc *list; - - if (!list_desc || !data) - return FAILURE; - - *data = NULL; - list = list_desc->priv_desc; - if (!list) - return FAILURE; - - if (idx >= list->nb_elements) - return FAILURE; - - list->l_it.elem = list->first; - if (SUCCESS != iterator_move(&(list->l_it), idx)) - return FAILURE; - - return iterator_read(&(list->l_it), data); -} - -/** @brief Read the element which match with cmp_data. Refer to \ref f_read */ -int32_t list_read_find(struct list_desc *list_desc, void **data, - void *cmp_data) -{ - struct _list_desc *list; - - if (!list_desc || !data) - return FAILURE; - - *data = NULL; - list = list_desc->priv_desc; - if (!list) - return FAILURE; - - list = list_desc->priv_desc; - list->l_it.elem = list->first; - if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) - return FAILURE; - - return iterator_read(&(list->l_it), data); -} - -/** @brief Read and delete the first element of the list. Refer to \ref f_get */ -int32_t list_get_first(struct list_desc *list_desc, void **data) -{ - struct list_elem *prev; - struct list_elem *next; - struct list_elem *elem; - struct _list_desc *list; - - if (!list_desc || !data) - return FAILURE; - - *data = NULL; - list = list_desc->priv_desc; - if (!list->nb_elements) - return FAILURE; - - elem = list->first; - prev = elem->prev; - next = elem->next; - - update_links(prev, NULL, next); - update_desc(list, next, list->last); - list->nb_elements--; - - *data = elem->data; - free(elem); - - return SUCCESS; -} - -/** @brief Read and delete the last element of the list. Refer to \ref f_get */ -int32_t list_get_last(struct list_desc *list_desc, void **data) -{ - struct list_elem *prev; - struct list_elem *next; - struct list_elem *elem; - struct _list_desc *list; - - if (!list_desc || !data) - return FAILURE; - - *data = NULL; - list = list_desc->priv_desc; - if (!list->nb_elements) - return FAILURE; - - elem = list->last; - prev = elem->prev; - next = elem->next; - - update_links(prev, NULL, next); - update_desc(list, list->first, prev); - list->nb_elements--; - - *data = elem->data; - free(elem); - - return SUCCESS; -} - -/** @brief Read and delete the element at idx. Refer to \ref f_get */ -int32_t list_get_idx(struct list_desc *list_desc, void **data, uint32_t idx) -{ - struct _list_desc *list; - - if (!list_desc || !data) - return FAILURE; - - *data = NULL; - list = list_desc->priv_desc; - list->l_it.elem = list->first; - if (SUCCESS != iterator_move(&(list->l_it), idx)) - return FAILURE; - - return iterator_get(&(list->l_it), data); -} - -/** - * @brief Read and delete the element which match with cmp_data. - * Refer to \ref f_get +/* + * Remove the given node from the list, freeing it and it's value. + * @self: Pointer to the list to delete a node + * @node: Pointer the node to be deleted */ -int32_t list_get_find(struct list_desc *list_desc, void **data, void *cmp_data) + +void list_remove(list_t *self, list_node_t *node) { - struct _list_desc *list; + node->prev + ? (node->prev->next = node->next) + : (self->head = node->next); - if (!list_desc || !data) - return FAILURE; + node->next + ? (node->next->prev = node->prev) + : (self->tail = node->prev); - *data = NULL; - list = list_desc->priv_desc; - list->l_it.elem = list->first; - if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) - return FAILURE; + if (self->free) + self->free(node->val); - return iterator_get(&(list->l_it), data); + LIST_FREE(node); + --self->len; } -/** - * @brief Create a new iterator - * @param iter - Where to store the reference for the new iterator - * @param list_desc - Reference of the list the iterator will be used for - * @param start - If it is true the iterator will be positioned at the first - * element of the list, else it will be positioned at the last. - * @return - * - \ref SUCCESS : On success - * - \ref FAILURE : Otherwise +/* + * Allocate a new list_iterator_t. NULL on failure. + * Accepts a direction, which may be LIST_HEAD or LIST_TAIL. */ -int32_t iterator_init(struct iterator **iter, struct list_desc *list_desc, - bool start) + +list_iterator_t * +list_iterator_new(list_t *list, list_direction_t direction) { - struct iterator *it; - - if (!list_desc) - return FAILURE; - - it = (struct iterator *)calloc(1, sizeof(*it)); - if (!it) - return FAILURE; - it->list = list_desc->priv_desc; - it->list->nb_iterators++; - it->elem = start ? it->list->first : it->list->last; - *iter = it; - - return SUCCESS; + list_node_t *node = direction == LIST_HEAD + ? list->head + : list->tail; + return list_iterator_new_from_node(node, direction); } -/** - * @brief Remove the created iterator - * @param iter - Reference of the iterator - * @return - * - \ref SUCCESS : On success - * - \ref FAILURE : Otherwise +/* + * Allocate a new list_iterator_t with the given start + * node. NULL on failure. */ -int32_t iterator_remove(struct iterator *iter) + +list_iterator_t * +list_iterator_new_from_node(list_node_t *node, list_direction_t direction) { - struct iterator *it = iter; - - if (!it) - return FAILURE; - - it->list->nb_iterators--; - free(it); - - return SUCCESS; + list_iterator_t *self; + if (!(self = LIST_MALLOC(sizeof(list_iterator_t)))) + return NULL; + self->next = node; + self->direction = direction; + return self; } -/** - * @brief Move the position of the iteration through the list. - * - * If the required position is outside the list, the call will fail and the - * iterator will keep its position. - * @param iter - Reference of the iterator - * @param steps - Number of positions to be move. If positive, it will be moved - * forward, otherwise backwords. - * @return - * - \ref SUCCESS : On success - * - \ref FAILURE : Otherwise +/* + * Return the next list_node_t or NULL when no more + * nodes remain in the list. */ -int32_t iterator_move(struct iterator *iter, int32_t steps) + +list_node_t * +list_iterator_next(list_iterator_t *self) { - struct iterator *it = iter; - struct list_elem *elem; - int32_t dir = (steps < 0) ? -1 : 1; - - if (!it) - return FAILURE; - - steps = abs(steps); - elem = it->elem; - while (steps > 0 && elem) - { - elem = dir > 0 ? elem->next : elem->prev; - steps--; - } - if (!elem) - return FAILURE; - - it->elem = elem; - - return SUCCESS; + list_node_t *curr = self->next; + if (curr) + { + self->next = self->direction == LIST_HEAD + ? curr->next + : curr->prev; + } + return curr; } -/** - * @brief Move the position of the iterator at the specified index of the list. - * - * @param iter - Reference of the iterator - * @param idx - Position in the list. If negative start counting backwords - * @return - * - \ref SUCCESS : On success - * - \ref FAILURE : Otherwise +/* + * Free the list iterator. */ -int32_t iterator_move_to_idx(struct iterator *iter, int32_t idx) + +void list_iterator_destroy(list_iterator_t *self) { - struct list_elem *elem; - int32_t dir = (idx < 0) ? -1 : 1; - - if (!iter) - return FAILURE; - - idx = abs(idx); - elem = dir > 0 ? iter->list->first : iter->list->last; - while (idx > 0 && elem) - { - elem = dir > 0 ? elem->next : elem->prev; - idx--; - } - if (!elem) - return FAILURE; - - iter->elem = elem; - - return SUCCESS; -} - -/** - * @brief Place the iterator where cmp_data if found. - * @param iter - Reference to the iterator - * @param cmp_data - Data to be found - * @return - * - \ref SUCCESS : On success - * - \ref FAILURE : Otherwise - */ -int32_t iterator_find(struct iterator *iter, void *cmp_data) -{ - struct iterator *it = iter; - struct list_elem *elem; - - if (!it) - return FAILURE; - - elem = it->list->first; - while (elem) - { - if (0 == it->list->comparator(elem->data, cmp_data)) - { - it->elem = elem; - return SUCCESS; - } - elem = elem->next; - } - - return FAILURE; -} - -/** - * @brief Replace the data at the current position. Refer to \ref f_edit - */ -int32_t iterator_edit(struct iterator *iter, void *new_data) -{ - struct iterator *it = iter; - - if (!it) - return FAILURE; - - it->elem->data = new_data; - - return SUCCESS; -} - -/** - * @brief Read and remove the data at the current position. Refer to \ref f_get. - * - * If the current item is the last one, the iterator will be moved to the - * previous one. - */ -int32_t iterator_get(struct iterator *iter, void **data) -{ - struct iterator *it = iter; - struct list_elem *next; - - if (!it || !it->elem || !data) - return FAILURE; - - update_links(it->elem->prev, NULL, it->elem->next); - if (it->elem == it->list->first) - update_desc(it->list, it->elem->next, it->list->last); - else if (it->elem == it->list->last) - update_desc(it->list, it->list->first, it->elem->prev); - it->list->nb_elements--; - - *data = it->elem->data; - if (it->elem == it->list->last) - next = it->elem->prev; - else - next = it->elem->next; - free(it->elem); - it->elem = next; - - return SUCCESS; -} - -/** - * @brief Read the data at the current position. Refer to \ref f_read - */ -int32_t iterator_read(struct iterator *iter, void **data) -{ - struct iterator *it = iter; - - if (!it || !it->elem || !data) - return FAILURE; - - *data = it->elem->data; - - return SUCCESS; -} - -/** - * @brief Insert an item in the list. Refer to \ref f_add - * @param iter - * @param data - * @param after - If true, the item will be inserted after the current position. - * Otherwise it will be inserted before. - */ -int32_t iterator_insert(struct iterator *iter, void *data, bool after) -{ - struct iterator *it = iter; - struct list_elem *elem; - struct list_desc list_desc; - - if (!it) - return FAILURE; - - list_desc.priv_desc = iter->list; - if (after && it->elem == it->list->last) - return list_add_last(&list_desc, data); - if (!after && it->elem == it->list->first) - return list_add_first(&list_desc, data); - - if (after) - elem = create_element(data, it->elem, it->elem->next); - else - elem = create_element(data, it->elem->prev, it->elem); - if (!elem) - return FAILURE; - - update_links(elem->prev, elem, elem->next); - - it->list->nb_elements++; - - return SUCCESS; + LIST_FREE(self); + self = NULL; } diff --git a/df_datalink/src/util/util.c b/df_datalink/src/util/util.c index f56db1f..02fdb01 100644 --- a/df_datalink/src/util/util.c +++ b/df_datalink/src/util/util.c @@ -3,7 +3,7 @@ /******************************************************************************/ #include #include -#include +// #include #include "util.h" #include "error.h" @@ -11,7 +11,8 @@ /************************** Functions Implementation **************************/ /******************************************************************************/ #ifdef __BITSWAP_TABLE -static uint8_t byte_flipLR[256] = { +static uint8_t byte_flipLR[256] = +{ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, @@ -43,7 +44,8 @@ static uint8_t byte_flipLR[256] = { 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, - 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF}; + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; #endif inline void IO_Out32(uintptr_t addr, uint32_t value)