Example #1
0
/* IOCTL interface */
static int motor_ioctl (struct inode *in, struct file *fl, unsigned int cmd, \
						unsigned long arg) {

	int retval = 0, id;
	unsigned long to_end;
	struct cdev* p = in->i_cdev;

	id = cdev_to_id (p);

	switch (cmd) {
		case MOTOR_ENABLE:
			if ((int)arg)
				gpio_set_value (g_enable[id], 0 ^ polarity[id]);
			else
				gpio_set_value (g_enable[id], 1 ^ polarity[id]);
			break;

		case MOTOR_DIR:
			if ((int)arg)
				gpio_set_value (g_dir[id], 1);
			else
				gpio_set_value (g_dir[id], 0);
			break;

		case MOTOR_PWM_ON:
			pwm_start (pwmc[id]);
			break;

		case MOTOR_PWM_OFF:
			pwm_stop (pwmc[id]);
			break;

		case MOTOR_PWM_SET:
			//set the pwm period in ms
			motor_pwm_set (pwmc[id], arg);
			break;

		case MOTOR_RESET:
			steps[id] = 0; /* set the actual position as home */
			break;

		case MOTOR_STEPS:
			steps_max[id] = arg; /* set the steps limit */
			break;

		case MOTOR_START:
			if (g_step[id] == 0) {
			} else {
				if ((int)arg)
					retval = pwm_set_handler (pwmc[id], &irq_steps_handler, NULL);
				else
					retval = pwm_set_handler (pwmc[id], NULL, NULL);
			}
			break;

		case MOTOR_LOWPWR:
			if ((int)arg)
				gpio_set_value (g_lpwr[id], 1 ^ polarity[id]);
			else
				gpio_set_value (g_lpwr[id], 0 ^ polarity[id]);
			break;

		/* return steps_max-step */
		case MOTOR_TO_END:
			to_end = steps_max[id] - steps[id];
			copy_to_user(&arg, &to_end, sizeof(unsigned long));
			break;

		default:
			retval = -EINVAL;
	}

	return retval;
}
Example #2
0
static int motor_add_one(unsigned int id, unsigned int *params)
{
	int status, err;
	struct cdev *motor_cdev;
	struct platform_device *pdev;
	struct gpio_pwm_platform_data pdata;

	if ( mot_nump[id] < 4 ) {
		printk(KERN_INFO "stepper: nothing to register for id: %d.\n", id);
		return 0;
	}

	g_enable[id] = params[1];
	g_dir[id] = params[2];
	g_step[id] = params[3];
	g_lpwr[id] = params[4];
	polarity[id] = params[5];

	/* sanity check */
	if ( !( g_enable[id] && g_dir[id] && g_step[id])) {
		printk(KERN_INFO "stepper: missing parameters, exit driver.\n");
		goto err_para;
	}

	/* request and set pwm channel and gpio pins */
	pdev = platform_device_alloc("gpio_pwm", g_step[id]);
	if (!pdev) {
		err = -ENOMEM;
		goto err_para;
	}

	pdata.gpio = g_step[id];

	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
	if (err)
		goto err;

	err = platform_device_add(pdev);
	if (err)
		goto err;

	pwmc[id] = pwm_request("gpio_pwm", g_step[id], "stepper");
	if (pwmc[id] != NULL) {
		goto err_pwm;
	}

	motor_pwm_set (pwmc[id], 0);	/* set default pwm pulse */

	if ( gpio_request(g_enable[id], "motor-enable") < 0 ) {
		goto err_gpioenable;
	}
	gpio_direction_output(g_enable[id] ,0);

	if ( gpio_request(g_dir[id], "motor-ccw") < 0) {
		goto err_gpiodir;
	}
	gpio_direction_output(g_dir[id] ,0);

	if (g_lpwr[id] != 0) {
		if ( gpio_request(g_lpwr[id], "motor-lowpwr") < 0 ) {
			goto err_gpiolwr;
		}
		gpio_direction_output(g_lpwr[id] ,0);
	}

	/* set to home */
	steps[id] = 0;

	/* alloc a new device number (major: dynamic, minor: 0) */
	status = alloc_chrdev_region(&motor_devno, 0, 1, "motor");

	/* create a new char device  */
	motor_cdev = cdev_alloc();
	if(motor_cdev == NULL) {
		status=-ENOMEM;
		goto err_dev;
	}

	/*save the cdev for id's */
	mot_map[id] = (int) motor_cdev;

	motor_cdev->owner = THIS_MODULE;
	motor_cdev->ops = &motor_fops;
	status = cdev_add(motor_cdev, motor_devno, 1);
	if(status){
		goto err_dev;
	}

	device_create(motor_class, NULL, motor_devno, NULL, "motor%d", params[0]);
	printk(KERN_INFO "stepper: motor%d registred on major: %u; minor: %u\n", \
		params[0], MAJOR(motor_devno), MINOR(motor_devno));

	return 0;

err:
	printk(KERN_INFO "stepper: err\n");
err_dev:
	printk(KERN_INFO "stepper: err_dev\n");
err_gpiolwr:
	printk(KERN_INFO "stepper: err_gpiolwr\n");
err_gpiodir:
	printk(KERN_INFO "stepper: err_gpiodir\n");
err_gpioenable:
	printk(KERN_INFO "stepper: err_gpioenable\n");
err_gpiostep:
	printk(KERN_INFO "stepper: err_gpiostep ");
err_pwm:
	printk(KERN_INFO "stepper: err_pwm\n");
err_para:
	printk(KERN_INFO "stepper: Error management not yet implemented. \
		Please reboot your board %d\n",g_step[id]);
	return -1;
}
Example #3
0
// Current control loop ISR - 5 kHz
void __ISR(_TIMER_2_VECTOR, IPL5SOFT) Controller() {

	char buffer[200];

	// state querying code
	switch(util_state_get()) {
		case IDLE:
			//set PWM to 0
			motor_pwm_set(0);
			//reset Eint to 0
			Eint = 0;
			break;
		case PWM:
			// set PWM to user specified value
			break;
		case TUNE:
			if(StoringData) {
				int E = 0, PWM = 0, temp1;
				control_data d;

				d.reference = 200*flag;
				d.sensor = isense_amps();
				E = d.reference - d.sensor;
				Eint = Eint + E;
				// integral anti-windup
				if(Eint > EINTMAX) {Eint = EINTMAX;}
				if(Eint < -EINTMAX) {Eint = -EINTMAX;}
				//
				d.control = Kp*((float) E) + Ki*((float) Eint);

				PWM = ((int) d.control);
				if(d.control < -100) {PWM = -100;}
				if(d.control > 100) {PWM = 100;}

				temp1 = motor_pwm_set(PWM);


				if(StoringDataControl==1) {
					util_buffer_write(d);
				}

				counter++;
				if(counter==19)
				{
					counter = 0;

					if(flag == 0) {temp = 1;}
					if(flag == 1) {	temp = 0;}

					flag = temp;
				}
			}
			else {
				counter = 0;
				Eint = 0;
			}
			break;
		case TRACK:
			if(StoringData) {
				int E = 0, PWM = 0, temp1;
				control_data d;

				d.reference = reference_milliamps;
				d.sensor = isense_amps();
				E = d.reference - d.sensor;
				Eint = Eint + E;
				// integral anti-windup
				if(Eint > EINTMAX) {Eint = EINTMAX;}
				if(Eint < -EINTMAX) {Eint = -EINTMAX;}
				//
				d.control = Kp*((float) E) + Ki*((float) Eint);

				PWM = ((int) d.control);
				if(d.control < -100) {PWM = -100;}
				if(d.control > 100) {PWM = 100;}

				temp1 = motor_pwm_set(PWM);

				if(StoringDataControl==1) {
					util_buffer_write(d);
				}

			}
			else {
				Eint = 0;
				reference_milliamps = 0;
			}
			break;
		default:
			//error, unknown state
			NU32_LED2 = 0;
	}

	IFS0bits.T2IF = 0;											// clear interrupt flag

}