From 90ea57b2e964f10f5b2d9736ec86c37c07cf9e0f Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Wed, 2 May 2012 17:58:15 +0100 Subject: [PATCH] Created a PWM demo using the newly introduced defines to manipulate PWM frequency. --- demo/Makefile.am | 7 ++- demo/README | 5 ++ demo/pwm.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 demo/pwm.c diff --git a/demo/Makefile.am b/demo/Makefile.am index 523d3eb..8e87f2b 100644 --- a/demo/Makefile.am +++ b/demo/Makefile.am @@ -4,7 +4,7 @@ noinst_PROGRAMS = \ choose_routing cmd do_waveform dio eeprom_dump gpct_buffered_counting \ gpct_encoder gpct_pulse_generator \ gpct_simple_counting inp inpn insn ledclock \ - mmap outp poll receiver select \ + mmap outp poll receiver select pwm \ sender sigio sv tut1 tut2 tut3 noinst_HEADERS = examples.h @@ -101,6 +101,11 @@ poll_SOURCES = poll.c common.c poll_CFLAGS = $(COMEDILIB_CFLAGS) poll_LDADD = $(COMEDILIB_LIBS) +pwm_SOURCES = pwm.c common.c +pwm_CFLAGS = $(COMEDILIB_CFLAGS) +pwm_LDADD = $(COMEDILIB_LIBS) + + receiver_SOURCES = receiver.c common.c receiver_CFLAGS = $(COMEDILIB_CFLAGS) receiver_LDADD = $(COMEDILIB_LIBS) diff --git a/demo/README b/demo/README index 9238186..b870db0 100644 --- a/demo/README +++ b/demo/README @@ -136,6 +136,11 @@ outp : Write one to one channel of one subdevice. Requires a digital or analog output subdevice. +pwm: + controls PWM devices. Use the option -N 0 and -N 1 to switch + it on / off respectively. Call with no arguments to get + a help screen. + receiver: This demo is meant to be used in conjunction with the sender demo. Receiver requires a digital input subdevice, and sender diff --git a/demo/pwm.c b/demo/pwm.c new file mode 100644 index 0000000..ede2ec7 --- /dev/null +++ b/demo/pwm.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +/* + * A little pwm demo + * Part of Comedilib + * + * Copyright (c) 2012 Bernd Porr + * + * This file may be freely modified, distributed, and combined with + * other software, as long as proper attribution is given in the + * source code. + */ + +#include +#include +#include +#include +#include "examples.h" + +// the option -n is used to switch on/off the pwm + +int main(int argc, char *argv[]) +{ + int ret,i; + comedi_insn insn; + lsampl_t d[5]; + comedi_t *device; + + int freq; + + struct parsed_options options; + + init_parsed_options(&options); + options.freq = -1; + // we hijack this option to switch it on or off + options.n_scan = -1; + options.value = -1; + parse_options(&options, argc, argv); + + if ((options.value==-1)&&(options.n_scan==-1)&&(options.freq==-1)) { + fprintf(stderr, + "Usage: %s OPTIONS duty_cycle\n" + "options: \n" + " -N 0 switches PWM off\n" + " -N 1 switches PWM on\n" + " -N 2 enquires the max value for the duty cycle\n" + " -F FREQ sets the PWM frequency\n", + argv[0]); + } + + device = comedi_open(options.filename); + if(!device){ + comedi_perror(options.filename); + exit(-1); + } + + options.subdevice = comedi_find_subdevice_by_type(device,COMEDI_SUBD_PWM,0); + if (options.verbose) + printf("PWM subdevice autodetection gave subdevice number %d\n", + options.subdevice); + + if(options.n_scan==2) { + printf("%d\n",comedi_get_maxdata(device,options.subdevice,0)); + close(device); + exit(0); + } + + insn.insn=INSN_CONFIG; + insn.data=d; + insn.subdev=options.subdevice; + insn.chanspec=CR_PACK(0,0,0); + + if(options.n_scan==1) { + d[0] = INSN_CONFIG_ARM; + d[1] = 0; + insn.n=2; + ret=comedi_do_insn(device,&insn); + if(ret < 0){ + fprintf(stderr,"Could not switch on:%d\n",ret); + comedi_perror(options.filename); + exit(-1); + } + } + if(options.n_scan==0) { + d[0] = INSN_CONFIG_DISARM; + d[1] = 0; + insn.n=1; + ret=comedi_do_insn(device,&insn); + if(ret < 0){ + fprintf(stderr,"Could not switch off:%d\n",ret); + comedi_perror(options.filename); + exit(-1); + } + } + if(options.freq>0) { + freq = options.freq; + d[0] = INSN_CONFIG_PWM_SET_PERIOD; + d[1] = 1E9/freq; + insn.n=2; + ret=comedi_do_insn(device,&insn); + if(ret < 0){ + fprintf(stderr,"Could set frequ:%d\n",ret); + comedi_perror(options.filename); + exit(-1); + } + } + + d[0] = INSN_CONFIG_GET_PWM_STATUS; + insn.n=2; + ret=comedi_do_insn(device,&insn); + if(ret < 0){ + fprintf(stderr,"Could not get status:%d insn=%d\n", + ret, + d[0]); + comedi_perror(options.filename); + exit(-1); + } + if (options.verbose) { + if (d[1]) + fprintf(stderr, + "PWM is on.\n"); + else + fprintf(stderr, + "PWM is off.\n"); + } + d[0] = INSN_CONFIG_PWM_GET_PERIOD; + insn.n=2; + ret=comedi_do_insn(device,&insn); + if(ret < 0){ + fprintf(stderr,"Could get frequ:%d\n",ret); + comedi_perror(options.filename); + exit(-1); + } + freq = 1E9 / d[1]; + if (options.verbose) + fprintf(stderr,"PWM frequency is %d\n", freq); + + if (options.value>=0) + + if(comedi_data_write(device, + options.subdevice, + options.channel, + 0, + 0, + options.value)<0) + { + fprintf(stderr,"error setting the pwm duty cycle on "); + comedi_perror(options.filename); + exit(1); + } + + return 0; +} -- 2.26.2