summaryrefslogtreecommitdiff
path: root/common/util.c
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2013-08-07 15:36:21 -0700
committerChromeBot <chrome-bot@google.com>2013-08-09 15:44:09 -0700
commit0c8c2e453ab3960f315050fbb9808f438398624f (patch)
tree472f7677ac3738338bea389a42d9c1b7f6703bda /common/util.c
parent71a3bb0c0746d17e55e1e08322258e555ac80682 (diff)
downloadchrome-ec-0c8c2e453ab3960f315050fbb9808f438398624f.tar.gz
Add abstract "cond_t" type to detect state transitions.
We often need to watch for transitions between one state and another, so that we can issue warnings or take action ONCE. This abstracts that "have I already reacted to this" stuff into a single set of functions. For example, this code reads a GPIO every time through the loop, but it only generates an event when the GPIO value changes from 0 to 1: cond_t c; cond_init_false(&c); while(1) { int val = read_some_gpio(); cond_set(&c, val); if (cond_went_true(&c)) host_event(SOMETHING_HAPPENED); sleep(1); } BUG=none BRANCH=falco,peppy TEST=manual make BOARD=falco runtests Change-Id: I42393fcf3c4eb71b9551118a0f442d55c0691315 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/65071
Diffstat (limited to 'common/util.c')
-rw-r--r--common/util.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/common/util.c b/common/util.c
index 5ccebeb063..0d7bff2710 100644
--- a/common/util.c
+++ b/common/util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -272,3 +272,59 @@ int uint64divmod(uint64_t *n, int d)
*n = q;
return r;
}
+
+
+/****************************************************************************/
+/* stateful conditional stuff */
+
+enum cond_internal_bits {
+ COND_CURR_MASK = (1 << 0), /* current value */
+ COND_RISE_MASK = (1 << 1), /* set if 0->1 */
+ COND_FALL_MASK = (1 << 2), /* set if 1->0 */
+};
+
+void cond_init(cond_t *c, int val)
+{
+ if (val)
+ *c = COND_CURR_MASK;
+ else
+ *c = 0;
+}
+
+int cond_is(cond_t *c, int val)
+{
+ if (val)
+ return *c & COND_CURR_MASK;
+ else
+ return !(*c & COND_CURR_MASK);
+}
+
+
+void cond_set(cond_t *c, int val)
+{
+ if (val && cond_is(c, 0))
+ *c |= COND_RISE_MASK;
+ else if (!val && cond_is(c, 1))
+ *c |= COND_FALL_MASK;
+ if (val)
+ *c |= COND_CURR_MASK;
+ else
+ *c &= ~COND_CURR_MASK;
+}
+
+
+int cond_went(cond_t *c, int val)
+{
+ int ret;
+
+ if (val) {
+ ret = *c & COND_RISE_MASK;
+ *c &= ~COND_RISE_MASK;
+ }
+ else {
+ ret = *c & COND_FALL_MASK;
+ *c &= ~COND_FALL_MASK;
+ }
+
+ return ret;
+}