/* doorKernel.c
 *
 *  Created on: May 01, 2015
 *      Author: kapvx4
 */




#ifndef MODULE
#define MODULE
#endif

#ifndef __KERNEL__
#define __KERNEL__
#endif



#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <rtai.h>
#include <rtai_sched.h>
#include <linux/time.h>
#include <rtai_fifos.h>




RTIME delay;
static RT_TASK task;
int pb = 0;
unsigned long button = 0;
unsigned long *ptr,*ptr2;
unsigned long *pfdr, *pfddr;
unsigned long *pbdr, *pbddr;
unsigned long *GPIOBIntEN, *GPIOBIntType1, *GPIOBIntType2, *GPIOBEOI,*GPIOBDB, *RawIntStsB;
unsigned long *VIC2SoftIntEnable, *VIC2SoftIntClear;
int fifo_in = 1;
int fifo_out = 0;
char pin;
int i = 1;
char password[6];
MODULE_LICENSE("GPL");




static void supply_power ()
{
while(1)
{
			*pbdr =*pbdr & 0x07; //Activate first Column
			*pbdr = *pbdr | 0x07;
			rt_task_wait_period();

			*pbdr = *pbdr & 0x0B; 	//Activate 2nd Column
			*pbdr = *pbdr | 0x0B;
			rt_task_wait_period();

			*pbdr = *pbdr & 0x0D; //Activate 3rd Column
			*pbdr = *pbdr | 0x0D;
			rt_task_wait_period();

			*pbdr = *pbdr & 0x0E; //Activate 4th Column
			*pbdr = *pbdr | 0x0E;
			rt_task_wait_period();
}

}


static void handler (unsigned irq_num, void *cookie)
{
	//check button

	rt_disable_irq(59); //Disable the request line
	//Handle stuff

	if((*RawIntStsB & 0x80) == 0x80  && (*pbdr & 0x07)== 0x07) //button 1 pressed
	{
		pin ='1';
		printk("Pressed 1.\n");

	}
	if((*RawIntStsB & 0x80) == 0x80  && (*pbdr & 0x0B)== 0x0B)//button 2 pressed
	{
		pin = '2';
		printk("Pressed 2.\n");

	}
	if((*RawIntStsB & 0x80) == 0x80  && (*pbdr & 0x0D)== 0x0D) //button 3 pressed
	{
		pin = '3';
		printk("Pressed 3.\n");


	}
	if((*RawIntStsB & 0x80) == 0x80  && (*pbdr & 0x0E)== 0x0E) //button A pressed
	{
		pin = 'A';
		printk("Pressed A.\n");

	}
	if((*RawIntStsB & 0x40) == 0x40  && (*pbdr & 0x07)== 0x07) //button 4 pressed
	{
		pin = '4';
		printk("Pressed 4.\n");

	}
	if((*RawIntStsB & 0x40) == 0x40  && (*pbdr & 0x0B)== 0x0B) //button 5 pressed
		{
		pin = '5';
		printk("Pressed 5.\n");


		}
	if((*RawIntStsB & 0x40) == 0x40  && (*pbdr & 0x0D)== 0x0D) //button 6 pressed
			{
			pin = '6';
			printk("Pressed 6.\n");

			}
	if((*RawIntStsB & 0x40) == 0x40  && (*pbdr & 0x0E)== 0x0E) //button B pressed
			{
			pin = 'B';
			printk("Pressed B.\n");


			}

	if((*RawIntStsB & 0x20) == 0x20  && (*pbdr & 0x07)== 0x07) //button 7 pressed
			{
			pin = '7';
			printk("Pressed 7.\n");


			}
	if((*RawIntStsB & 0x20) == 0x20  && (*pbdr & 0x0B)== 0x0B) //button 8 pressed
			{
			pin = '8';
			printk("Pressed 8.\n");

			}
	if((*RawIntStsB & 0x20) == 0x20  && (*pbdr & 0x0D)== 0x0D) //button 9 pressed
			{
			pin = '9';
			printk("Pressed 9.\n");


			}
	if((*RawIntStsB & 0x20) == 0x20  && (*pbdr & 0x0E)== 0x0E) //button c pressed
			{
			pin = 'C';
			printk("Pressed C.\n");


			}
	if((*RawIntStsB & 0x10) == 0x10  && (*pbdr & 0x07)== 0x07) //button * pressed
			{
			pin = '*';
			printk("Pressed *.\n");

			}
	if((*RawIntStsB & 0x10) == 0x10  && (*pbdr & 0x0B)== 0x0B) //button 0 pressed
			{
			pin = '0';
			printk("Pressed 0.\n");


			}
	if((*RawIntStsB & 0x10) == 0x10  && (*pbdr & 0x0D)== 0x0D) //button # pressed
			{
			pin = '#';
			printk("Pressed #.\n");


			}
	if((*RawIntStsB & 0x10) == 0x10  && (*pbdr & 0x0E)== 0x0E) //Button D pressed
			{
			pin = 'D';
			printk("Pressed D.\n");

			}
	password[0] = '#';
	password[i] = pin; //save entries
	printk("Password is: %s\n", password);
	i++;//count how many # entries
		if(i == 6) //if 5 entries put onto fifo
		{
		rtf_put(fifo_out, &password, 6* sizeof(password[0]));
		strcpy(password, "\0"); //clear string
		 i = 1; //reset counter
		}


	*GPIOBEOI = *GPIOBEOI | *RawIntStsB; //clear the end of the interrupt register
	rt_enable_irq(59); //re-enable the interrupt line
}

int init_module(void)
{
	printk("INSTALLING MODULE...\n");


	ptr = (unsigned long *)__ioremap(0x80840000, 4096, 0);
	//Configure the Registers
	GPIOBIntEN = (unsigned long*) ((char*) ptr + 0xB8);
	*GPIOBIntEN = *GPIOBIntEN | 0xF0;

	GPIOBIntType1 = (unsigned long*) ((char*) ptr + 0xAC);
	*GPIOBIntType1 = *GPIOBIntType1 | 0xF0;

	GPIOBIntType2 = (unsigned long*) ((char*) ptr + 0xB0);
	*GPIOBIntType2 = *GPIOBIntType2 & 0xFFFFFF0F;


	GPIOBEOI = (unsigned long*) ((char*) ptr + 0xB4);
	*GPIOBEOI = *GPIOBEOI | 0xF0;


	RawIntStsB = (unsigned long*) ((char*) ptr + 0xC0);
	//*RawIntStsB = *RawIntStsB | 0xF0;

	GPIOBDB = (unsigned long*) ((char*) ptr + 0xC4);
	*GPIOBDB = *GPIOBDB | 0xF0;

	pbdr = (unsigned long*)((char*) ptr + 0x04);
	pbddr = (unsigned long*)((char*) ptr + 0x14);
	*pbddr = *pbddr & 0xFFFFFF0F;  //Set button direction pointer to 00001111
	*pbddr = *pbddr | 0x0F;
	//create fifo
	rtf_create(fifo_out,10*sizeof(password));
	//Set up  Hardware ISR
	rt_request_irq(59, handler, 0, 1);
	rt_enable_irq(59);

	rt_set_periodic_mode(); //set to periodic mode
		delay = start_rt_timer(nano2count(1000000));
		rt_task_init(&task,supply_power, 0, 256,0,0,0);
		rt_task_make_periodic(&task, rt_get_time()+delay, 70*delay);

	printk("MODULE INSTALLED.\n");
	return 0;
}




void cleanup_module(void)
{
rt_task_delete(&task);
rtf_destroy(fifo_out);

printk("MODULE SUCCESSFULLY REMOVED.\n");
}




