/* * Part of Comedi::Lib * * Copyright (c) 2009 Manuel Gebele , Germany * */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include int lib_close(comedi_t *dev) { return comedi_close(dev); } comedi_t *lib_open(const char *fn) { return comedi_open(fn); } int lib_loglevel(int level) { return comedi_loglevel(level); } void lib_perror(const char *str) { return comedi_perror(str); } const char *lib_strerror(int errnum) { return comedi_strerror(errnum); } int lib_errno() { return comedi_errno(); } int lib_fileno(comedi_t *dev) { return comedi_fileno(dev); } int lib_get_n_subdevices(comedi_t *dev) { return comedi_get_n_subdevices(dev); } int lib_get_version_code(comedi_t *dev) { return comedi_get_version_code(dev); } const char *lib_get_driver_name(comedi_t *dev) { return comedi_get_driver_name(dev); } const char *lib_get_board_name(comedi_t *dev) { return comedi_get_board_name(dev); } int lib_get_subdevice_type(comedi_t *dev, unsigned int subdev) { return comedi_get_subdevice_type(dev, subdev); } int lib_find_subdevice_by_type(comedi_t *dev, int type, unsigned int start) { return comedi_find_subdevice_by_type(dev, type, start); } int lib_get_read_subdevice(comedi_t *dev) { return comedi_get_read_subdevice(dev); } int lib_get_write_subdevice(comedi_t *dev) { return comedi_get_write_subdevice(dev); } int lib_get_subdevice_flags(comedi_t *dev, unsigned int subdev) { return comedi_get_subdevice_flags(dev, subdev); } int lib_get_n_channels(comedi_t *dev, unsigned int subdev) { return comedi_get_n_channels(dev, subdev); } int lib_range_is_chan_specific(comedi_t *dev, unsigned int subdev) { return comedi_range_is_chan_specific(dev, subdev); } int lib_maxdata_is_chan_specific(comedi_t *dev, unsigned int subdev) { return comedi_maxdata_is_chan_specific(dev, subdev); } lsampl_t lib_get_maxdata(comedi_t *dev, unsigned int subdev, unsigned int chan) { return comedi_get_maxdata(dev, subdev, chan); } int lib_get_n_ranges(comedi_t *dev, unsigned int subdev, unsigned int chan) { return comedi_get_n_ranges(dev, subdev, chan); } /* Comedilib returns a pointer to a comedi_range structure */ HV *lib_get_range(comedi_t *dev, unsigned int subdev, unsigned int chan, unsigned int rng) { comedi_range *range; HV *range_hash = (HV *)sv_2mortal((SV *)newHV()); range = comedi_get_range(dev, subdev, chan, rng); if (!range) { hv_undef(range_hash); /* optional */ return range_hash; } /* * The comedi_range structure contains the following components: * double min; * double max; * unsigned int unit; */ hv_store(range_hash, "min", 3, newSVnv(range->min), 0); hv_store(range_hash, "max", 3, newSVnv(range->max), 0); hv_store(range_hash, "unit", 4, newSVuv(range->unit), 0); return range_hash; } int lib_find_range(comedi_t *dev, unsigned int subdev, unsigned int chan, unsigned int unit, double min, double max) { return comedi_find_range(dev, subdev, chan, unit, min, max); } int lib_get_buffer_size(comedi_t *dev, unsigned int subdev) { return comedi_get_buffer_size(dev, subdev); } int lib_get_max_buffer_size(comedi_t *dev, unsigned int subdev) { return comedi_get_max_buffer_size(dev, subdev); } int lib_set_buffer_size(comedi_t *dev, unsigned int subdev, unsigned int size) { return comedi_set_buffer_size(dev, subdev, size); } /* _DEPRECATED_ - comedi_trigger */ int lib_do_insn(comedi_t *dev, HV *insn_ref) { SV **insn, **n, **subdev, **chanspec, **data; AV *data_arr; int len; unsigned int *insn_data; int i; SV **ele; comedi_insn cinsn; int retval; if (!(insn = hv_fetch(insn_ref, "insn", 4, 0))) return -1; if (!(n = hv_fetch(insn_ref, "n", 1, 0))) return -1; if (!(subdev = hv_fetch(insn_ref, "subdev", 6, 0))) return -1; if (!(chanspec = hv_fetch(insn_ref, "chanspec", 8, 0))) return -1; if (!(data = hv_fetch(insn_ref, "data", 4, 0))) return -1; if (!(data_arr = (AV *)SvRV(*data))) return -1; len = av_len(data_arr); if (len == -1) /* An empty array makes no sense at all */ return len; Newx(insn_data, len + 1, unsigned int); for (i = 0; i <= len; i++) { if (!(ele = av_fetch(data_arr, i, FALSE))) return -1; insn_data[i] = SvUV(*ele); } cinsn.insn = SvUV(*insn); cinsn.n = SvUV(*n); cinsn.data = insn_data; cinsn.subdev = SvUV(*subdev); cinsn.chanspec = SvUV(*chanspec); if ((retval = comedi_do_insn(dev, &cinsn)) == -1) return retval; /* Copy back, essential for a number of * instructions (e.g. INSN_READ) */ for (i = 0; i <= len; i++) av_store(data_arr, i, newSVuv(cinsn.data[i])); return retval; } int lib_do_insnlist(comedi_t *dev, HV *insnlist_ref) { SV **n_insns, **insns; AV *insns_arr; int insns_len; comedi_insn *insns_tmp; AV **data_arr; int *data_len; int i; SV **insn_ele; HV *insn_hash; SV **insn, **n, **subdev, **chanspec, **data; unsigned int *insn_data; int j; SV **data_ele; comedi_insn cinsn; comedi_insnlist insnlist; int retval; if (!(n_insns = hv_fetch(insnlist_ref, "n_insns", 7, 0))) return -1; if (n_insns <= 0) /* There's nothing to do */ return 0; if (!(insns = hv_fetch(insnlist_ref, "insns", 5, 0))) return -1; if (!(insns_arr = (AV *)SvRV(*insns))) return -1; insns_len = av_len(insns_arr); if (insns_len == -1) /* An empty array makes no sense at all */ return insns_len; Newx(insns_tmp, insns_len + 1, comedi_insn); Newx(data_arr, insns_len + 1, AV *); Newx(data_len, insns_len + 1, int); for (i = 0; i <= insns_len; i++) { if (!(insn_ele = av_fetch(insns_arr, i, FALSE))) return -1; if (!(insn_hash = (HV *)SvRV(*insn_ele))) return -1; if (!(insn = hv_fetch(insn_hash, "insn", 4, 0))) return -1; if (!(n = hv_fetch(insn_hash, "n", 1, 0))) return -1; if (!(subdev = hv_fetch(insn_hash, "subdev", 6, 0))) return -1; if (!(chanspec = hv_fetch(insn_hash, "chanspec", 8, 0))) return -1; if (!(data = hv_fetch(insn_hash, "data", 4, 0))) return -1; if (!(data_arr[i] = (AV *)SvRV(*data))) return -1; data_len[i] = av_len(data_arr[i]); if (data_len[i] == -1) continue; /* Or better return -1 ? */ Newx(insn_data, data_len[i] + 1, unsigned int); for (j = 0; j <= data_len[i]; j++) { if (!(data_ele = av_fetch(data_arr[i], j, FALSE))) return -1; insn_data[j] = SvUV(*data_ele); } cinsn.insn = SvUV(*insn); cinsn.n = SvUV(*n); cinsn.data = insn_data; cinsn.subdev = SvUV(*subdev); cinsn.chanspec = SvUV(*chanspec); insns_tmp[i] = cinsn; } insnlist.n_insns = SvUV(*n_insns); insnlist.insns = insns_tmp; retval = comedi_do_insnlist(dev, &insnlist); if (retval == -1) return retval; /* Copy back */ for (i = 0; i <= insns_len; i++) for (j = 0; j <= data_len[i]; j++) av_store(data_arr[i], j, newSViv(insnlist.insns[i].data[j])); return retval; } int lib_lock(comedi_t *dev, unsigned int subdev) { return comedi_lock(dev, subdev); } int lib_unlock(comedi_t *dev, unsigned int subdev) { return comedi_unlock(dev, subdev); } /* _DEPRECATED_ - comedi_to_phys */ /* _DEPRECATED_ - comedi_from_phys */ int lib_data_read(comedi_t *dev, unsigned int subdev, unsigned int chan, unsigned int rng, unsigned int aref, SV *data) { int retval; lsampl_t data_tmp; SV *sv; retval = comedi_data_read(dev, subdev, chan, rng, aref, &data_tmp); if (retval == -1) return retval; sv = SvRV(data); sv_setuv(sv, data_tmp); return retval; } int lib_data_read_delayed(comedi_t *dev, unsigned int subdev, unsigned int chan, unsigned int rng, unsigned int aref, SV *data, unsigned int ns) { int retval; lsampl_t data_tmp; SV *sv; retval = comedi_data_read_delayed(dev, subdev, chan, rng, aref, &data_tmp, ns); if (retval == -1) return retval; sv = SvRV(data); sv_setuv(sv, data_tmp); return retval; } int lib_data_read_hint(comedi_t *dev, unsigned int subdev, unsigned int chan, unsigned int rng, unsigned int aref) { return comedi_data_read_hint(dev, subdev, chan, rng, aref); } int lib_data_write(comedi_t *dev, unsigned int subdev, unsigned int chan, unsigned int rng, unsigned int aref, lsampl_t data) { return comedi_data_write(dev, subdev, chan, rng, aref, data); } int lib_dio_config(comedi_t *dev, unsigned int subdev, unsigned int chan, unsigned int dir) { return comedi_dio_config(dev, subdev, chan, dir); } int lib_dio_get_config(comedi_t *dev, unsigned int subdev, unsigned int chan, SV *dir) { int retval; unsigned int dir_tmp; SV *sv; retval = comedi_dio_get_config(dev, subdev, chan, &dir_tmp); if (retval == -1) return retval; sv = SvRV(dir); sv_setuv(sv, dir_tmp); return retval; } int lib_dio_read(comedi_t *dev, unsigned int subdev, unsigned int chan, SV *bit) { int retval; unsigned int bit_tmp; SV *sv; retval = comedi_dio_read(dev, subdev, chan, &bit_tmp); if (retval == -1) return retval; sv = SvRV(bit); sv_setuv(sv, bit_tmp); return retval; } int lib_dio_write(comedi_t *dev, unsigned int subdev, unsigned int chan, unsigned int bit) { return comedi_dio_write(dev, subdev, chan, bit); } /* _DEPRECATED_ - comedi_dio_bitfield */ int lib_dio_bitfield2(comedi_t *dev, unsigned int subdev, unsigned int write_mask, SV *bits, unsigned int base_ch) { int retval; unsigned int bits_tmp; SV *sv; retval = comedi_dio_bitfield2(dev, subdev, write_mask, &bits_tmp, base_ch); if (retval == -1) return retval; sv = SvRV(bits); sv_setuv(sv, bits_tmp); return retval; } /* _DEPRECATED_ - comedi_sv_init */ /* _DEPRECATED_ - comedi_sv_update */ /* _DEPRECATED_ - comedi_sv_measure */ /* Not implemented yet - comedi_get_cmd_src_mask */ /* Not implemented yet - comedi_get_cmd_generic_timed */ int lib_cancel(comedi_t *dev, unsigned int subdev) { return comedi_cancel(dev, subdev); } /* Not implemented yet - comedi_command */ /* Not implemented yet - comedi_command_test */ int lib_poll(comedi_t *dev, unsigned int subdev) { return comedi_poll(dev, subdev); } int lib_set_max_buffer_size(comedi_t *dev, unsigned int subdev, unsigned int max_size) { return comedi_set_max_buffer_size(dev, subdev, max_size); } int lib_get_buffer_contents(comedi_t *dev, unsigned int subdev) { return comedi_get_buffer_contents(dev, subdev); } int lib_mark_buffer_read(comedi_t *dev, unsigned int subdev, unsigned int num_bytes) { return comedi_mark_buffer_read(dev, subdev, num_bytes); } int lib_mark_buffer_written(comedi_t *dev, unsigned int subdev, unsigned int num_bytes) { return comedi_mark_buffer_written(dev, subdev, num_bytes); } int lib_get_buffer_offset(comedi_t *dev, unsigned int subdev) { return comedi_get_buffer_offset(dev, subdev); } /* _DEPRECATED_ - comedi_get_timer */ /* _DEPRECATED_ - comedi_timed_1chan */ MODULE = Comedi::Lib PACKAGE = Comedi::Lib PROTOTYPES: DISABLE int lib_close (dev) comedi_t * dev comedi_t * lib_open (fn) const char * fn int lib_loglevel (level) int level void lib_perror (str) const char * str PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; lib_perror(str); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ const char * lib_strerror (errnum) int errnum int lib_errno () int lib_fileno (dev) comedi_t * dev int lib_get_n_subdevices (dev) comedi_t * dev int lib_get_version_code (dev) comedi_t * dev const char * lib_get_driver_name (dev) comedi_t * dev const char * lib_get_board_name (dev) comedi_t * dev int lib_get_subdevice_type (dev, subdev) comedi_t * dev unsigned int subdev int lib_find_subdevice_by_type (dev, type, start) comedi_t * dev int type unsigned int start int lib_get_read_subdevice (dev) comedi_t * dev int lib_get_write_subdevice (dev) comedi_t * dev int lib_get_subdevice_flags (dev, subdev) comedi_t * dev unsigned int subdev int lib_get_n_channels (dev, subdev) comedi_t * dev unsigned int subdev int lib_range_is_chan_specific (dev, subdev) comedi_t * dev unsigned int subdev int lib_maxdata_is_chan_specific (dev, subdev) comedi_t * dev unsigned int subdev lsampl_t lib_get_maxdata (dev, subdev, chan) comedi_t * dev unsigned int subdev unsigned int chan int lib_get_n_ranges (dev, subdev, chan) comedi_t * dev unsigned int subdev unsigned int chan HV * lib_get_range (dev, subdev, chan, rng) comedi_t * dev unsigned int subdev unsigned int chan unsigned int rng int lib_find_range (dev, subdev, chan, unit, min, max) comedi_t * dev unsigned int subdev unsigned int chan unsigned int unit double min double max int lib_get_buffer_size (dev, subdev) comedi_t * dev unsigned int subdev int lib_get_max_buffer_size (dev, subdev) comedi_t * dev unsigned int subdev int lib_set_buffer_size (dev, subdev, size) comedi_t * dev unsigned int subdev unsigned int size int lib_do_insn (dev, insn_ref) comedi_t * dev HV * insn_ref int lib_do_insnlist (dev, insnlist_ref) comedi_t * dev HV * insnlist_ref int lib_lock (dev, subdev) comedi_t * dev unsigned int subdev int lib_unlock (dev, subdev) comedi_t * dev unsigned int subdev int lib_data_read (dev, subdev, chan, rng, aref, data) comedi_t * dev unsigned int subdev unsigned int chan unsigned int rng unsigned int aref SV * data int lib_data_read_delayed (dev, subdev, chan, rng, aref, data, ns) comedi_t * dev unsigned int subdev unsigned int chan unsigned int rng unsigned int aref SV * data unsigned int ns int lib_data_read_hint (dev, subdev, chan, rng, aref) comedi_t * dev unsigned int subdev unsigned int chan unsigned int rng unsigned int aref int lib_data_write (dev, subdev, chan, rng, aref, data) comedi_t * dev unsigned int subdev unsigned int chan unsigned int rng unsigned int aref lsampl_t data int lib_dio_config (dev, subdev, chan, dir) comedi_t * dev unsigned int subdev unsigned int chan unsigned int dir int lib_dio_get_config (dev, subdev, chan, dir) comedi_t * dev unsigned int subdev unsigned int chan SV * dir int lib_dio_read (dev, subdev, chan, bit) comedi_t * dev unsigned int subdev unsigned int chan SV * bit int lib_dio_write (dev, subdev, chan, bit) comedi_t * dev unsigned int subdev unsigned int chan unsigned int bit int lib_dio_bitfield2 (dev, subdev, write_mask, bits, base_ch) comedi_t * dev unsigned int subdev unsigned int write_mask SV * bits unsigned int base_ch int lib_cancel (dev, subdev) comedi_t * dev unsigned int subdev int lib_poll (dev, subdev) comedi_t * dev unsigned int subdev int lib_set_max_buffer_size (dev, subdev, max_size) comedi_t * dev unsigned int subdev unsigned int max_size int lib_get_buffer_contents (dev, subdev) comedi_t * dev unsigned int subdev int lib_mark_buffer_read (dev, subdev, num_bytes) comedi_t * dev unsigned int subdev unsigned int num_bytes int lib_mark_buffer_written (dev, subdev, num_bytes) comedi_t * dev unsigned int subdev unsigned int num_bytes int lib_get_buffer_offset (dev, subdev) comedi_t * dev unsigned int subdev