Skip to content

Instantly share code, notes, and snippets.

@nucatus
Forked from gabirx/wiegand-gpio.c
Created April 19, 2020 12:56
Show Gist options
  • Save nucatus/444f106f11178d5ae7511218299f5b8a to your computer and use it in GitHub Desktop.
Save nucatus/444f106f11178d5ae7511218299f5b8a to your computer and use it in GitHub Desktop.
Gpio read module
/* 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