/*
 ============================================================================
 Name        : fpclientkernel.c
 Author      : Stephanie Cahail
 Version     :
 Copyright   : Your copyright notice
 Description : The kernel module to be used for the client board.
 ============================================================================
 */

#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_lxrt.h>
#include <rtai_sched.h>
#include <rtai_fifos.h>
#include <linux/time.h>

MODULE_LICENSE("GPL");

static RT_TASK myTask;
RTIME period, delay;

int flag = 0;

unsigned long *ptrA, *PFDR, *PFDDR;

static void rt_process(int t){
	while(1){
        //read flag from pipe
		rtf_get(0, (int*)&flag, sizeof(int));
		if (flag == 1){
			*PFDR ^= 0x02; //speaker plays
		}
		else{
			*PFDR &= ~0x02; //disables speaker
		}
		rt_task_wait_period();//waits for other thread to complete its task
	}
}

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

	//starting pointer at port A
	ptrA = (unsigned long *) __ioremap(0x80840000, 4096, 0);

	//port F and port F direction register
	PFDR = (unsigned long *) ((char*)ptrA + 0x30);
	PFDDR = (unsigned long*) ((char*)ptrA + 0x34);
	//upper nibble set for port F direction register, since only output will be used
	*PFDDR |= 0x02;

	rt_set_periodic_mode();
	period = start_rt_timer(nano2count(1000000)); //start timer
	delay = period * 1000;//delay 1 second
	rt_task_init(&myTask, rt_process, 0, 256, 0, 0, 0);
	rt_task_make_periodic(&myTask, rt_get_time(), period);

	//create fifo 1
	rtf_create(0, sizeof(double));

	return 0;
}

void cleanup_module(void)
{
	rt_task_delete(&myTask);
	stop_rt_timer();//stop timer
	rtf_destroy(0);//delete fifo 0
	printk("MODULE REMOVED \n");
}
