/*
 ============================================================================
 Name        : LEDControlKernel.c
 Author      : Michael Lux
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */


#ifndef MODULE
#define MODULE
#endif

#ifndef __KERNEL__
#define __KERNEL__
#endif

#include <stdio.h>
#include <stdlib.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <asm/io.h>
#include <rtai_lxrt.h>
#include <rtai.h>

#define MAX_BUF 1024

MODULE_LICENSE("GPL");

static RT_TASK mytask;
RTIME period;
char *redLightStatus, *yellowLightStatus, *greenLightStatus;
unsigned long *ptrBDR;


static void rt_task(int t){
	int fd;
	char *myfifo = "/dev/rtf/0";
	char buf[MAX_BUF];
	fd = open(myfifo, O_RDONLY);
	while(1){
		read(fd, buf, MAX_BUF);
		if(!strcmp(buf, "0")){
			*ptrBDR |= 0x20;
		}
		else if(!strcmp(buf, "1")){
			*ptrBDR &= 0xDF;
		}
		else if(!strcmp(buf, "2")){
			*ptrBDR |= 0x40;
		}
		else if(!strcmp(buf, "3")){
			*ptrBDR &= 0xBF;
		}
		else if(!strcmp(buf, "4")){
			*ptrBDR |= 0x80;
		}
		else if(!strcmp(buf, "5")){
			*ptrBDR &= 0x7F;
		}
	}
	close(fd);
}

int init_module(void)
{

	unsigned long *ptrA, *ptrBDDR;

	ptrA = (unsigned long *) __ioremap(0x80840000,4096,0);
	ptrBDR = (unsigned long *) ((char *) ptrA + 0x04);
	ptrBDDR = (unsigned long *) ((char *) ptrA + 0x14);

	//initialize light values
	*ptrBDDR |= 0xE0;
	*ptrBDR &= 0xFFFFFF1F;

	//set to periodic mode
	rt_set_periodic_mode();
	period = start_rt_timer(nano2count(1000000));

	//initialize real-time task
	rt_task_init(&mytask, rt_task, 0, 256, 0, 0, 0);
	rt_task_make_periodic(&mytask, rt_get_time()+10*period, 75*period);

	return 0;
}

void cleanup_module(void)
{
	unsigned long *ptrA, *ptrBDR;

	ptrA = (unsigned long *) __ioremap(0x80840000,4096,0);
	ptrBDR = (unsigned long *) ((char *) ptrA + 0x04);

	*ptrBDR |= 0x00;
	rt_task_delete(&mytask);
	stop_rt_timer();
}

