Project

General

Profile

Statistics
| Branch: | Revision:

root / toolbox / main.c @ master

History | View | Annotate | Download (7.37 KB)

1 20e5429c Tom Mullins
#include <stdint.h>
2 12ea39cc Tom Mullins
#include <string.h>
3
#include <avr/io.h>
4 20e5429c Tom Mullins
#include <util/delay.h>
5
#include "mb.h"
6
#include "mbport.h"
7
#include "tooltron_mb.h"
8 9b2b6d91 Tom Mullins
#include "rfid.h"
9 532ba0bd Tom Mullins
#include "led.h"
10 10936c07 Tom Mullins
#include "current.h"
11 94548bf4 Tom Mullins
#include "time.h"
12 20e5429c Tom Mullins
13 a96c5547 Tom Mullins
#if TOOL_ADDRESS < 0
14
#error Please define TOOL_ADDRESS
15
#endif
16
17 12ea39cc Tom Mullins
enum toolstate_t {
18
  TS_INIT,
19
  TS_OFF,
20
  TS_WAIT_ACCESS,
21 f5d1f56a Tom Mullins
  TS_DENY,
22 12ea39cc Tom Mullins
  TS_REQ_DIS,
23
  TS_MISSING_ID,
24 e2a3c71f Tom Mullins
  TS_ON,
25
  TS_OVER_CURRENT
26 12ea39cc Tom Mullins
};
27
28
static enum toolstate_t toolstate = TS_INIT;
29 6ca98a3f Tom Mullins
static uint8_t coils;
30 1b054655 Tom Mullins
static uint8_t latest_reading[RFID_SERNO_SIZE];
31 6ca98a3f Tom Mullins
static uint8_t current_user[RFID_SERNO_SIZE];
32 10936c07 Tom Mullins
static uint16_t current;
33 f4df665c Tom Mullins
//static uint16_t current_max_warn, current_max_hard;
34 208a6fb2 Tom Mullins
35 e2a3c71f Tom Mullins
// watch for current spike when tool turns on
36
#define CURRENT_STARTUP_THRESH   10
37
#define CURRENT_STARTUP_TIMEOUT 200 // ms
38
static uint8_t current_startup_timeout;
39
static uint16_t current_startup_value;
40
41 208a6fb2 Tom Mullins
static inline void set_coil(char coil, char bit) {
42 6ca98a3f Tom Mullins
  coils = (coils & ~(1 << coil)) | (bit << coil);
43 208a6fb2 Tom Mullins
}
44 12ea39cc Tom Mullins
static inline char get_coil(char coil) {
45
  return (coils >> coil) & 1;
46
}
47
48
static inline void tool_init() {DDRA |= _BV(DDA1);}
49
static inline void tool_enable() {PORTA |= _BV(PA1);}
50 76915f20 Tom Mullins
static inline void tool_disable() {PORTA &= ~ _BV(PA1);}
51 12ea39cc Tom Mullins
52 1085ef77 Tom Mullins
static inline void serno_zero(uint8_t *serno) {
53 1b054655 Tom Mullins
  memset(serno, 0, RFID_SERNO_SIZE);
54
}
55
56
static char serno_is_nonzero(uint8_t *serno) {
57
  int i;
58
  for (i = 0; i < RFID_SERNO_SIZE; i++) {
59
    if (serno[i]) {
60
      return 1;
61
    }
62
  }
63
  return 0;
64
}
65
66
static char serno_equal(uint8_t *a, uint8_t *b) {
67
  return memcmp(a, b, RFID_SERNO_SIZE) == 0;
68
}
69
70
static void serno_cpy(uint8_t *dest, uint8_t *src) {
71
  memcpy(dest, src, RFID_SERNO_SIZE);
72
}
73
74 94548bf4 Tom Mullins
static void tool_tick() {
75 12ea39cc Tom Mullins
76
  switch (toolstate) {
77
78
    case TS_INIT:
79
      if (get_coil(MB_COIL_INIT)) {
80
        set_coil(MB_COIL_NEW, 0);
81
        set_coil(MB_COIL_EN, 0);
82
        set_coil(MB_COIL_REQ_DIS, 0);
83
        toolstate = TS_OFF;
84
      }
85
      break;
86
87
    case TS_OFF:
88 f5d1f56a Tom Mullins
      led_off();
89 4b7d087b Tom Mullins
      set_coil(MB_COIL_EN, 0);
90 1b054655 Tom Mullins
      if (serno_is_nonzero(latest_reading)) {
91
        serno_cpy(current_user, latest_reading);
92 12ea39cc Tom Mullins
        set_coil(MB_COIL_NEW, 1);
93
        toolstate = TS_WAIT_ACCESS;
94
      }
95
      break;
96
97
    case TS_WAIT_ACCESS:
98 1b054655 Tom Mullins
      led_yellow();
99 12ea39cc Tom Mullins
      if (get_coil(MB_COIL_EN)) {
100
        tool_enable();
101
        toolstate = TS_ON;
102 e2a3c71f Tom Mullins
        current_startup_timeout = CURRENT_STARTUP_TIMEOUT / TICK_MS;
103
        current_startup_value = current + CURRENT_STARTUP_THRESH;
104 dc472500 Tom Mullins
      } else if (!get_coil(MB_COIL_NEW)) {
105 f5d1f56a Tom Mullins
        toolstate = TS_DENY;
106 4b7d087b Tom Mullins
      } else if (!serno_equal(current_user, latest_reading)) {
107
        set_coil(MB_COIL_NEW, 0);
108
        toolstate = TS_OFF;
109 12ea39cc Tom Mullins
      }
110
      break;
111
112 f5d1f56a Tom Mullins
    case TS_DENY:
113
      led_red();
114
      if (!serno_equal(current_user, latest_reading)) {
115
        toolstate = TS_OFF;
116
        serno_zero(current_user);
117
      }
118 bbf2f5ad Tom Mullins
      break;
119 f5d1f56a Tom Mullins
120 12ea39cc Tom Mullins
    case TS_REQ_DIS:
121 e53aa5c5 Tom Mullins
      if (!get_coil(MB_COIL_EN)) {
122
        tool_disable();
123
        toolstate = TS_OFF;
124
      } else if (!get_coil(MB_COIL_REQ_DIS)) {
125
        toolstate = TS_ON;
126
      } else {
127
        // TODO blink yellow for 10 seconds or something
128
        set_coil(MB_COIL_EN, 0);
129
        set_coil(MB_COIL_REQ_DIS, 0);
130
        tool_disable();
131 1b054655 Tom Mullins
        serno_zero(current_user);
132 e53aa5c5 Tom Mullins
        toolstate = TS_OFF;
133
      }
134 12ea39cc Tom Mullins
      break;
135
136
    case TS_MISSING_ID:
137 e2a3c71f Tom Mullins
      if (current_startup_timeout > 0 && current > current_startup_value) {
138
        tool_disable();
139
        set_coil(MB_COIL_EN, 0);
140
        toolstate = TS_OVER_CURRENT;
141
        led_blink_start(500, 16, RED);
142
      } else if (!get_coil(MB_COIL_EN)) {
143 e53aa5c5 Tom Mullins
        tool_disable();
144
        toolstate = TS_OFF;
145
      } else if (get_coil(MB_COIL_REQ_DIS)) {
146
        toolstate = TS_REQ_DIS;
147 1b054655 Tom Mullins
      } else if (serno_equal(current_user, latest_reading)) {
148 12ea39cc Tom Mullins
        toolstate = TS_ON;
149 bbf2f5ad Tom Mullins
      } else if (led_blink_done()) {
150
        set_coil(MB_COIL_EN, 0);
151
        tool_disable();
152
        serno_zero(current_user);
153
        toolstate = TS_OFF;
154 12ea39cc Tom Mullins
      }
155 e2a3c71f Tom Mullins
      if (current_startup_timeout > 0) {
156
        current_startup_timeout--;
157
      }
158 12ea39cc Tom Mullins
      break;
159
160
    case TS_ON:
161 1b054655 Tom Mullins
      led_green();
162 e2a3c71f Tom Mullins
      if (current_startup_timeout > 0 && current > current_startup_value) {
163
        tool_disable();
164
        set_coil(MB_COIL_EN, 0);
165
        toolstate = TS_OVER_CURRENT;
166
        led_blink_start(500, 16, RED);
167
      } else if (!get_coil(MB_COIL_EN)) {
168 12ea39cc Tom Mullins
        tool_disable();
169 1b054655 Tom Mullins
        serno_zero(current_user);
170 12ea39cc Tom Mullins
        toolstate = TS_OFF;
171 e53aa5c5 Tom Mullins
      } else if(get_coil(MB_COIL_REQ_DIS)) {
172 12ea39cc Tom Mullins
        toolstate = TS_REQ_DIS;
173 1b054655 Tom Mullins
      } else if (!serno_equal(current_user, latest_reading)) {
174 12ea39cc Tom Mullins
        toolstate = TS_MISSING_ID;
175 e2a3c71f Tom Mullins
        led_blink_start(500, 16, YELLOW);
176
      }
177
      if (current_startup_timeout > 0) {
178
        current_startup_timeout--;
179
      }
180
      break;
181
182
    case TS_OVER_CURRENT:
183
      if (led_blink_done() && !serno_equal(current_user, latest_reading)) {
184
        toolstate = TS_OFF;
185
        serno_zero(current_user);
186 12ea39cc Tom Mullins
      }
187
      break;
188
189
  }
190
191
}
192 208a6fb2 Tom Mullins
193 04b8cd51 Tom Mullins
eMBErrorCode eMBRegCoilsCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils,
194 20e5429c Tom Mullins
    eMBRegisterMode mode) {
195 208a6fb2 Tom Mullins
196 dc472500 Tom Mullins
  addr--;
197
198 532ba0bd Tom Mullins
  if (addr+n_coils > N_COILS) {
199 20e5429c Tom Mullins
    return MB_ENOREG;
200 208a6fb2 Tom Mullins
  }
201
202
  if (mode == MB_REG_WRITE) {
203
204
    switch (addr) {
205
206
      case MB_COIL_NEW:
207
        /* nop */
208
        reg_buf[0] >>= 1;
209
        n_coils--;
210
        if (n_coils == 0) {
211
          return MB_ENOERR;
212
        }
213
214
      case MB_COIL_EN:
215
        set_coil(MB_COIL_NEW, 0);
216
        set_coil(MB_COIL_EN, reg_buf[0] & 1);
217
        reg_buf[0] >>= 1;
218
        n_coils--;
219
        if (n_coils == 0) {
220
          return MB_ENOERR;
221
        }
222
223
      case MB_COIL_REQ_DIS:
224 12ea39cc Tom Mullins
        set_coil(MB_COIL_REQ_DIS, reg_buf[0] & 1);
225 208a6fb2 Tom Mullins
        reg_buf[0] >>= 1;
226
        n_coils--;
227
        if (n_coils == 0) {
228
          return MB_ENOERR;
229
        }
230
231
      case MB_COIL_INIT:
232
        set_coil(MB_COIL_INIT, reg_buf[0] & 1);
233
        reg_buf[0] >>= 1;
234
        n_coils--;
235
        if (n_coils == 0) {
236
          return MB_ENOERR;
237
        }
238
    }
239
240 20e5429c Tom Mullins
  } else if (mode == MB_REG_READ) {
241 208a6fb2 Tom Mullins
242 dc472500 Tom Mullins
    reg_buf[0] = (coils >> addr) & ((1 << n_coils) - 1);
243 208a6fb2 Tom Mullins
    return MB_ENOERR;
244
245 20e5429c Tom Mullins
  }
246 208a6fb2 Tom Mullins
247
  return MB_EIO;
248 20e5429c Tom Mullins
}
249
250 04b8cd51 Tom Mullins
eMBErrorCode eMBRegDiscreteCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils) {
251 20e5429c Tom Mullins
  return MB_ENOREG;
252
}
253
254 04b8cd51 Tom Mullins
eMBErrorCode eMBRegInputCB(UCHAR *reg_buf, USHORT addr, USHORT n_regs) {
255
256 dc472500 Tom Mullins
  addr--;
257
258 20e5429c Tom Mullins
  switch (addr) {
259 04b8cd51 Tom Mullins
260
    case MB_INP_SERNOL:
261 76915f20 Tom Mullins
      *reg_buf++ = current_user[0];
262
      *reg_buf++ = current_user[1];
263 04b8cd51 Tom Mullins
      n_regs--;
264
      if (n_regs == 0) {
265
        return MB_ENOERR;
266
      }
267
268
    case MB_INP_SERNOH:
269 76915f20 Tom Mullins
      *reg_buf++ = current_user[2];
270
      *reg_buf++ = current_user[3];
271 04b8cd51 Tom Mullins
      n_regs--;
272
      if (n_regs == 0) {
273
        return MB_ENOERR;
274
      }
275
276
    case MB_INP_CURRENT:
277 10936c07 Tom Mullins
      *reg_buf++ = (uint8_t)(current >> 8);
278
      *reg_buf++ = (uint8_t)current;
279 04b8cd51 Tom Mullins
      n_regs--;
280
      if (n_regs == 0) {
281
        return MB_ENOERR;
282 20e5429c Tom Mullins
      }
283 04b8cd51 Tom Mullins
284 20e5429c Tom Mullins
    default:
285
      return MB_ENOREG;
286
  }
287
}
288
289 04b8cd51 Tom Mullins
eMBErrorCode eMBRegHoldingCB(UCHAR *reg_buf, USHORT addr, USHORT n_regs,
290 20e5429c Tom Mullins
    eMBRegisterMode mode) {
291
  if (mode == MB_REG_WRITE) {
292
    return MB_ENOREG;
293
  } else if (mode == MB_REG_READ) {
294
    return MB_ENOREG;
295
  } else {
296
    return MB_EIO;
297
  }
298
}
299
300
int main() {
301 36f3b65f Tom Mullins
  char rfid_ticks = 0;
302 12ea39cc Tom Mullins
303 94548bf4 Tom Mullins
  time_init();
304 532ba0bd Tom Mullins
  led_init();
305 12ea39cc Tom Mullins
  tool_init();
306 9b2b6d91 Tom Mullins
  rfid_init();
307 94548bf4 Tom Mullins
  current_init();
308 20e5429c Tom Mullins
309 a96c5547 Tom Mullins
  eMBInit(MB_RTU, TOOL_ADDRESS, 0, MB_BAUD, MB_PAR_NONE);
310 20e5429c Tom Mullins
  eMBEnable();
311
312 208a6fb2 Tom Mullins
  sei();
313
314 532ba0bd Tom Mullins
  rfid_start_read();
315 20e5429c Tom Mullins
  while (1) {
316 bbf2f5ad Tom Mullins
    if (rfid_poll()) {
317
      rfid_get_serno(latest_reading);
318
    }
319 36f3b65f Tom Mullins
    if (++rfid_ticks >= RFID_PERIOD/TICK_MS)
320 94548bf4 Tom Mullins
    {
321
      rfid_ticks = 0;
322 bbf2f5ad Tom Mullins
      rfid_start_read();
323 532ba0bd Tom Mullins
    }
324 10936c07 Tom Mullins
    current = current_read();
325 94548bf4 Tom Mullins
    tool_tick();
326
    led_tick();
327 20e5429c Tom Mullins
    eMBPoll();
328 94548bf4 Tom Mullins
    time_wait();
329 20e5429c Tom Mullins
  }
330
331
  return 0;
332
}