]> www.fi.muni.cz Git - openparking.git/blobdiff - firmware/firmware.c
Infinite reads handling
[openparking.git] / firmware / firmware.c
index 8e973510ae55d1577ecc28b2ec2b413d85d59f43..7fbcdf18601b65f661edfb46b9cced58d937a72a 100644 (file)
 #define thresholds     (hold_regs+1)
 #define led1_sensors   (hold_regs[13])
 #define led2_sensors   (hold_regs[14])
+#define long_as_free   (hold_regs[15])
+#define long_thr       (hold_regs[16])
 
 #define led_bitmap     (hold_regs[MB_N_HOLD_REGS_EEPROM])
 #define distances      (hold_regs+MB_N_HOLD_REGS_EEPROM+1)
 #define free_bitmap    (hold_regs[MB_N_HOLD_REGS_EEPROM+13])
 #define err_bitmap     (hold_regs[MB_N_HOLD_REGS_EEPROM+14])
+#define long_bitmap    (hold_regs[MB_N_HOLD_REGS_EEPROM+15])
 #define max_distances  (hold_regs+MB_N_HOLD_REGS_EEPROM+21)
+#define err_counts     (hold_regs+MB_N_HOLD_REGS_EEPROM+41)
 
 static void pull_trigger(uint8_t trig)
 {
@@ -104,16 +108,33 @@ static void do_measurement(unsigned char trig)
                }
        }
 
-       for (i = 0; i < N_TRIG_SENSORS; i++)
-               if (to_start & (1 << i))
-                       distances[trig*N_TRIG_SENSORS + i] = -1;
-               else if (to_measure & (1 << i))
+       for (i = 0; i < N_TRIG_SENSORS; i++) {
+               uint8_t off = trig*N_TRIG_SENSORS + i;
+
+               if (to_start & (1 << i)) { // echo not received
+                       uint16_t err_count = err_counts[off] & 0xFF;
+                       if (distances[off] != -1 && err_count < 255) {
+                               err_count++;
+                               err_counts[off] = (err_counts[off] & 0xFF00)
+                                       | err_count;
+                       }
+                       distances[off] = -1;
+               } else if (to_measure & (1 << i)) { // echo pulse too long
+                       uint16_t err_count = err_counts[off] >> 8;
+
+                       if (err_count < 255) {
+                               err_count++;
+                               err_counts[off] = (err_counts[off] & 0x00FF)
+                                       | (err_count << 8);
+                       }
                        /*
                         * If the echo pulse is too long, do not treat it
-                        * as error, just count it as maximum length.
+                        * as error, just count it as maximum length
+                        * and notify the state in the bitmap.
                         */
-                       distances[trig*N_TRIG_SENSORS + i]
-                               = now - starttimes[i];
+                       distances[off] = now - starttimes[i];
+               }
+       }
 }
 
 static void led_set(uint8_t led, uint8_t state)
@@ -170,15 +191,15 @@ static void leds_update()
        }
 
        if (led_bitmap & 8) {
-               DDRB |= _BV(PB5);
-       } else {
                DDRB &= ~_BV(PB5);
+       } else {
+               DDRB |= _BV(PB5);
        }
 }
 
 static void eval_bitmaps()
 {
-       uint16_t free_b = 0, err_b = 0, mask;
+       uint16_t free_b = 0, err_b = 0, long_b = 0, mask;
        uint8_t i;
 
        for (i = 0; i < N_SENSORS; i++) {
@@ -188,13 +209,21 @@ static void eval_bitmaps()
                        if (distances[i] == -1) {
                                err_b |= mask;
                        } else if (distances[i] > thresholds[i]) {
-                               free_b |= mask;
+                               if (long_thr && distances[i] > long_thr) {
+                                       long_b |= mask;
+                                       if (long_as_free & mask) {
+                                               free_b |= mask;
+                                       }
+                               } else {
+                                       free_b |= mask;
+                               }
                        }
                }
        }
 
        free_bitmap = free_b;
        err_bitmap  = err_b;
+       long_bitmap = long_b;
 
        if (led1_sensors) {
                if (led1_sensors & err_bitmap) {