Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
linear_range.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022, Nordic Semiconductor ASA
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
11
12#ifndef ZEPHYR_INCLUDE_SYS_LINEAR_RANGE_H_
13#define ZEPHYR_INCLUDE_SYS_LINEAR_RANGE_H_
14
15#include <errno.h>
16#include <stdint.h>
17#include <stdlib.h>
18
19#include <zephyr/sys/util.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
67
79
88#define LINEAR_RANGE_INIT(_min, _step, _min_idx, _max_idx) \
89 { \
90 .min = (_min), \
91 .step = (_step), \
92 .min_idx = (_min_idx), \
93 .max_idx = (_max_idx), \
94 }
95
104{
105 return r->max_idx - r->min_idx + 1U;
106}
107
117 const struct linear_range *r, size_t r_cnt)
118{
119 uint32_t values = 0U;
120
121 for (size_t i = 0U; i < r_cnt; i++) {
122 values += linear_range_values_count(&r[i]);
123 }
124
125 return values;
126}
127
136{
137 return r->min + (int32_t)(r->step * (r->max_idx - r->min_idx));
138}
139
150static inline int linear_range_get_value(const struct linear_range *r,
151 uint16_t idx, int32_t *val)
152{
153 if ((idx < r->min_idx) || (idx > r->max_idx)) {
154 return -EINVAL;
155 }
156
157 *val = r->min + (int32_t)(r->step * (idx - r->min_idx));
158
159 return 0;
160}
161
173static inline int linear_range_group_get_value(const struct linear_range *r,
174 size_t r_cnt, uint16_t idx,
175 int32_t *val)
176{
177 int ret = -EINVAL;
178
179 for (size_t i = 0U; (ret != 0) && (i < r_cnt); i++) {
180 ret = linear_range_get_value(&r[i], idx, val);
181 }
182
183 return ret;
184}
185
201static inline int linear_range_get_index(const struct linear_range *r,
202 int32_t val, uint16_t *idx)
203{
204 if (val < r->min) {
205 *idx = r->min_idx;
206 return -ERANGE;
207 }
208
209 if (val > linear_range_get_max_value(r)) {
210 *idx = r->max_idx;
211 return -ERANGE;
212 }
213
214 if (r->step == 0U) {
215 *idx = r->min_idx;
216 } else {
217 *idx = r->min_idx + DIV_ROUND_UP((uint32_t)(val - r->min),
218 r->step);
219 }
220
221 return 0;
222}
223
239static inline int linear_range_group_get_index(const struct linear_range *r,
240 size_t r_cnt, int32_t val,
241 uint16_t *idx)
242{
243 for (size_t i = 0U; i < r_cnt; i++) {
244 if ((val > linear_range_get_max_value(&r[i])) &&
245 (i < (r_cnt - 1U))) {
246 continue;
247 }
248
249 return linear_range_get_index(&r[i], val, idx);
250 }
251
252 return -EINVAL;
253}
254
273static inline int linear_range_get_win_index(const struct linear_range *r,
274 int32_t val_min, int32_t val_max,
275 uint16_t *idx)
276{
278
279 if ((val_max < r->min) || (val_min > r_max)) {
280 return -EINVAL;
281 }
282
283 if (val_min < r->min) {
284 *idx = r->min_idx;
285 return -ERANGE;
286 }
287
288 if (val_max > r_max) {
289 *idx = r->max_idx;
290 return -ERANGE;
291 }
292
293 if (r->step == 0U) {
294 *idx = r->min_idx;
295 return 0;
296 }
297
298 *idx = r->min_idx + DIV_ROUND_UP((uint32_t)(val_min - r->min), r->step);
299 if ((r->min + r->step * (*idx - r->min_idx)) > val_max) {
300 return -EINVAL;
301 }
302
303 return 0;
304}
305
326static inline int linear_range_group_get_win_index(const struct linear_range *r,
327 size_t r_cnt,
328 int32_t val_min,
329 int32_t val_max,
330 uint16_t *idx)
331{
332 for (size_t i = 0U; i < r_cnt; i++) {
333 if (val_min > linear_range_get_max_value(&r[i])) {
334 continue;
335 }
336
337 return linear_range_get_win_index(&r[i], val_min, val_max, idx);
338 }
339
340 return -EINVAL;
341}
342
344
345#ifdef __cplusplus
346}
347#endif
348
349#endif /* ZEPHYR_INCLUDE_SYS_LINEAR_RANGE_H_ */
workaround assembler barfing for ST r
Definition asm-macro-32-bit-gnu.h:27
System error numbers.
static int linear_range_group_get_win_index(const struct linear_range *r, size_t r_cnt, int32_t val_min, int32_t val_max, uint16_t *idx)
Obtain index in a group given a value that must be within a window of values.
Definition linear_range.h:326
static uint32_t linear_range_group_values_count(const struct linear_range *r, size_t r_cnt)
Obtain the number of values representable by a group of linear ranges.
Definition linear_range.h:116
static int linear_range_get_win_index(const struct linear_range *r, int32_t val_min, int32_t val_max, uint16_t *idx)
Obtain index given a window of values.
Definition linear_range.h:273
static int linear_range_get_value(const struct linear_range *r, uint16_t idx, int32_t *val)
Obtain value given a linear range index.
Definition linear_range.h:150
static int linear_range_get_index(const struct linear_range *r, int32_t val, uint16_t *idx)
Obtain index given a value.
Definition linear_range.h:201
static int linear_range_group_get_index(const struct linear_range *r, size_t r_cnt, int32_t val, uint16_t *idx)
Obtain index in a group given a value.
Definition linear_range.h:239
static int linear_range_group_get_value(const struct linear_range *r, size_t r_cnt, uint16_t idx, int32_t *val)
Obtain value in a group given a linear range index.
Definition linear_range.h:173
static uint32_t linear_range_values_count(const struct linear_range *r)
Obtain the number of values representable in a linear range.
Definition linear_range.h:103
static int32_t linear_range_get_max_value(const struct linear_range *r)
Obtain the maximum value representable by a linear range.
Definition linear_range.h:135
#define DIV_ROUND_UP(n, d)
Divide and round up.
Definition util.h:348
#define EINVAL
Invalid argument.
Definition errno.h:61
#define ERANGE
Result too large.
Definition errno.h:73
#define min(a, b)
Return smaller value of two provided expressions.
Definition minmax.h:81
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__INT32_TYPE__ int32_t
Definition stdint.h:74
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
Linear range.
Definition linear_range.h:69
int32_t min
Minimum value.
Definition linear_range.h:71
uint16_t min_idx
Minimum index (must be <= maximum index).
Definition linear_range.h:75
uint16_t max_idx
Maximum index (must be >= minimum index).
Definition linear_range.h:77
uint32_t step
Step value.
Definition linear_range.h:73
Misc utilities.