之前在用户空间用操作gpio实现完整的步进电机的控制功能.下面将其挪到底层去,顺便总结下驱动所用到的知识点.
驱动源码:
/*
* Copyright (c) 2014-5-15 SE7EN
*
* Four phases step motor support
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/delay.h>
#define DRIVER_VERSION "2014.05.15"
#define DRIVER_AUTHOR "SE7EN"
#define DRIVER_DESC "Four Phases StepMotor Driver"
#define DRIVER_LICENSE "GPL"
#define DEVICE_NAME "motor"
#define MOTOR_MAJOR 173
#define MOTOR_IOC_MAGIC 'm'
#define MOTOR_IOCGETDATA _IOR(MOTOR_IOC_MAGIC,1,int)
#define MOTOR_IOCSETDATA _IOW(MOTOR_IOC_MAGIC,2,int)
#define MOTOR_IOCSETLEFT _IOW(MOTOR_IOC_MAGIC,3,int)
#define MOTOR_IOCSETRIGHT _IOW(MOTOR_IOC_MAGIC,4,int)
#define MOTOR_IOC_MAXNR 4
#define DEF_PULSE 2500
#define PHASE_A GPIO_PE(20)
#define PHASE_B GPIO_PE(21)
#define PHASE_C GPIO_PE(22)
#define PHASE_D GPIO_PE(29)
#define DIRECTION_L GPIO_PB(2)
#define DIRECTION_R GPIO_PA(29)
#define THOUSAND_US 1000000
/* debug macros */
#define DEBUG 1
#ifdef DEBUG
#define DPRINTK(fmt,args...) printk(fmt,##args)
#else
#define DPRINTK(fmt,args...)
#endif
typedef struct _stepMotorInfo
{
uint openCnt;
uint pulse;
uint phase_a;
uint phase_b;
uint phase_c;
uint phase_d;
uint direction_left;
uint direction_right;
uint irqCntLeft;
uint irqCntRight;
spinlock_t lock;
struct semaphore sem;
struct tasklet_struct tasklet_left;
struct tasklet_struct tasklet_right;
struct class *class;
struct cdev cdev;
}stepMotorInfo,*pstepMotorInfo;
stepMotorInfo motor;
static int motor_major = MOTOR_MAJOR;
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);
MODULE_VERSION(DRIVER_VERSION);
static irqreturn_t motorTurnLeftHandle(int irq,void *dev_id)
{
pstepMotorInfo pMotor = (pstepMotorInfo)dev_id;
tasklet_schedule(&pMotor->tasklet_left);
return IRQ_HANDLED;
}
static irqreturn_t motorTurnRightHandle(int irq,void *dev_id)
{
pstepMotorInfo pMotor = (pstepMotorInfo)dev_id;
tasklet_schedule(&pMotor->tasklet_right);
return IRQ_HANDLED;
}
//A->AB->B->BC->C->CD->D->DA->A
static void stepMotorTurnLeft(pstepMotorInfo motor)
{
//->A
gpio_direction_output(motor->phase_b,0);
gpio_direction_output(motor->phase_c,0);
gpio_direction_output(