#ifndef MODULE
#define MODULE
#endif

#ifndef __KERNEL__
#define __KERNEL__
#endif


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

RTIME period;

static RT_TASK mytask1;

MODULE_LICENSE("GPL");

		// message size

unsigned long *ptr;
unsigned long *pbdr;
unsigned long *pbddr;
unsigned long *pfdr;
unsigned long *pfddr;
unsigned long *int_han;
unsigned long *status;
unsigned long *clear;
unsigned long *GPIOBT1;
unsigned long *GPIOBT2;
unsigned long *softintclr;

int r1, r2, rall = 0;
#define IRQ_NUM 59

int adata = 1;


int irq_handler(int irq){

	rt_disable_irq(irq);
	ptr = (unsigned long *) __ioremap(0x80840000, 4096, 0);
	pbdr = ptr + 0x01;
	clear = ptr + 0x2D;
	status = ptr + 0x2F;


	if(*status == 0x01 && r1 == 0){
		r1 = 1;
		adata = 2;
		rtf_put(0, &adata, sizeof(adata));
		*pbdr |= 0X80;
	}
	else if(*status == 0x01 && r1 == 1){
		r1 = 0;
		adata = 3;
		rtf_put(0, &adata, sizeof(adata));
		*pbdr &= 0XFFFFFF7F;
	}
	else if(*status == 0x02 && r2 == 0){
		r2 = 1;
		adata = 4;
		rtf_put(0, &adata, sizeof(adata));
		*pbdr |= 0X40;
		}
	else if(*status == 0x02 && r2 == 1){
		r2 = 0;
		adata = 5;
		rtf_put(0, &adata, sizeof(adata));
		*pbdr &= 0XFFFFFFBF;
		}

	*clear |= 0xFF;

	rt_enable_irq(irq);
	return 0;
}



static void display(){

	        	while(1){
	        		adata = 1;
	        		rtf_put(0, &adata, sizeof(adata));
	        		rt_task_wait_period();
	        	}

}




int init_module(void){
		period = start_rt_timer(nano2count(1000000));
	    rt_task_init(&mytask1, display, 0, 256, 0,0,0);
	    rt_task_make_periodic(&mytask1, rt_get_time()+period, 1000 * period);
        ptr = (unsigned long *) __ioremap(0x80840000, 4096, 0);
        rtf_create(0, sizeof(adata));

			pbddr = ptr + 0x05;
			int_han = ptr + 0x2E;
			GPIOBT1 = ptr + 0x2B;
			GPIOBT2 = ptr + 0x2C;


			*pbddr &= 0xFFFFFFFC;
			*pbddr |= 0xE0;
        	*int_han |= 0x03;
        	*GPIOBT1 |= 0x03;
        	*GPIOBT2 &= 0xFFFFFFFC;


        rt_request_irq(IRQ_NUM, (irqreturn_t*)irq_handler, NULL, 1);
        rt_enable_irq(IRQ_NUM);

        return 0;
}




void cleanup_module(void){
	ptr = (unsigned long *) __ioremap(0x80840000, 4096, 0);
	pbdr = ptr + 0x01;
	*pbdr &= 0xFFFFFF00;
				rt_disable_irq(IRQ_NUM);
				rt_release_irq(IRQ_NUM);
                rt_task_delete(&mytask1);
                rtf_destroy(0);
}
