/*
 * events_reg.c
 *
 *  Created on: 02-06-2014
 *      Author: KJ
 */


#include "tdefs.h"
#include "misc.h"

#include <ti/ipc/Notify.h>
#include <string.h>
#include "events_reg.h"
#include "event.h"
#include "comm.h"
#include <ti/sysbios/knl/Swi.h>

struct events_db ev_db;
struct events_reg_logic *ev_reg_log = NULL;
volatile u8 events_reg_filter_act=0;
volatile u16 events_reg_filter_period=2000;
volatile u8 events_reg_filter_trans_limit=10;
volatile u8 saved_events[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void zprae_event_add(u8 fun, u8 inf)
{
	ev_db.ev[ev_db.pos].sec=(timesync_bits & CFG_TSYNC_USE_SWCLK)?cur_time_sw.tv_sec:cur_time.tv_sec;
	ev_db.ev[ev_db.pos].msec=(timesync_bits & CFG_TSYNC_USE_SWCLK)?cur_time_sw.tv_usec:cur_time.tv_usec;
	ev_db.ev[ev_db.pos].fun=fun;
	ev_db.ev[ev_db.pos].inf=inf;
	ev_db.pos++;
	ev_db.pos%=MAX_EVENTS_COUNT;
}

void zprae_event_add_with_time(u8 fun, u8 inf,struct timeval *cur_time)
{
	ev_db.ev[ev_db.pos].sec=cur_time->tv_sec;
	ev_db.ev[ev_db.pos].msec=cur_time->tv_usec;
	ev_db.ev[ev_db.pos].fun=fun;
	ev_db.ev[ev_db.pos].inf=inf;
	ev_db.pos++;
	ev_db.pos%=MAX_EVENTS_COUNT;
}

int events_reg_initlog(void *arguments, void *logic)
{
//	struct events_reg_args *args = (struct events_reg_args *)arguments;
	struct events_reg_logic *log = (struct events_reg_logic *)logic;
	int i;

	ev_reg_log=log;

	log->events_count=0;

	for(i=0;i<MAX_LOG_ELEMENTS;i++)
	{
		if(log_manager.log_element[i].flags & FUNCTION_IS_EVENT)
		{
			if((u8 *)&log->element_num[log->events_count]>(u8 *)(log_manager.buf+sizeof(log_manager.buf)-sizeof(u16)))
				return -1;

			log->element_num[log->events_count]=i;
			log->events_count++;
		}
	}

	memset(&ev_db,0,sizeof(ev_db));

	return 0;
}

void events_reg(void *arguments, void *logic)
{
	//struct events_reg_args *args = (struct events_reg_args *)arguments;
	struct events_reg_logic *log = (struct events_reg_logic *)logic;
	struct event_args *ev_args;
	struct event_logic *ev_log;
	int i,new_events;
//	dbg.temp_dbg=(u32)saved_events[0] | ((u32)saved_events[1]<<8) | ((u32)saved_events[2]<<16)| ((u32)saved_events[3]<<24);
	if(!log->start_cnt) // 1 cycle without events
	{
		log->start_cnt++;
		return;
	}

	new_events=0;

	if(!events_reg_filter_act)
		log->time_cnt=0;
	else
		log->time_cnt+=LOOP_CYCLE_MS;

	for(i=0;i<log->events_count;i++)
	{
		ev_args = (struct event_args *)log_manager.log_element[log->element_num[i]].fun_args_ptr;
		ev_log = (struct event_logic *)log_manager.log_element[log->element_num[i]].fun_log_ptr;

		if(events_reg_filter_act)
		{
			if(log->time_cnt==events_reg_filter_period)
			{
				if(ev_log->transition_cnt & EVENT_FILTERED)
					if((ev_log->transition_cnt & 0x7F)<events_reg_filter_trans_limit)
					{
						zprae_event_add(ev_args->params.fun | EVENT_FILTERED,ev_args->params.inf | EVENT_OFF);
						ev_log->transition_cnt=0;
						new_events=1;
					}
					else
						ev_log->transition_cnt&=~0x7F;
				else
					ev_log->transition_cnt=0;
			}

			if(ev_log->transition_cnt>=events_reg_filter_trans_limit && !(ev_log->transition_cnt & EVENT_FILTERED))
			{
				zprae_event_add(ev_args->params.fun | EVENT_FILTERED,ev_args->params.inf | EVENT_ON);
				ev_log->transition_cnt|=EVENT_FILTERED;
				new_events=1;
			}
		}
		else
			ev_log->transition_cnt=0;

		if(*ev_log->in_ptr & (1<<ev_log->in_bit_no))
		{
			if(!ev_log->prev_state)
			{
				if((log_manager.status & LOGMAN_STATUS_SOFT_STARTED) && (ev_log->transition_cnt & 0x7F) <= 0x7E)
					ev_log->transition_cnt++;

				if(((log_manager.status & LOGMAN_STATUS_SOFT_STARTED)||!ev_args->params.fun) && !(ev_log->transition_cnt & EVENT_FILTERED))
					zprae_event_add(ev_args->params.fun,ev_args->params.inf | EVENT_ON);
				ev_log->prev_state=1;

				if(!ev_args->params.fun)
					saved_events[(ev_args->params.inf&0x7F)>>3]|=(1<<(ev_args->params.inf%8));

				new_events=1;
			}
		}
		else
		{
			if(ev_log->prev_state)
			{
				if((log_manager.status & LOGMAN_STATUS_SOFT_STARTED) && (ev_log->transition_cnt & 0x7F) <= 0x7E)
					ev_log->transition_cnt++;

				if(((log_manager.status & LOGMAN_STATUS_SOFT_STARTED)||!ev_args->params.fun) && !(ev_log->transition_cnt & EVENT_FILTERED))
					zprae_event_add(ev_args->params.fun,ev_args->params.inf | EVENT_OFF);
				ev_log->prev_state=0;
				if(!ev_args->params.fun)
					saved_events[(ev_args->params.inf & 0x7F)>>3]&=~(1<<(ev_args->params.inf%8));
				new_events=1;
			}
		}
	}

	if(log->time_cnt >= events_reg_filter_period)
		log->time_cnt=0;

	if(new_events)
		logman_notify|=LOGMAN_NOTIFY_NEW_EVENTS;
}
