1 #include "comedilib_scxi.h"
6 static int scxi_identify(scxi_mod_t *mod);
8 static int scxi_serial_config(comedi_t *it, unsigned int clock_interval)
13 memset(&insn,0,sizeof(insn));
14 insn.insn = INSN_CONFIG;
17 insn.subdev = comedi_find_subdevice_by_type(it, COMEDI_SUBD_SERIAL, 0);
18 data[0]=INSN_CONFIG_SERIAL_CLOCK;
19 data[1]=clock_interval;
21 return comedi_do_insn(it,&insn);
24 static int scxi_serial_readwrite(comedi_t *it, unsigned char out_bits, unsigned char *in_bits)
30 memset(&insn,0,sizeof(insn));
32 insn.insn = INSN_CONFIG;
35 insn.subdev = comedi_find_subdevice_by_type(it, COMEDI_SUBD_SERIAL, 0);
37 data[0]=INSN_CONFIG_BIDIRECTIONAL_DATA;
40 ret = comedi_do_insn(it,&insn);
50 static int local_serial_readwrite(comedi_t *it, unsigned int subdev, unsigned int num_bits,
51 unsigned int out_bits, unsigned int *in_bits)
53 unsigned char byte_out, byte_in;
55 if(in_bits != NULL) (*in_bits) <<= 8;
56 byte_out = (out_bits >> (num_bits - 8)) & 0xFF;
57 scxi_serial_readwrite(it,byte_out, &byte_in);
58 if(in_bits != NULL) *in_bits |= byte_in;
65 static int scxi_slot_select(comedi_t *dev, unsigned int dio_subdev,
66 unsigned int serial_subdev, unsigned short chassis_address, unsigned short module_slot)
68 const unsigned int ssreg = ((chassis_address & 0x1f) << 4) | (module_slot & 0x0f);
70 comedi_dio_write(dev, dio_subdev, SCXI_LINE_SS, 0);
71 scxi_serial_config(dev, SLOT0_INTERVAL);
72 local_serial_readwrite(dev, serial_subdev, 16, ssreg, NULL);
73 comedi_dio_write(dev, dio_subdev, SCXI_LINE_SS, 1);
78 void comedi_scxi_close(scxi_mod_t *mod)
83 scxi_mod_t *comedi_scxi_open(comedi_t *dev, unsigned short chassis_address, unsigned short mod_slot)
85 scxi_mod_t *mod = NULL;
87 mod = (scxi_mod_t *) malloc(sizeof(*mod));
88 if(mod == NULL) goto Error;
90 memset(mod, 0, sizeof(*mod));
91 mod->chassis = chassis_address;
95 if(mod->dev == NULL) goto Error;
97 mod->dio_subdev = comedi_find_subdevice_by_type(mod->dev, COMEDI_SUBD_DIO, 0);
98 mod->ser_subdev = comedi_find_subdevice_by_type(mod->dev, COMEDI_SUBD_SERIAL, 0);
100 comedi_dio_config(mod->dev, mod->dio_subdev, SCXI_LINE_MISO, COMEDI_INPUT);
101 comedi_dio_config(mod->dev, mod->dio_subdev, SCXI_LINE_DA, COMEDI_OUTPUT);
102 comedi_dio_config(mod->dev, mod->dio_subdev, SCXI_LINE_SS, COMEDI_OUTPUT);
103 comedi_dio_config(mod->dev, mod->dio_subdev, SCXI_LINE_MOSI, COMEDI_OUTPUT);
105 comedi_dio_write(mod->dev, mod->dio_subdev, SCXI_LINE_DA, 1);
106 comedi_dio_write(mod->dev, mod->dio_subdev, SCXI_LINE_SS, 1);
113 comedi_scxi_close(mod);
117 static int scxi_module_select(scxi_mod_t *mod, unsigned short address)
119 scxi_slot_select(mod->dev, mod->dio_subdev, mod->ser_subdev, mod->chassis, mod->slot);
121 if(scxi_serial_config(mod->dev, scxi_boards[mod->board].clock_interval) < 0)
124 if(scxi_boards[mod->board].modclass == 2)
125 if(local_serial_readwrite(mod->dev, mod->ser_subdev, 16, address, NULL) < 0) return -1;
127 if(comedi_dio_write(mod->dev, mod->dio_subdev, SCXI_LINE_DA, 0) < 0) return -1;
132 static int scxi_module_deselect(scxi_mod_t *mod)
134 if(comedi_dio_write(mod->dev, mod->dio_subdev, SCXI_LINE_DA, 1) < 0) return -1;
136 if(scxi_boards[mod->board].modclass == 2) {
137 if(local_serial_readwrite(mod->dev, mod->ser_subdev, 16, REG_PARK, NULL) < 0) return -1;
140 scxi_slot_select(mod->dev, mod->dio_subdev, mod->ser_subdev, mod->chassis, 0);
145 static int scxi_identify(scxi_mod_t *mod)
148 if(mod == NULL || mod->dev == NULL)
151 scxi_slot_select(mod->dev, mod->dio_subdev, mod->ser_subdev, mod->chassis, mod->slot);
153 scxi_serial_config(mod->dev, SLOW_INTERVAL);
154 local_serial_readwrite(mod->dev, mod->ser_subdev, 32, 0, &id);
156 if(id == 0xffffffff) {
157 comedi_dio_write(mod->dev, mod->dio_subdev, SCXI_LINE_DA, 0);
158 local_serial_readwrite(mod->dev, mod->ser_subdev, 32, 0, &id);
159 comedi_dio_write(mod->dev, mod->dio_subdev, SCXI_LINE_DA, 1);
164 scxi_module_deselect(mod);
166 for (i=0;i<n_scxi_boards; i++) {
167 if (id == scxi_boards[i].device_id) {
173 fprintf(stderr, "name=%s, device_id = 0x%x, chassis_ad = %d, mod = %d\n",
174 scxi_boards[mod->board].name, scxi_boards[mod->board].device_id, mod->chassis, mod->slot);
180 int comedi_scxi_register_readwrite(scxi_mod_t *mod, unsigned short reg_address, unsigned int num_bytes,
181 unsigned char *data_out, unsigned char *data_in)
184 unsigned int tmp_in, tmp_out = 0;
186 if(mod == NULL || mod->dev == NULL) return -1;
188 scxi_module_select(mod, reg_address);
190 for(i = 0; i < num_bytes; ++i) {
191 if(data_out) tmp_out = data_out[i];
192 local_serial_readwrite(mod->dev, mod->ser_subdev, 8, tmp_out, &tmp_in);
193 if(data_in) data_in[i] = tmp_in;
196 if(scxi_boards[mod->board].modclass == 1 && reg_address == 0) {
197 comedi_dio_write(mod->dev, mod->dio_subdev, SCXI_LINE_SS, 1);
200 scxi_module_deselect(mod);