Project

General

Profile

Revision 1085ef77

ID1085ef7751b530b21865d0ca7d23786578749364
Parent 1b054655
Child 215b2fa6

Added by Thomas Mullins over 11 years ago

Made rfid.c more robust against false negatives

Also changed LED code to be more generally usable, and changed mainbox
to grant access to a particular user id instead of randomly choosing

View differences:

mainbox/tool.c
102 102
      if (status[MB_COIL_NEW]) {
103 103
        tool_read_user(tool);
104 104
        // TODO check actual credentials
105
        if (rand() & 1) {
105
        if (tool->user == 0x023acbf6) {
106 106
          tool_grant_access(tool);
107 107
        } else {
108 108
          tool_deny_access(tool);
toolbox/led.c
9 9
#define OCR (F_CPU / PRESCALE / 1000UL)
10 10
#define ERROR (F_CPU / PRESCALE - OCR * 1000UL)
11 11

  
12
char count;
13
uint16_t period;
12
char blink_count;
13
enum color_t blink_color;
14
uint16_t blink_period;
14 15

  
15 16
uint16_t ms;
16 17
uint16_t error;
17 18

  
19
static void led_color(enum color_t color) {
20
  switch (color) {
21
    case OFF:
22
      led_off();
23
      break;
24
    case RED:
25
      led_red();
26
      break;
27
    case YELLOW:
28
      led_yellow();
29
      break;
30
    case GREEN:
31
      led_green();
32
      break;
33
  }
34
}
35

  
18 36
static void blink() {
19
  count--;
20
  if (count % 2) {
21
    led_yellow();
37
  blink_count--;
38
  if (blink_count % 2) {
39
    led_color(blink_color);
22 40
  } else {
23 41
    led_off();
24 42
  }
......
30 48
    error -= 1000;
31 49
  } else {
32 50
    ms++;
33
    if (ms == period) {
51
    if (ms == blink_period) {
34 52
      blink();
35
      if (count == 0) {
53
      if (blink_count == 0) {
36 54
        TCCR0B = 0;
37 55
      }
38 56
      ms = 0;
......
40 58
  }
41 59
}
42 60

  
43
void led_blink_start(unsigned int period_ms, char n_times) {
44
  led_yellow();
61
void led_blink_start(unsigned int period_ms, char n_times, enum color_t color) {
62

  
45 63
  ms = 0;
46 64
  error = 0;
47
  count = n_times*2-1;
48
  period = period_ms/2;
65

  
66
  blink_count = n_times*2-1;
67
  blink_period = period_ms/2;
68
  blink_color = color;
69
  led_color(color);
70

  
49 71
  OCR0A = OCR;
50 72
  TIMSK = _BV(OCIE0A);
51 73
  TCCR0A = _BV(WGM01);
52 74
  TCCR0B = CLOCK_SEL;
75

  
53 76
}
54 77

  
55 78
char led_blink_done() {
56
  return count == 0;
79
  return blink_count == 0;
57 80
}
toolbox/led.h
3 3

  
4 4
#include <avr/io.h>
5 5

  
6
enum color_t {
7
  OFF, RED, YELLOW, GREEN
8
};
9

  
6 10
static inline void led_init() {DDRC |= _BV(DDC1) | _BV(DDC0);}
7 11
static inline void led_off() {PORTC &= ~(_BV(PC1) | _BV(PC0));}
8 12
static inline void led_red() {PORTC = (PORTC & ~_BV(PC0)) | _BV(PC1);}
......
10 14
static inline void led_green() {PORTC = (PORTC & ~_BV(PC1)) | _BV(PC0);}
11 15

  
12 16
/* Starts LED blinking */ 
13
void led_blink_start(unsigned int period_ms, char n_times);
17
void led_blink_start(unsigned int period_ms, char n_times, enum color_t color);
14 18

  
15 19
/* Returns nonzero if blinking has finished */
16 20
char led_blink_done();
toolbox/main.c
33 33
static inline void tool_enable() {PORTA |= _BV(PA1);}
34 34
static inline void tool_disable() {PORTA &= ~ _BV(PA1);}
35 35

  
36
static char serno_zero(uint8_t *serno) {
36
static inline void serno_zero(uint8_t *serno) {
37 37
  memset(serno, 0, RFID_SERNO_SIZE);
38 38
}
39 39

  
......
131 131
        toolstate = TS_REQ_DIS;
132 132
      } else if (!serno_equal(current_user, latest_reading)) {
133 133
        toolstate = TS_MISSING_ID;
134
        led_blink_start(666, 6);
134
        led_blink_start(666, 15, YELLOW);
135 135
      }
136 136
      break;
137 137

  
toolbox/rfid.c
4 4
#include "rfid.h"
5 5
#include "serial.h"
6 6

  
7
#define RFID_OK 1
7 8
static uint8_t read_cmd[] = {'!', 'R', 'W', 1, 32};
8 9

  
9 10
static int serno_idx;
11
static char n_failures;
10 12
static uint8_t serno[RFID_SERNO_SIZE];
11 13

  
12 14
static void zero_serno() {
......
20 22
  serial_init();
21 23
}
22 24

  
23
void rfid_start_read() {
25
static void restart_read() {
24 26
  serno_idx = -1;
25
  serial_flush();
26 27
  serial_write(read_cmd, sizeof(read_cmd));
27 28
}
28 29

  
30
void rfid_start_read() {
31
  n_failures = 0;
32
  restart_read();
33
}
34

  
29 35
char rfid_poll() {
30 36
  int c;
31 37

  
......
33 39

  
34 40
    if (serno_idx < 0) {
35 41
      if (c != RFID_OK) {
36
        zero_serno();
37
        return 1;
42
        n_failures++;
43
        if (n_failures >= RFID_N_FAILURES) {
44
          zero_serno();
45
          return 1;
46
        } else {
47
          restart_read();
48
          return 0;
49
        }
38 50
      }
39 51
    } else {
40 52
      serno[serno_idx] = c;
toolbox/rfid.h
1 1
#ifndef RFID_H
2 2
#define RFID_H
3 3

  
4
/* First byte back from rfid reader */
5
#define RFID_OK 1
6

  
7 4
/* Bytes in serial number on rfid tags */
8 5
#define RFID_SERNO_SIZE 4
9 6

  
10
/* In rfid_read_safe, it must read the same value RFID_MIN_OK times. If it
11
 * encounters RFID_MAX_ERRS read errors first, it will output all 0's. */
12
#define RFID_MAX_ERRS 10
13
#define RFID_MIN_OK 5
7
/* Number of consective read failures before giving up and returning all 0s */
8
#define RFID_N_FAILURES 5
14 9

  
15 10
/* Should be called before anything else */
16 11
void rfid_init();
......
24 19
 * rfid_get_serno can be called */
25 20
char rfid_poll();
26 21

  
27
/* Attempts to read the serial number multiple times, and only accepts it if it
28
 * is the same every time. Don't use it */
29
void rfid_read_safe();
30

  
31 22
/* Call this only after rfid_poll returns nonzero. This will copy the value it
32 23
 * read into serno, which should be at least RFID_SERNO_SIZE bytes */
33 24
void rfid_get_serno(uint8_t *serno);
34 25

  
35
/* Call this only after rfid_poll returns nonzero. Returns 1 if serno matches
36
 * the internal buffer of the most recently read serial number */
37
char rfid_check_serno(uint8_t *serno);
38

  
39 26
/* Call this only after rfid_poll returns nonzero. Returns 1 if the internal
40 27
 * buffer is nonzero, meaning a serial number was successfully read from an
41 28
 * rfid tag */

Also available in: Unified diff