Project

General

Profile

Revision 7bdb98c5

ID7bdb98c5c7f6b44c764f8dd3620f7da270cfd830
Parent ec0eab37
Child 208a6fb2

Added by Thomas Mullins over 11 years ago

Initial commit of mainbox code.

View differences:

mainbox/Makefile
1
SRC=main.c tool.c
2
HDR=tool.h
3

  
4
FLAGS=-O2 -g -Wall -I.. `pkg-config --cflags --libs libmodbus`
5

  
6
all: tooltron
7

  
8
tooltron: $(SRC) $(HDR)
9
	gcc $(SRC) $(FLAGS) -o $@
10

  
11
install: tooltron
12
	cp tooltron /usr/local/bin
13

  
14
clean:
15
	rm -f *.o tooltron
mainbox/main.c
1
#include "tool.h"
2
#include <unistd.h>
3
#include <signal.h>
4
#include <strings.h>
5
#include <stdio.h>
6

  
7
#define SLEEP_MS 250
8

  
9
struct tool_t tools[] = {
10
  {4, "test", TS_INIT}
11
};
12

  
13
#define N_TOOLS (sizeof(tools)/sizeof(struct tool_t))
14

  
15
volatile int run = 1;
16

  
17
void sigint(int sig) {
18
  run = 0;
19
}
20

  
21
int main(int argc, char **argv) {
22
  int i;
23
  struct sigaction sigact;
24
  const char *device = "/dev/ttyUSB0";
25

  
26
  // TODO getopts to get device name
27

  
28
  bzero(&sigact, sizeof(sigact));
29
  sigact.sa_handler = sigint;
30
  sigact.sa_flags = SA_RESTART;
31
  sigemptyset(&sigact.sa_mask);
32
  sigaction(SIGINT, &sigact, NULL);
33

  
34
  if (tool_init_mb(device)) {
35
    return 1;
36
  }
37

  
38
  printf("Modbus initialized; polling tools...\n");
39

  
40
  i = 0;
41
  while (run) {
42
    tool_poll(&tools[i]);
43
    usleep(SLEEP_MS * (useconds_t)1000);
44
    i = (i+1) % N_TOOLS;
45
  }
46

  
47
  printf("\nDisabling tools\n");
48
  for (i = 0; i < N_TOOLS; i++) {
49
    tool_request_disable(&tools[i]);
50
  }
51

  
52
  printf("Closing modbus connection\n");
53
  tool_close_mb();
54

  
55
  printf("Exiting\n");
56
  return 0;
57
}
mainbox/tool.c
1
#include "tool.h"
2
#include "tooltron_mb.h"
3
#include <modbus.h>
4
#include <stdio.h>
5
#include <errno.h>
6
#include <stdlib.h> // TODO temporary
7

  
8
modbus_t *ctx;
9

  
10
int tool_init_mb(const char *device) {
11
  ctx = modbus_new_rtu(device, MB_BAUD, 'N', 8, 1);
12
  if (ctx == NULL) {
13
    fprintf(stderr, "modbus_new_rtu: %s\n", modbus_strerror(errno));
14
    return 1;
15
  }
16

  
17
  if (modbus_connect(ctx) == -1) {
18
    fprintf(stderr, "modbus_connect: %s\n", modbus_strerror(errno));
19
    modbus_free(ctx);
20
    return 1;
21
  }
22

  
23
  return 0;
24
}
25

  
26
void tool_close_mb() {
27
  modbus_close(ctx);
28
  modbus_free(ctx);
29
}
30

  
31
static void tool_write_coil(int addr, int bit) {
32
  if (modbus_write_bit(ctx, addr, bit) == -1) {
33
    fprintf(stderr, "modbus_write_bit: %s\n", modbus_strerror(errno));
34
  }
35
}
36

  
37
static void tool_init(struct tool_t *tool) {
38
  // TODO write current limit values
39
  tool_write_coil(MB_COIL_INIT, 1);
40
  tool->state = TS_OFF;
41
}
42

  
43
static void tool_get_user(struct tool_t *tool) {
44
  unsigned short serno[2];
45
  if (modbus_read_registers(ctx, MB_INP_SERNOL, 2, serno) == -1) {
46
    fprintf(stderr, "modbus_read_registers: %s\n", modbus_strerror(errno));
47
    tool->user = 0;
48
  } else {
49
    tool->user = MODBUS_GET_INT32_FROM_INT16(serno, 0);
50
  }
51
}
52

  
53
static void tool_grant_access(struct tool_t *tool) {
54
  printf("Granting access to %08x on %s\n", tool->user, tool->name);
55
  tool_write_coil(MB_COIL_EN, 1);
56
}
57

  
58
static void tool_deny_access(struct tool_t *tool) {
59
  printf("Denying access to %08x on %s\n", tool->user, tool->name);
60
  tool_write_coil(MB_COIL_EN, 0);
61
}
62

  
63
void tool_request_disable(struct tool_t *tool) {
64
  printf("Requesting disable on %s\n", tool->name);
65
  tool_write_coil(MB_COIL_REQ_DIS, 1);
66
}
67

  
68
void tool_poll(struct tool_t *tool) {
69
  unsigned char status[N_COILS];
70

  
71
  if (modbus_set_slave(ctx, SLAVE_ADDR) == -1) {
72
    fprintf(stderr, "modbus_set_slave: %s\n", modbus_strerror(errno));
73
  }
74

  
75
  if (modbus_read_bits(ctx, 0, N_COILS, status) == -1) {
76
    fprintf(stderr, "modbus_read_bits: %s\n", modbus_strerror(errno));
77
    return;
78
  }
79

  
80
  if (!status[MB_COIL_INIT]) {
81
    tool->state = TS_INIT;
82
  }
83

  
84
  switch (tool->state) {
85

  
86
    case TS_INIT:
87
      tool_init(tool);
88
      break;
89

  
90
    case TS_OFF:
91
      if (status[MB_COIL_NEW]) {
92
        tool_get_user(tool);
93
        // TODO check actual credentials
94
        if (rand() & 1) {
95
          tool_grant_access(tool);
96
        } else {
97
          tool_deny_access(tool);
98
        }
99
      }
100
      break;
101

  
102
    case TS_ON:
103
      if (!status[MB_COIL_EN]) {
104
        printf("Tool %s is off\n", tool->name);
105
        tool->state = TS_OFF;
106
      }
107
      break;
108

  
109
    case TS_REQ_DIS:
110
      if (!status[MB_COIL_EN]) {
111
        printf("Tool %s is off after requested disable\n", tool->name);
112
        tool->state = TS_OFF;
113
      }
114
      break;
115

  
116
  }
117

  
118
}
mainbox/tool.h
1
#ifndef TOOL_H
2
#define TOOL_H
3

  
4
enum toolstate_t {
5
  TS_INIT,
6
  TS_OFF,
7
  TS_REQ_DIS,
8
  TS_ON
9
};
10

  
11
struct tool_t {
12
  int address;
13
  const char *name;
14
  enum toolstate_t state;
15
  unsigned int user;
16
};
17

  
18
int tool_init_mb(const char *device);
19
void tool_close_mb();
20
void tool_request_disable(struct tool_t *tool);
21
void tool_poll(struct tool_t *tool);
22

  
23
#endif
tooltron_mb.h
16 16
 * Coils, 1 bit read/write
17 17
 */
18 18

  
19
/* When 1, there is a new rfid tag in the tool. The main box should either
20
 * write 1 to MB_COIL_EN, which automatically clears MB_COIL_NEW, or it should
21
 * write 0 directly to MB_COIL_NEW which denies the request */
19
/* When 1, there is a new rfid tag in the tool. Automatically cleared when the
20
 * main box writes to MB_COIL_EN */
22 21
#define MB_COIL_NEW     0
23 22

  
24
/* When 1, tool can be turned on. Write 0 to immediately shut off tool */
23
/* When 1, the tool receives power. Write 1 or 0 to grant or deny an access
24
 * request, respectively. If the tool is running, write 0 to immediately shut
25
 * off the tool */
25 26
#define MB_COIL_EN      1
26 27

  
27 28
/* Write 1 to request that the tool is disabled soon (what that means will be
......
33 34
 * later) */
34 35
#define MB_COIL_INIT    3
35 36

  
37
/* Number of coils */
38
#define N_COILS 4
39

  
36 40
/*
37 41
 * Other things
38 42
 */

Also available in: Unified diff