Last active
April 19, 2020 12:56
-
-
Save gabirx/7264385 to your computer and use it in GitHub Desktop.
Gpio read module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* wiegand-gpio.c. | |
*. | |
* Wiegand test driver using GPIO an interrupts.. | |
* | |
*/ | |
/* Standard headers for LKMs */ | |
#include <linux/module.h><----->/* Needed by all modules */ | |
#include <linux/kernel.h><----->/* Needed for KERN_INFO */ | |
#include <linux/kobject.h> | |
#include <linux/string.h> | |
#include <linux/sysfs.h> | |
#include <linux/timer.h> | |
#include <linux/tty.h> /* console_print() interface */ | |
#include <linux/signal.h> | |
#include <linux/sched.h> | |
#include <linux/interrupt.h> | |
#include <asm/irq.h> | |
#include <mach/gpio.h> | |
const int Readers[][4] ={ | |
{0,1,2,3}, | |
{1,4,5,6} | |
}; | |
int irq_gpio01,irq_gpio02; | |
static struct wiegand | |
{ | |
int startParity; | |
int readNum; | |
char buffer[MAX_WIEGAND_BYTES]; | |
int currentBit; | |
unsigned int lastFacilityCode; | |
unsigned int lastCardNumber; | |
} | |
wiegand; | |
static struct timer_list timer; | |
irqreturn_t wiegand_data_isr(int irq, void *dev_id); | |
void wiegand_clear(struct wiegand *w) | |
{ | |
w->currentBit = 0; | |
} | |
void wiegand_init(struct wiegand *w) | |
{ | |
wiegand_clear(w); | |
} | |
void wiegand_timer(unsigned long data) | |
{ | |
struct wiegand *w = (struct wiegand *) data; | |
printk("wiegand read %d bit complete\n",w->currentBit); | |
w->currentBit=0; | |
} | |
int init_module() | |
{ | |
int retval; | |
int err;. | |
printk("Pcduino wiegand intialising\n"); | |
wiegand_init(&wiegand); | |
err = gpio_request(Readers[0][3],"Beep 0 ON"); | |
if (err) | |
{ | |
printk(KERN_DEBUG"Could not request pin %d for GPIO.\n", Readers[0][3]); | |
return -EIO; | |
} | |
err = gpio_request(Readers[1][3],"Beep 1 ON"); | |
if (err) | |
{ | |
printk(KERN_DEBUG"Could not request pin %d for GPIO.\n", Readers[1][3]); | |
return -EIO; | |
} | |
err = gpio_request(Readers[0][1],"data0"); | |
if (err) | |
{ | |
printk(KERN_DEBUG"Could not request pin %d for GPIO.\n", Readers[0][1]); | |
return -EIO; | |
} | |
err = gpio_request(Readers[0][2],"data1"); | |
if (err) | |
{ | |
printk(KERN_DEBUG"Could not request pin %d for GPIO.\n", Readers[0][2]); | |
return -EIO; | |
} | |
if(gpio_direction_output(Readers[0][3],1)) | |
{ | |
printk(KERN_DEBUG"Could not set pin %i for GPIO output.\n", Readers[0][3]); | |
return -EIO; | |
} | |
if(gpio_direction_output(Readers[1][3],1)) | |
{ | |
printk(KERN_DEBUG"Could not set pin %i for GPIO output.\n", Readers[1][3]); | |
return -EIO; | |
} | |
/** Set pin as GPIO input, with internal pull up */ | |
if(gpio_direction_input(Readers[0][1])) | |
{ | |
printk(KERN_DEBUG"Could not set pin %i for GPIO input.\n", Readers[0][1]); | |
return -EIO; | |
} | |
/** Set pin as GPIO input, with internal pull up */ | |
if(gpio_direction_input(Readers[0][2])) | |
{ | |
printk(KERN_DEBUG"Could not set pin %i for GPIO input.\n", Readers[0][2]); | |
return -EIO; | |
} | |
irq_gpio01 = gpio_to_irq(Readers[0][1]); | |
if (irq_gpio01<0) { | |
printk(KERN_DEBUG"Unable to get irq number, %d\n",irq_gpio01); | |
} | |
printk(KERN_DEBUG"register IRQ %d\n",irq_gpio01); | |
/** Request IRQ for pin */ | |
if(request_irq(irq_gpio01, wiegand_data_isr,IRQF_TRIGGER_FALLING, "wiegand_data", &wiegand)) | |
{ | |
printk(KERN_DEBUG"Can't register IRQ %d\n", irq_gpio01); | |
return -EIO; | |
} | |
irq_gpio02 = gpio_to_irq(Readers[0][2]); | |
if (irq_gpio02<0) { | |
printk(KERN_DEBUG"Unable to get irq number, %d\n",irq_gpio02); | |
} | |
printk(KERN_DEBUG"register IRQ %d\n",irq_gpio02); | |
if(request_irq(irq_gpio02, wiegand_data_isr,IRQF_TRIGGER_FALLING, "wiegand_data", &wiegand)) | |
{ | |
printk(KERN_DEBUG"Can't register IRQ %d\n", irq_gpio02); | |
return -EIO; | |
} | |
//setup the timer | |
init_timer(&timer); | |
timer.function = wiegand_timer; | |
timer.data = (unsigned long) &wiegand; | |
//turn off leds. | |
gpio_set_value(Readers[0][3], 1); | |
gpio_set_value(Readers[1][3], 1); | |
printk("wiegand ready\n"); | |
return retval; | |
} | |
irqreturn_t wiegand_data_isr(int irq, void *dev_id) | |
{ | |
struct wiegand *w = (struct wiegand *)dev_id; | |
// int data0 = gpio_get_value(Readers[0][1]); | |
// int data1 = gpio_get_value(Readers[0][2]); | |
w->currentBit++; | |
printk("[%li] %d IRQ = %d\n",jiffies,w->currentBit,irq); | |
return IRQ_HANDLED; | |
} | |
void cleanup_module() | |
{ | |
free_irq(irq_gpio01, &wiegand); | |
free_irq(irq_gpio02, &wiegand); | |
gpio_set_value(Readers[0][3], 1); | |
gpio_set_value(Readers[1][3], 1); | |
printk("wiegand removed\n"); | |
} | |
MODULE_DESCRIPTION("Wiegand test GPIO driver"); | |
MODULE_LICENSE("GPL"); | |
MODULE_AUTHOR("test"); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hello,
your project is really very INTEREST
is it possible to have more details on using your code
thank you in advance