📄 serial2002.c
字号:
data = serial_read(devpriv->tty, 1000); if (data.kind!=is_channel || data.index!=31 || !(data.value & 0xe0)) { break; } else { int command, channel, kind; config_t *cur_config = 0; channel = data.value & 0x1f; kind = (data.value>>5) & 0x7; command = (data.value>>8) & 0x3; switch (kind) { case 1: { cur_config = dig_in_config; } break; case 2: { cur_config = dig_out_config; } break; case 3: { cur_config = chan_in_config; } break; case 4: { cur_config = chan_out_config; } break; case 5: { cur_config = chan_in_config; } break; } if (cur_config) { cur_config[channel].kind = kind; switch (command) { case 0: { cur_config[channel].bits = (data.value >> 10) & 0x3f; } break; case 1: { int unit, sign, min; unit = (data.value >> 10) & 0x7; sign = (data.value >> 13) & 0x1; min = (data.value >> 14) & 0xfffff; switch (unit) { case 0: { min = min * 1000000; } break; case 1: { min = min * 1000; } break; case 2: { min = min * 1; } break; } if (sign) { min = -min; } cur_config[channel].min = min; } break; case 2: { int unit, sign, max; unit = (data.value >> 10) & 0x7; sign = (data.value >> 13) & 0x1; max = (data.value >> 14) & 0xfffff; switch (unit) { case 0: { max = max * 1000000; } break; case 1: { max = max * 1000; } break; case 2: { max = max * 1; } break; } if (sign) { max = -max; } cur_config[channel].max = max; } break; } } } } for (i = 0 ; i < 4 ; i++) { // Fill in subdev data config_t *c; unsigned char *mapping = 0; serial2002_range_table_t *range = 0; int kind = 0; switch (i) { case 0: { c = dig_in_config; mapping = devpriv->digital_in_mapping; kind = 1; } break; case 1: { c = dig_out_config; mapping = devpriv->digital_out_mapping; kind = 2; } break; case 2: { c = chan_in_config; mapping = devpriv->analog_in_mapping; range = devpriv->in_range; kind = 3; } break; case 3: { c = chan_out_config; mapping = devpriv->analog_out_mapping; range = devpriv->out_range; kind = 4; } break; case 4: { c = chan_in_config; c = 0; // Counters/encoder not implemented yet kind = 5; } break; default: { c = 0; } break; } if (c) { comedi_subdevice *s; int j, chan; for (chan = 0, j = 0 ; j < 32 ; j++) { if (c[j].kind == kind) { chan++; } } s = &dev->subdevices[i]; s->n_chan = chan; s->maxdata = 0; if (s->maxdata_list) { kfree(s->maxdata_list); } s->maxdata_list = kmalloc(sizeof(lsampl_t)*s->n_chan, GFP_KERNEL); if (s->range_table_list) { kfree(s->range_table_list); } if (range) { s->range_table = 0; s->range_table_list = kmalloc(sizeof(serial2002_range_table_t)*s->n_chan, GFP_KERNEL); } for (chan = 0, j = 0 ; j < 32 ; j++) { if (c[j].kind == kind) { if (mapping) { mapping[chan] = j; } if (range) { range[j].length = 1; range[j].range.min = c[j].min; range[j].range.max = c[j].max; s->range_table_list[chan] = (comedi_lrange*)&range[j]; } s->maxdata_list[chan] = (1<<c[j].bits) - 1; chan++; } } } } } return 0;}static int serial_2002_close(comedi_device *dev) { if (!IS_ERR(devpriv->tty) && (devpriv->tty != 0)) { filp_close(devpriv->tty, 0); } return 0;}static int serial2002_di_rinsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int n; int chan; chan = devpriv->digital_in_mapping[CR_CHAN(insn->chanspec)]; for(n = 0 ; n < insn->n ; n++){ struct serial_data read; poll_digital(devpriv->tty, chan); while (1) { read = serial_read(devpriv->tty, 1000); if (read.kind != is_digital || read.index == chan) { break; } } data[n] = read.value; } return n;}static int serial2002_do_winsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int n; int chan; chan = devpriv->digital_out_mapping[CR_CHAN(insn->chanspec)]; for(n = 0 ; n < insn->n ; n++){ struct serial_data write; write.kind = is_digital; write.index = chan; write.value = data[n]; serial_write(devpriv->tty, write); } return n;}static int serial2002_ai_rinsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int n; int chan; chan = devpriv->analog_in_mapping[CR_CHAN(insn->chanspec)]; for(n = 0 ; n < insn->n ; n++){ struct serial_data read; poll_channel(devpriv->tty, chan); while (1) { read = serial_read(devpriv->tty, 1000); if (read.kind != is_channel || read.index == chan) { break; } } data[n] = read.value; } return n;}static int serial2002_ao_winsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){ int n; int chan; chan = devpriv->analog_out_mapping[CR_CHAN(insn->chanspec)]; for(n = 0 ; n < insn->n ; n++){ struct serial_data write; write.kind = is_channel; write.index = chan; write.value = data[n]; serial_write(devpriv->tty, write); devpriv->ao_readback[chan] = data[n]; } return n;}static int serial2002_ao_rinsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){ int n; int chan = CR_CHAN(insn->chanspec); for(n = 0; n < insn->n ; n++) { data[n] = devpriv->ao_readback[chan]; } return n;}static int serial2002_attach(comedi_device *dev,comedi_devconfig *it){ comedi_subdevice *s; printk("comedi%d: serial2002: ",dev->minor); dev->board_name = thisboard->name; if(alloc_private(dev,sizeof(serial2002_private)) < 0) { return -ENOMEM; } dev->open = serial_2002_open; dev->close = serial_2002_close; devpriv->port = it->options[0]; devpriv->speed = it->options[1]; printk("/dev/ttyS%d @ %d\n", devpriv->port, devpriv->speed); if(alloc_subdevices(dev, 4)<0) return -ENOMEM; /* digital input subdevice */ s = dev->subdevices+0; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 0; s->maxdata = 1; s->range_table = &range_digital; s->insn_read = &serial2002_di_rinsn; /* digital output subdevice */ s = dev->subdevices+1; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITEABLE; s->n_chan = 0; s->maxdata = 1; s->range_table = &range_digital; s->insn_write = &serial2002_do_winsn; /* analog input subdevice */ s=dev->subdevices+2; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE|SDF_GROUND; s->n_chan = 0; s->maxdata = 1; s->range_table = 0; s->insn_read = &serial2002_ai_rinsn; /* analog output subdevice */ s=dev->subdevices+3; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE; s->n_chan = 0; s->maxdata = 1; s->range_table = 0; s->insn_write = &serial2002_ao_winsn; s->insn_read = &serial2002_ao_rinsn; printk("attached\n"); return 1;}static int serial2002_detach(comedi_device *dev){ comedi_subdevice *s; int i; printk("comedi%d: serial2002: remove\n",dev->minor); for (i = 0 ; i < 4 ; i++) { s = &dev->subdevices[i]; if (s->maxdata_list) { kfree(s->maxdata_list); } if (s->range_table_list) { kfree(s->range_table_list); } } return 0;}COMEDI_INITCLEANUP(driver_serial2002);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -