Revision: 86 http://acme-dev.svn.sourceforge.net/acme-dev/?rev=86&view=rev Author: claudyus Date: 2011-05-21 08:41:27 +0000 (Sat, 21 May 2011) Log Message: ----------- stepper-drw: implement real solution in 0.4 fox.py: align apis, remove pin_name for class pin Modified Paths: -------------- kernel-stuff/stepper-driver/stepper-nopwm.c python/fox.py Modified: kernel-stuff/stepper-driver/stepper-nopwm.c =================================================================== --- kernel-stuff/stepper-driver/stepper-nopwm.c 2011-05-21 08:41:09 UTC (rev 85) +++ kernel-stuff/stepper-driver/stepper-nopwm.c 2011-05-21 08:41:27 UTC (rev 86) @@ -20,6 +20,7 @@ #include <linux/gpio.h> #include <linux/slab.h> #include <linux/io.h> +#include <linux/input.h> #include <linux/platform_device.h> #include <linux/hrtimer.h> #include <linux/workqueue.h> @@ -30,18 +31,20 @@ #define DRV_NAME "stepper-drv" #define DRV_DESC "Stepper motor driver using gpio and pwm pins" -#define DRV_VERSION "0.3-emulating" +#define DRV_VERSION "0.4-emulating" #define MAX_MOT_NUM 4 /* module var*/ struct class *motor_class; struct motor_device *motor; +struct input_dev *motor_input_dev; /*manage the limits*/ static dev_t motor_devno = 0; struct motor_device { unsigned long steps_max; unsigned long steps; + int count; int g_enable; int g_dir; @@ -53,6 +56,8 @@ ktime_t interval; int status; + unsigned long num_steps; + struct cdev *mcdev; }; @@ -111,17 +116,17 @@ mot->steps++; } - if (mot->steps < mot->steps_max) { - hrtimer_forward(&(mot->hrt), ktime_get(), mot->interval); - return HRTIMER_RESTART; + if (mot->count == 1 && mot->steps >= mot->steps_max) { + hrtimer_try_to_cancel(&(mot->hrt)); + return HRTIMER_NORESTART; } - hrtimer_try_to_cancel(&(mot->hrt)); - return HRTIMER_NORESTART; + hrtimer_forward(&(mot->hrt), ktime_get(), mot->interval); + return HRTIMER_RESTART; } /* IOCTL interface */ -static long motor_ioctl (struct file *file, unsigned int cmd, unsigned long arg){ +static int motor_ioctl (struct file *file, unsigned int cmd, unsigned long arg){ int retval = 0; unsigned long to_end; @@ -148,7 +153,13 @@ break; case MOTOR_START: + mot->count = 1; //execute step_max steps + hrtimer_start(&(mot->hrt), mot->interval, HRTIMER_MODE_REL); + break; + case MOTOR_PWM_ON: + //run without step count + mot->count = 0; hrtimer_start(&(mot->hrt), mot->interval, HRTIMER_MODE_REL); break; @@ -191,8 +202,9 @@ return retval; } + struct file_operations motor_fops = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, .unlocked_ioctl = motor_ioctl, }; @@ -204,12 +216,13 @@ printk(KERN_INFO "stepper: nothing to register for motor %d, too few arguments: %d.\n", id, mot_nump[id]); return 0; } -// Supported args: motX=en,dir,step[,lowpwr,polarity] +// Supported args: motX=en,dir,step,limit[,lowpwr,polarity] motor[id].g_enable = params[0]; motor[id].g_dir = params[1]; motor[id].g_step = params[2]; - motor[id].g_lpwr = params[3]; - motor[id].polarity = params[4]; + motor[id].g_limit = params[3] + motor[id].g_lpwr = params[4]; + motor[id].polarity = params[5]; /* sanity check */ if ( !( motor[id].g_enable && motor[id].g_dir && motor[id].g_step)) { @@ -217,7 +230,6 @@ goto err_para; } -// printk(KERN_INFO "request g_spte\n"); if (gpio_request(motor[id].g_step, "motor-step")) return -EINVAL; @@ -231,13 +243,26 @@ goto err_gpioenable; } gpio_direction_output(motor[id].g_enable ,0); - gpio_set_value (motor[id].g_enable, 0); + gpio_set_value (motor[id].g_enable, 1); if ( gpio_request(motor[id].g_dir, "motor-ccw") < 0) { goto err_gpiodir; } gpio_direction_output(motor[id].g_dir ,0); + + if ( gpio_request(motor[id].g_limit, "motor-limit") < 0) { + goto err_gpiolimit; + } + gpio_direction_input(motor[id].g_limit ,1); +#if CONFIG_MACH_AT91 + at91_set_deglitch(motor[id].g_limit, 1); /* Enable the glitch filter for interrupt */ +#endif + ret = request_irq(motor[id].g_limit, enc424j600_irq, 0, DRV_NAME, priv); + if (ret < 0) { + printk(KERN_INFO "stepper: error requiring .\n"); + } + if (motor[id].g_lpwr != 0) { if ( gpio_request(motor[id].g_lpwr, "motor-lowpwr") < 0 ) { goto err_gpiolwr; @@ -253,7 +278,6 @@ /* create a new char device */ motor[id].mcdev = cdev_alloc(); - printk(KERN_INFO "stepper: cdev: %d\n", motor[id].mcdev); if(motor[id].mcdev == NULL) { status=-ENOMEM; goto err_dev; @@ -300,10 +324,16 @@ printk(KERN_INFO DRV_DESC ", version " DRV_VERSION "\n"); hrtimer_get_res(CLOCK_MONOTONIC, &tp); - printk(KERN_INFO "Clock resolution is %ldns\n", tp.tv_nsec); + printk(KERN_INFO "Minimun clock resolution is %ldns\n", tp.tv_nsec); motor = kmalloc(sizeof(struct motor_device) * MAX_MOT_NUM, GFP_KERNEL ); + motor_input_dev = input_allocate_device(); + if (!motor_input_dev) { + printk(KERN_INFO "stepper: Cannot allocate input device\n"); + return -ENOMEM; + } + /*register the class */ motor_class = class_create(THIS_MODULE, "motor_class"); if(IS_ERR(motor_class)){ Modified: python/fox.py =================================================================== --- python/fox.py 2011-05-21 08:41:09 UTC (rev 85) +++ python/fox.py 2011-05-21 08:41:27 UTC (rev 86) @@ -5,9 +5,10 @@ # $Id$ import os.path -import serial +#import serial import fcntl, struct, termios, os import time +import types GPIO_GET = 16906 GPIO_SET = 16907 @@ -22,93 +23,19 @@ class pin: """This call can be used to access GPIO pins using device base method\n - It implements: pin(fox_pin_name, direction), .get(), .set(1|0)""" - kernelid_table = { - 'J7.3' : 82, - 'J7.4' : 83, - 'J7.5' : 80, - 'J7.6' : 81, - 'J7.7' : 66, - 'J7.8' : 67, - 'J7.9' : 64, - 'J7.10' : 65, - 'J7.11' : 110, - 'J7.12' : 111, - 'J7.13' : 108, - 'J7.14' : 109, - 'J7.15' : 105, - 'J7.16' : 106, - 'J7.17' : 103, - 'J7.18' : 104, - 'J7.19' : 101, - 'J7.20' : 102, - 'J7.21' : 73, - 'J7.22' : 72, - 'J7.31' : 87, - 'J7.32' : 86, - 'J7.33' : 89, - 'J7.34' : 88, - 'J7.35' : 60, - 'J7.36' : 59, - 'J7.37' : 58, - 'J7.38' : 57, - 'J6.3' : 92, - 'J6.4' : 71, - 'J6.5' : 70, - 'J6.6' : 93, - 'J6.7' : 90, - 'J6.8' : 69, - 'J6.9' : 68, - 'J6.10' : 91, - 'J6.13' : 75, - 'J6.14' : 74, - 'J6.15' : 77, - 'J6.16' : 76, - 'J6.17' : 85, - 'J6.18' : 84, - 'J6.19' : 95, - 'J6.20' : 94, - 'J6.21' : 63, - 'J6.22' : 62, - 'J6.24' : 38, - 'J6.25' : 39, - 'J6.26' : 41, - 'J6.27' : 99, - 'J6.28' : 98, - 'J6.29' : 97, - 'J6.30' : 96, - 'J6.31' : 56, - 'J6.32' : 55, - 'J6.36' : 42, - 'J6.37' : 54, - 'J6.38' : 43, - } + It implements: pin(kernel_id_pin, direction), .get(), .set(1|0)""" fd_pin = -1 - def is_low(self, string): - if (string == "out" or string == "low" or string == "0"): - return True - if (string == "in" or string == "high" or string == "1"): - return False - return int(string) + def __init__(self,kernelid,direction): - def getid(self,pin_name): - if (pin_name.isdigit() == False ): - return self.kernelid_table[pin_name] - else: - return int(pin_name) - - def __init__(self,pin_name,direction): - self.kernelid=self.getid(pin_name) - self.fd_pin = open ("/dev/gpio") fcntl.ioctl(self.fd_pin, GPIO_REQUEST, self.kernelid) if self.is_low(direction): - fcntl.ioctl(self.fd_pin, GPIO_DIR_OUT, self.kernelid) + fcntl.ioctl(self.fd_pin, GPIO_DIR_OUT, kernelid) else: - fcntl.ioctl(self.fd_pin, GPIO_DIR_IN, self.kernelid) + fcntl.ioctl(self.fd_pin, GPIO_DIR_IN, kernelid) def set(self,value): if self.is_low(value): @@ -128,6 +55,10 @@ def free(self): fcntl.ioctl(self.fd_pin, GPIO_FREE, self.kernelid) + def __del__(self): + self.free() + + class display: """ This class can be used to controll 4D System oled display attacched to serial port. If no arg is supply if will use ttyS3 as default. @@ -151,6 +82,10 @@ ser.write("s%c%c%c%c%c%s%c" % (int(x),int(y),1,0xFF,0xFF,string,0x00)) ser.read(1) + def __del__(self): + ser.close() + + class adc: """This class allow you to access the four ADC channel using the appropriate device file""" def __init__ (self, chan): @@ -185,9 +120,12 @@ self.pt1.off() self.pt2.off() + def __del__(self): + self.pt1.free() + self.pt2.() class stepper: - """ This class allow you to drive a stepper motor using gpio pins.\n + """ This class allow you to drive a stepper motor using pwm signal and gpio for actual limits.\n The stepper class use the follow paramethers for costructor:\n (enable, direction, step, [limit], [low_pwr])\n """ @@ -197,36 +135,23 @@ direction = 0 def __init__ (self, en, dir, step, limit=0, low_pwr=0): - self.en_pin = pin(en, "out") - self.dir_pin = pin(dir, "out") - self.step_pin = pin(step, "out") - if (low_pwr != 0): - self.lwpwr_pin = pin(low_pwr, "out") - self.have_lowpwr= 1 if (limit != 0): self.limit_pin = pin(limit, "in") self.have_limit = 1 - #reset the hw - self.dir(0) - self.disable() def enable (self): - self.en_pin.off() + self.step_pwm.enable(1) def disable (self): - self.en_pin.on() + self.step_pwm.enable(0) def dir (self, value): - self.dir_pin.set(value) + self.step_pwm.dir(value) self.direction = value def recover_end (self, step=300): print "direction: %d" % self.direction - self.dir_pin.set(not self.direction) - for i in range(0, step): - self.step_pin.set(0) - self.step_pin.set(1) - self.dir_pin.set(self.direction) + self.step_pwm.dir(not self.direction) def step (self, number=1, delay=0, recover_step=300): self.enable() @@ -256,7 +181,7 @@ MOTOR_ENABLE = 19210 MOTOR_DIR = 19211 MOTOR_PWM_ON = 19212 -MOTOR_PWN_OFF = 19213 +MOTOR_PWM_OFF = 19213 MOTOR_PWM_SET = 19214 MOTOR_RESET = 19215 MOTOR_STEPS = 19216 @@ -287,9 +212,9 @@ def pwm_off(self): fcntl.ioctl(self.dev_fd_pwm, MOTOR_PWM_OFF) - def pwm_set(self,val_ns): - """set the pulse width, express in ns""" - fcntl.ioctl(self.dev_fd_pwm, MOTOR_PWM_SET, val_ns) + def pwm_set(self,val_ms): + """set the pulse width, express in ms""" + fcntl.ioctl(self.dev_fd_pwm, MOTOR_PWM_SET, val_ms) def step_reset (self): fcntl.ioctl(self.dev_fd_pwm, MOTOR_RESET) @@ -299,12 +224,9 @@ fcntl.ioctl(self.dev_fd_pwm, MOTOR_STEPS, val) def start(self): - fcntl.ioctl(self.dev_fd_pwm, MOTOR_START) + # return the number of missin steps + return fcntl.ioctl(self.dev_fd_pwm, MOTOR_START) def lowpwr(self): fcntl.ioctl(self.dev_fd_pwm, MOTOR_LOWPWR) - #output - #def to_end(self) - # fcntl.ioctl(self.dev_fd_pwm, MOTOR_TO_END, val) - # return val This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.