Switch from GPLv2 to GPLv2+
[fw/altos] / src / kernel / ao_pyro.c
index 0b286466fa3a7495d91406bedb91c1ebbe6cd3e9..c9920ab335cd681369ad8e78e893f8b1bd49b021 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -252,7 +253,7 @@ ao_pyro_check(void)
        struct ao_pyro  *pyro;
        uint8_t         p, any_waiting;
        uint16_t        fire = 0;
-       
+
        any_waiting = 0;
        for (p = 0; p < AO_PYRO_NUM; p++) {
                pyro = &ao_config.pyro[p];
@@ -288,6 +289,16 @@ ao_pyro_check(void)
                 * the delay to expire
                 */
                if (pyro->delay_done) {
+
+                       /* Check to make sure the required conditions
+                        * remain valid. If not, inhibit the channel
+                        * by setting the fired bit
+                        */
+                       if (!ao_pyro_ready(pyro)) {
+                               pyro->fired = 1;
+                               continue;
+                       }
+
                        if ((int16_t) (ao_time() - pyro->delay_done) < 0)
                                continue;
                }
@@ -365,9 +376,7 @@ ao_pyro(void)
                ao_sleep(&ao_flight_state);
 
        for (;;) {
-               ao_alarm(AO_MS_TO_TICKS(100));
-               ao_sleep(&ao_pyro_wakeup);
-               ao_clear_alarm();
+               ao_sleep_for(&ao_pyro_wakeup, AO_MS_TO_TICKS(100));
                if (ao_flight_state >= ao_flight_landed)
                        break;
                any_waiting = ao_pyro_check();
@@ -465,7 +474,7 @@ ao_pyro_set(void)
                printf ("invalid pyro channel %d\n", p);
                return;
        }
-       pyro_tmp.flags = 0;
+       memset(&pyro_tmp, '\0', sizeof (pyro_tmp));
        for (;;) {
                ao_cmd_white();
                if (ao_cmd_lex_c == '\n')
@@ -489,13 +498,26 @@ ao_pyro_set(void)
                }
                pyro_tmp.flags |= ao_pyro_values[v].flag;
                if (ao_pyro_values[v].offset != NO_VALUE) {
+                       uint8_t negative = 0;
+                       ao_cmd_white();
+                       if (ao_cmd_lex_c == '-') {
+                               negative = 1;
+                               ao_cmd_lex();
+                       }
                        ao_cmd_decimal();
                        if (ao_cmd_status != ao_cmd_success)
                                return;
-                       if (ao_pyro_values[v].flag & AO_PYRO_8_BIT_VALUE)
+                       if (ao_pyro_values[v].flag & AO_PYRO_8_BIT_VALUE) {
+                               if (negative) {
+                                       ao_cmd_status = ao_cmd_syntax_error;
+                                       return;
+                               }
                                *((uint8_t *) ((char *) &pyro_tmp + ao_pyro_values[v].offset)) = ao_cmd_lex_i;
-                       else
+                       } else {
+                               if (negative)
+                                       ao_cmd_lex_i = -ao_cmd_lex_i;
                                *((int16_t *) ((char *) &pyro_tmp + ao_pyro_values[v].offset)) = ao_cmd_lex_i;
+                       }
                }
        }
        _ao_config_edit_start();