]> sigrok.org Git - libsigrok.git/blob - src/sw_limits.c
scpi-pps: Add a missing "break" in config_get().
[libsigrok.git] / src / sw_limits.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2016 Lars-Peter Clausen <lars@metafoo.de>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * @file
22  * Software limits helper functions
23  * @internal
24  */
25
26 #include <config.h>
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <libsigrok/libsigrok.h>
32 #include "libsigrok-internal.h"
33
34 #define LOG_PREFIX "sw_limits"
35
36 /**
37  * Initialize a software limit instance
38  *
39  * Must be called before any other operations are performed on a struct
40  * sr_sw_limits and should typically be called after the data structure has been
41  * allocated.
42  *
43  * @param limits the software limit instance to initialize
44  */
45 SR_PRIV void sr_sw_limits_init(struct sr_sw_limits *limits)
46 {
47         limits->limit_samples = 0;
48         limits->limit_msec = 0;
49 }
50
51 /**
52  * Get software limit configuration
53  *
54  * Retrieve the currently configured software limit for the specified key.
55  * Should be called from the drivers config_get() callback.
56  *
57  * @param limits software limit instance
58  * @param key config item key
59  * @param data config item data
60  * @return SR_ERR_NA if @p key is not a supported limit, SR_OK otherwise
61  */
62 SR_PRIV int sr_sw_limits_config_get(struct sr_sw_limits *limits, uint32_t key,
63         GVariant **data)
64 {
65         switch (key) {
66         case SR_CONF_LIMIT_SAMPLES:
67                 *data = g_variant_new_uint64(limits->limit_samples);
68                 break;
69         case SR_CONF_LIMIT_MSEC:
70                 *data = g_variant_new_uint64(limits->limit_msec / 1000);
71                 break;
72         default:
73                 return SR_ERR_NA;
74         }
75
76         return SR_OK;
77 }
78
79 /**
80  * Set software limit configuration
81  *
82  * Configure software limit for the specified key. Should be called from the
83  * drivers config_set() callback.
84  *
85  * @param limits software limit instance
86  * @param key config item key
87  * @param data config item data
88  * @return SR_ERR_NA if @p key is not a supported limit, SR_OK otherwise
89  */
90 SR_PRIV int sr_sw_limits_config_set(struct sr_sw_limits *limits, uint32_t key,
91         GVariant *data)
92 {
93         switch (key) {
94         case SR_CONF_LIMIT_SAMPLES:
95                 limits->limit_samples = g_variant_get_uint64(data);
96                 break;
97         case SR_CONF_LIMIT_MSEC:
98                 limits->limit_msec = g_variant_get_uint64(data) * 1000;
99                 break;
100         default:
101                 return SR_ERR_NA;
102         }
103
104         return SR_OK;
105 }
106
107 /**
108  * Start a new data acquisition session
109  *
110  * Resets the internal accounting for all software limits. Usually should be
111  * called from the drivers acquisition_start() callback.
112  *
113  * @param limits software limits instance
114  */
115 SR_PRIV void sr_sw_limits_acquisition_start(struct sr_sw_limits *limits)
116 {
117         limits->samples_read = 0;
118         limits->start_time = g_get_monotonic_time();
119 }
120
121 /**
122  * Check if any of the configured software limits has been reached
123  *
124  * Usually should be called at the end of the drivers work function after all
125  * processing has been done.
126  *
127  * @param limits software limits instance
128  * @returns TRUE if any of the software limits has been reached and the driver
129  *               should stop data acquisition, otherwise FALSE.
130  */
131 SR_PRIV gboolean sr_sw_limits_check(struct sr_sw_limits *limits)
132 {
133         if (limits->limit_samples) {
134                 if (limits->samples_read >= limits->limit_samples) {
135                         sr_dbg("Requested number of samples (%" PRIu64
136                                ") reached.", limits->limit_samples);
137                         return TRUE;
138                 }
139         }
140
141         if (limits->limit_msec) {
142                 guint64 now;
143                 now = g_get_monotonic_time();
144                 if (now > limits->start_time &&
145                         now - limits->start_time > limits->limit_msec) {
146                         sr_dbg("Requested sampling time (%" PRIu64
147                                "ms) reached.", limits->limit_msec / 1000);
148                         return TRUE;
149                 }
150         }
151
152         return FALSE;
153 }
154
155 /**
156  * Update the amount samples that have been read
157  *
158  * Update the amount of samples that have been read in the current data
159  * acquisition run. For each invocation @p samples_read will be accumulated and
160  * once the configured sample limit has been reached sr_sw_limits_check() will
161  * return TRUE.
162  *
163  * @param limits software limits instance
164  * @param samples_read the amount of samples that have been read
165  */
166 SR_PRIV void sr_sw_limits_update_samples_read(struct sr_sw_limits *limits,
167         uint64_t samples_read)
168 {
169         limits->samples_read += samples_read;
170 }