Project

General

Profile

Statistics
| Branch: | Revision:

root / toolbox / main.c @ f5d1f56a

History | View | Annotate | Download (5.72 KB)

1
#include <stdint.h>
2
#include <string.h>
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include "mb.h"
6
#include "mbport.h"
7
#include "tooltron_mb.h"
8
#include "rfid.h"
9
#include "led.h"
10

    
11
enum toolstate_t {
12
  TS_INIT,
13
  TS_OFF,
14
  TS_WAIT_ACCESS,
15
  TS_DENY,
16
  TS_REQ_DIS,
17
  TS_MISSING_ID,
18
  TS_ON
19
};
20

    
21
static enum toolstate_t toolstate = TS_INIT;
22
static uint8_t coils;
23
static uint8_t latest_reading[RFID_SERNO_SIZE];
24
static uint8_t current_user[RFID_SERNO_SIZE];
25

    
26
static inline void set_coil(char coil, char bit) {
27
  coils = (coils & ~(1 << coil)) | (bit << coil);
28
}
29
static inline char get_coil(char coil) {
30
  return (coils >> coil) & 1;
31
}
32

    
33
static inline void tool_init() {DDRA |= _BV(DDA1);}
34
static inline void tool_enable() {PORTA |= _BV(PA1);}
35
static inline void tool_disable() {PORTA &= ~ _BV(PA1);}
36

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

    
41
static char serno_is_nonzero(uint8_t *serno) {
42
  int i;
43
  for (i = 0; i < RFID_SERNO_SIZE; i++) {
44
    if (serno[i]) {
45
      return 1;
46
    }
47
  }
48
  return 0;
49
}
50

    
51
static char serno_equal(uint8_t *a, uint8_t *b) {
52
  return memcmp(a, b, RFID_SERNO_SIZE) == 0;
53
}
54

    
55
static void serno_cpy(uint8_t *dest, uint8_t *src) {
56
  memcpy(dest, src, RFID_SERNO_SIZE);
57
}
58

    
59
static void tool_main() {
60

    
61
  switch (toolstate) {
62

    
63
    case TS_INIT:
64
      if (get_coil(MB_COIL_INIT)) {
65
        set_coil(MB_COIL_NEW, 0);
66
        set_coil(MB_COIL_EN, 0);
67
        set_coil(MB_COIL_REQ_DIS, 0);
68
        toolstate = TS_OFF;
69
      }
70
      break;
71

    
72
    case TS_OFF:
73
      led_off();
74
      if (serno_is_nonzero(latest_reading)) {
75
        serno_cpy(current_user, latest_reading);
76
        set_coil(MB_COIL_NEW, 1);
77
        toolstate = TS_WAIT_ACCESS;
78
      }
79
      break;
80

    
81
    case TS_WAIT_ACCESS:
82
      led_yellow();
83
      if (get_coil(MB_COIL_EN)) {
84
        tool_enable();
85
        toolstate = TS_ON;
86
      } else if (!get_coil(MB_COIL_NEW)) {
87
        toolstate = TS_DENY;
88
      }
89
      break;
90

    
91
    case TS_DENY:
92
      led_red();
93
      if (!serno_equal(current_user, latest_reading)) {
94
        toolstate = TS_OFF;
95
        serno_zero(current_user);
96
      }
97

    
98
    case TS_REQ_DIS:
99
      if (!get_coil(MB_COIL_EN)) {
100
        tool_disable();
101
        toolstate = TS_OFF;
102
      } else if (!get_coil(MB_COIL_REQ_DIS)) {
103
        toolstate = TS_ON;
104
      } else {
105
        // TODO blink yellow for 10 seconds or something
106
        set_coil(MB_COIL_EN, 0);
107
        set_coil(MB_COIL_REQ_DIS, 0);
108
        tool_disable();
109
        serno_zero(current_user);
110
        toolstate = TS_OFF;
111
      }
112
      break;
113

    
114
    case TS_MISSING_ID:
115
      if (!get_coil(MB_COIL_EN)) {
116
        tool_disable();
117
        toolstate = TS_OFF;
118
      } else if (get_coil(MB_COIL_REQ_DIS)) {
119
        toolstate = TS_REQ_DIS;
120
      } else if (serno_equal(current_user, latest_reading)) {
121
        toolstate = TS_ON;
122
      } else {
123
        if (led_blink_done()) {
124
          set_coil(MB_COIL_EN, 0);
125
          tool_disable();
126
          serno_zero(current_user);
127
          toolstate = TS_OFF;
128
        }
129
      }
130
      break;
131

    
132
    case TS_ON:
133
      led_green();
134
      if (!get_coil(MB_COIL_EN)) {
135
        tool_disable();
136
        serno_zero(current_user);
137
        toolstate = TS_OFF;
138
      } else if(get_coil(MB_COIL_REQ_DIS)) {
139
        toolstate = TS_REQ_DIS;
140
      } else if (!serno_equal(current_user, latest_reading)) {
141
        toolstate = TS_MISSING_ID;
142
        led_blink_start(666, 15, YELLOW);
143
      }
144
      break;
145

    
146
  }
147

    
148
}
149

    
150
eMBErrorCode eMBRegCoilsCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils,
151
    eMBRegisterMode mode) {
152

    
153
  addr--;
154

    
155
  if (addr+n_coils > N_COILS) {
156
    return MB_ENOREG;
157
  }
158

    
159
  if (mode == MB_REG_WRITE) {
160

    
161
    switch (addr) {
162

    
163
      case MB_COIL_NEW:
164
        /* nop */
165
        reg_buf[0] >>= 1;
166
        n_coils--;
167
        if (n_coils == 0) {
168
          return MB_ENOERR;
169
        }
170

    
171
      case MB_COIL_EN:
172
        set_coil(MB_COIL_NEW, 0);
173
        set_coil(MB_COIL_EN, reg_buf[0] & 1);
174
        reg_buf[0] >>= 1;
175
        n_coils--;
176
        if (n_coils == 0) {
177
          return MB_ENOERR;
178
        }
179

    
180
      case MB_COIL_REQ_DIS:
181
        set_coil(MB_COIL_REQ_DIS, reg_buf[0] & 1);
182
        reg_buf[0] >>= 1;
183
        n_coils--;
184
        if (n_coils == 0) {
185
          return MB_ENOERR;
186
        }
187

    
188
      case MB_COIL_INIT:
189
        set_coil(MB_COIL_INIT, reg_buf[0] & 1);
190
        reg_buf[0] >>= 1;
191
        n_coils--;
192
        if (n_coils == 0) {
193
          return MB_ENOERR;
194
        }
195
    }
196

    
197
  } else if (mode == MB_REG_READ) {
198

    
199
    reg_buf[0] = (coils >> addr) & ((1 << n_coils) - 1);
200
    return MB_ENOERR;
201

    
202
  }
203

    
204
  return MB_EIO;
205
}
206

    
207
eMBErrorCode eMBRegDiscreteCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils) {
208
  return MB_ENOREG;
209
}
210

    
211
eMBErrorCode eMBRegInputCB(UCHAR *reg_buf, USHORT addr, USHORT n_regs) {
212

    
213
  addr--;
214

    
215
  switch (addr) {
216

    
217
    case MB_INP_SERNOL:
218
      *reg_buf++ = current_user[0];
219
      *reg_buf++ = current_user[1];
220
      n_regs--;
221
      if (n_regs == 0) {
222
        return MB_ENOERR;
223
      }
224

    
225
    case MB_INP_SERNOH:
226
      *reg_buf++ = current_user[2];
227
      *reg_buf++ = current_user[3];
228
      n_regs--;
229
      if (n_regs == 0) {
230
        return MB_ENOERR;
231
      }
232

    
233
    case MB_INP_CURRENT:
234
      *reg_buf++ = 0;
235
      *reg_buf++ = 0;
236
      n_regs--;
237
      if (n_regs == 0) {
238
        return MB_ENOERR;
239
      }
240

    
241
    default:
242
      return MB_ENOREG;
243
  }
244
}
245

    
246
eMBErrorCode eMBRegHoldingCB(UCHAR *reg_buf, USHORT addr, USHORT n_regs,
247
    eMBRegisterMode mode) {
248
  if (mode == MB_REG_WRITE) {
249
    return MB_ENOREG;
250
  } else if (mode == MB_REG_READ) {
251
    return MB_ENOREG;
252
  } else {
253
    return MB_EIO;
254
  }
255
}
256

    
257
int main() {
258

    
259
  led_init();
260
  tool_init();
261
  rfid_init();
262

    
263
  eMBInit(MB_RTU, SLAVE_ADDR, 0, MB_BAUD, MB_PAR_NONE);
264
  eMBEnable();
265

    
266
  sei();
267

    
268
  rfid_start_read();
269
  while (1) {
270
    if (rfid_poll()) {
271
      rfid_get_serno(latest_reading);
272
      rfid_start_read();
273
    }
274
    tool_main();
275
    eMBPoll();
276
    _delay_ms(50);
277
  }
278

    
279
  return 0;
280
}