Zephyr API 3.6.99
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
6#ifndef INCLUDE_ZEPHYR_SYS_LINEAR_RANGE_H_
7#define INCLUDE_ZEPHYR_SYS_LINEAR_RANGE_H_
8
9#include <errno.h>
10#include <stdint.h>
11#include <stdlib.h>
12
13#include <zephyr/sys/util.h>
14
15#ifdef __cplusplus
16extern "C" {
17#endif
18
71
80#define LINEAR_RANGE_INIT(_min, _step, _min_idx, _max_idx) \
81 { \
82 .min = (_min), \
83 .step = (_step), \
84 .min_idx = (_min_idx), \
85 .max_idx = (_max_idx), \
86 }
87
96{
97 return r->max_idx - r->min_idx + 1U;
98}
99
109 const struct linear_range *r, size_t r_cnt)
110{
111 uint32_t values = 0U;
112
113 for (size_t i = 0U; i < r_cnt; i++) {
114 values += linear_range_values_count(&r[i]);
115 }
116
117 return values;
118}
119
128{
129 return r->min + (int32_t)(r->step * (r->max_idx - r->min_idx));
130}
131
142static inline int linear_range_get_value(const struct linear_range *r,
143 uint16_t idx, int32_t *val)
144{
145 if ((idx < r->min_idx) || (idx > r->max_idx)) {
146 return -EINVAL;
147 }
148
149 *val = r->min + (int32_t)(r->step * (idx - r->min_idx));
150
151 return 0;
152}
153
165static inline int linear_range_group_get_value(const struct linear_range *r,
166 size_t r_cnt, uint16_t idx,
167 int32_t *val)
168{
169 int ret = -EINVAL;
170
171 for (size_t i = 0U; (ret != 0) && (i < r_cnt); i++) {
172 ret = linear_range_get_value(&r[i], idx, val);
173 }
174
175 return ret;
176}
177
193static inline int linear_range_get_index(const struct linear_range *r,
194 int32_t val, uint16_t *idx)
195{
196 if (val < r->min) {
197 *idx = r->min_idx;
198 return -ERANGE;
199 }
200
201 if (val > linear_range_get_max_value(r)) {
202 *idx = r->max_idx;
203 return -ERANGE;
204 }
205
206 if (r->step == 0U) {
207 *idx = r->min_idx;
208 } else {
209 *idx = r->min_idx + DIV_ROUND_UP((uint32_t)(val - r->min),
210 r->step);
211 }
212
213 return 0;
214}
215
231static inline int linear_range_group_get_index(const struct linear_range *r,
232 size_t r_cnt, int32_t val,
233 uint16_t *idx)
234{
235 for (size_t i = 0U; i < r_cnt; i++) {
236 if ((val > linear_range_get_max_value(&r[i])) &&
237 (i < (r_cnt - 1U))) {
238 continue;
239 }
240
241 return linear_range_get_index(&r[i], val, idx);
242 }
243
244 return -EINVAL;
245}
246
265static inline int linear_range_get_win_index(const struct linear_range *r,
266 int32_t val_min, int32_t val_max,
267 uint16_t *idx)
268{
270
271 if ((val_max < r->min) || (val_min > r_max)) {
272 return -EINVAL;
273 }
274
275 if (val_min < r->min) {
276 *idx = r->min_idx;
277 return -ERANGE;
278 }
279
280 if (val_max > r_max) {
281 *idx = r->max_idx;
282 return -ERANGE;
283 }
284
285 if (r->step == 0U) {
286 *idx = r->min_idx;
287 return 0;
288 }
289
290 *idx = r->min_idx + DIV_ROUND_UP((uint32_t)(val_min - r->min), r->step);
291 if ((r->min + r->step * (*idx - r->min_idx)) > val_max) {
292 return -EINVAL;
293 }
294
295 return 0;
296}
297
318static inline int linear_range_group_get_win_index(const struct linear_range *r,
319 size_t r_cnt,
320 int32_t val_min,
321 int32_t val_max,
322 uint16_t *idx)
323{
324 for (size_t i = 0U; i < r_cnt; i++) {
325 if (val_min > linear_range_get_max_value(&r[i])) {
326 continue;
327 }
328
329 return linear_range_get_win_index(&r[i], val_min, val_max, idx);
330 }
331
332 return -EINVAL;
333}
334
337#ifdef __cplusplus
338}
339#endif
340
341#endif /* INCLUDE_ZEPHYR_SYS_LINEAR_RANGE_H_ */
workaround assembler barfing for ST r
Definition asm-macro-32-bit-gnu.h:24
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:318
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:108
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:265
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:142
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:193
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:231
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:165
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:95
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:127
#define DIV_ROUND_UP(n, d)
Divide and round up.
Definition util.h:359
#define EINVAL
Invalid argument.
Definition errno.h:60
#define ERANGE
Result too large.
Definition errno.h:72
__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:61
int32_t min
Minimum value.
Definition linear_range.h:63
uint16_t min_idx
Minimum index (must be <= maximum index).
Definition linear_range.h:67
uint16_t max_idx
Maximum index (must be >= minimum index).
Definition linear_range.h:69
uint32_t step
Step value.
Definition linear_range.h:65
Misc utilities.