/*
 * comm.c
 *
 *  Created on: 01-08-2013
 *      Author: Krzysztof Jakubczyk
 */


#include <xdc/std.h>

#include <string.h>
#include <stdio.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/hal/Timer.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>

#include <ti/ipc/Ipc.h>
#include <ti/ipc/MultiProc.h>
#include <ti/ipc/MessageQ.h>
#include <ti/ipc/Notify.h>

#include "version.h"
#include "comm.h"
#include "misc.h"
#include "cfg_var.h"
#include "tdefs.h"
#include "logman.h"
#include "spi.h"
#include "logic_elements/elements.h"
#include "logic_elements/events_reg.h"
#include "logic_elements/dfr.h"
#include "logic_elements/ddr.h"
#include "logic_elements/measurand.h"
#include "logic_elements/leds_drv.h"
#include "logic_elements/virt_in_drv.h"
#include "logic_elements/dfr_drv.h"
#include "logic_elements/ddr_drv.h"
#include "logic_elements/rec_float.h"
#include "logic_elements/rec_an.h"
#include "logic_elements/rec_buf.h"
#include "logic_elements/analog_in.h"
#include "logic_elements/event.h"
#include "logic_elements/events_reg.h"
#include "logic_elements/dev_ctrl.h"
#include "logic_elements/an_gen.h"
#include "logic_elements/events_reg.h"
#include "logic_elements/mki7.h"
#include "logic_elements/mki7_2.h"
#include "config.h"
/// ethernet
#include "ethernet/ports/am1808/include/lwiplib.h"
#include "ethernet/emac.h"
#include "ports/am1808/include/netif/sitaraif.h"
#include <ti/sysbios/hal/Hwi.h>
///

Timer_Handle tick_timer_handle;
u32 tick_timer_period;
static MessageQ_Handle	msgqueue_local;
struct notify_data notify;
struct broadcast_info bcast_nfo;
volatile struct ping_info ping_nfo;

struct eth_data eth = { .flags = 0 };

volatile u8 saved_bank = 0;

//u8 time_good=0;

Void commFxn(UArg a0, UArg a1) 
{
	struct timeval cur_time_old;
	int status = 0;
	UInt16 remoteProcId;
	MessageQ_Params msgqParams;
	struct msg_data *msg;
	int ret;
	u8 may_sync_hw;
	u8 may_sync_sw;
	MessageQ_QueueId msgqueue_id_remote;
	int offset;
	struct parsed_cfg_transport_line *line = (struct parsed_cfg_transport_line *)shared_buf;
	int i;
	float tmp;
	int tmpstate;
	u8 *off;
	char firm_ver[40];
	u8 first_tsync=1;
	u16 kob_bin=0;

	snprintf(firm_ver,sizeof(firm_ver),SW_VER" %u",(u32)ic->fpga_verl|((u32)ic->fpga_verh<<16));

	tick_timer_handle = Clock_getTimerHandle();
	tick_timer_period = Timer_getPeriod(tick_timer_handle);
	dbg.tick_period = tick_timer_period;
	dbg.logman_buf_capacity = sizeof(log_manager.buf);

    do
    {
    	Task_sleep(1);
    	status = Ipc_start();
    }
    while(status == Ipc_E_NOTREADY);

    remoteProcId = MultiProc_getId("HOST");

    do
    {
		Task_sleep(1);
    	status = Ipc_attach(remoteProcId);
    } while(status == Ipc_E_NOTREADY);

    MessageQ_Params_init(&msgqParams);

    msgqueue_local = MessageQ_create("MsgQdsp", &msgqParams);

    if(msgqueue_local == NULL)
    	System_printf("queue failed\n");
    else
    	System_printf("queue succ\n");

// notify subsystem from dsp to arm

    notify.lineId               = 0;
    notify.eventId              = 7;
    notify.remoteProcId         = remoteProcId;

    do
    {
        status = Notify_sendEvent(notify.remoteProcId,notify.lineId,notify.eventId, NOTIFY_INIT, TRUE);

        if (status == Notify_E_EVTNOTREGISTERED)
            Task_sleep(10);

    } while (status == Notify_E_EVTNOTREGISTERED);

    for(;;)
    {
    	status = MessageQ_get(msgqueue_local, (MessageQ_Msg *)&msg, MessageQ_FOREVER);
    	if(status == 0)
    	{
    		msgqueue_id_remote = MessageQ_getReplyQueue(msg);
    		switch(msg->cmd)
    		{
    			case DSP_CMD_INIT_COMM:
    				msg->p1 = CMD_ACK;
    				if(msg->p2 == 0xAA55AA55) // neg pps
    				    ic->sync_reg=0;

    				while(!spi_fram_restored)
    					Task_sleep(100); // wait for spi first read

    				msg->p3 = saved_bank;

    				break;

    			case DSP_CMD_GET_ANALOG_BUF:
    				analog_buf_card = msg->p1;
    	 			analog_buf_channel = msg->p2;

    	 			for(i=0;i<127;i++)
    					analog_buf[i]=(short)bus_an_samples_buf[analog_buf_card][analog_buf_channel][(bus_an_cur_sample_num+i)%(SAMPLES_PER_MS*MAIN_FREQ_PERIOD_MS*2)] - 32767;

    				memcpy((char*)shared_buf,(char*)analog_buf,sizeof(analog_buf));
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = sizeof(analog_buf);
    				break;

    			case DSP_CMD_GET_MEASURANDS:

    				switch(msg->p1)
    				{
						case 0:
	 						for(i=0;i<measurands.count;i++)
							{
								*((char *)shared_buf+(i<<2)+i) = measurands.id[i];
							/*	if(i<=6)
									tmp=debug_size[i];
								else*/
									tmp=*(measurands.value[i]);
								memcpy((char *)shared_buf+(i<<2)+i+1,(char *)&tmp,sizeof(float));
							}
							break;
						case 1:
							for(i=0;i<measurands.count;i++)
							{
								*((char *)shared_buf+(i<<2)+i) = measurands.id[i];
								tmp=*(measurands.value_pri[i]);
								memcpy((char *)shared_buf+(i<<2)+i+1,(char *)&tmp,sizeof(float));
							}
							break;
						case 2:
							for(i=0;i<measurands.count;i++)
							{
								*((char *)shared_buf+(i<<2)+i) = measurands.id[i];
								tmp=*(measurands.value_sec[i]);
								memcpy((char *)shared_buf+(i<<2)+i+1,(char *)&tmp,sizeof(float));
							}
							break;
						default:
							for(i=0;i<measurands.count;i++)
							{
								*((char *)shared_buf+(i<<2)+i) = measurands.id[i];
								tmp=*(measurands.value[i]);
								memcpy((char *)shared_buf+(i<<2)+i+1,(char *)&tmp,sizeof(float));
							}
							break;
    				}

    				msg->p2 = sizeof(shared_buf);
    				msg->p3 = measurands.count;

    				break;

    			case DSP_CMD_GET_FWVER:
   					memcpy((char *)shared_buf,firm_ver,40);
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = sizeof(shared_buf);
    				break;

    			case DSP_CMD_GET_NET_BUF:
    				offset=0;
    				// maybe use semaphore to avoid race condition
    				memcpy((char*)shared_buf,(char*)&log_manager.nets_data[msg->p1],256);
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = offset;
    				break;

    			case DSP_CMD_GET_IO_BUF:
    				offset=0;
    				// maybe use semaphore to avoid race condition
    				//memcpy((char*)shared_buf,(char*)ic->bin_in,sizeof(ic->bin_in));
    				//offset=sizeof(ic->bin_in);
    				memcpy((char*)shared_buf,(char*)bus_bin_data,sizeof(bus_bin_data));
    				offset=sizeof(bus_bin_data);
    				memcpy((char*)shared_buf+offset,(char *)ic->out_set,sizeof(ic->out_set));
    				offset+=sizeof(ic->out_set);
    				memcpy((char*)shared_buf+offset,(char *)&ic->kob_an,12); // kobs and errs
    				offset+=2;

    				kob_bin=ic->kob_bin;
    				for(i=0;i<8;i++)
    				{
    					if(mwd32_mask & (1<<i))
    					{
    						if(kob_bin & (1<<i))
    							kob_bin|=(1<<(i+8));
    						else
    							kob_bin&=~(1<<(i+8));
    					}
    				}

    				memcpy((char*)shared_buf+offset,(char *)&kob_bin,2); // kobs and errs
    				offset+=2;

    				memcpy((char*)shared_buf+offset,(char *)&ic->kob_out,8); // kobs and errs
    				offset+=8;




    				memcpy((char*)shared_buf+offset,(char *)&samples_dropped,2);
    				offset+=2;
    				memcpy((char*)shared_buf+offset,(char*)bus_bin_data_ench,sizeof(bus_bin_data_ench));
    				offset+=sizeof(bus_bin_data_ench);


    				for(i=0;i<8;i++)
    				{
    					if(mwd32_mask & (1<<i))
    					{
    						if(ic->kob_bin & (1<<i))
    							kob_bin_ench|=(1<<i) | (1<<(i+8));
    						else
    							kob_bin_ench&=~((1<<i) | (1<<(i+8)));
    					}
    					else
							kob_bin_ench&=~((1<<i) | (1<<(i+8)));
    				}

    				memcpy((char*)shared_buf+offset,(char*)&kob_bin_ench,sizeof(kob_bin_ench));
    				offset+=sizeof(kob_bin_ench);


    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = offset;
    				break;

    			case DSP_CMD_GET_LEDS_VIRT_IN:
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = 16+MAX_BIN_CARDS+(MAX_OUT_CARDS*2)+8;//+MAX_BIN_CARDS;
    				memcpy((char*)shared_buf+0,(char *)&led_states,4);
    				memcpy((char*)shared_buf+4,(char *)&led_blink_states,4);
    				memcpy((char*)shared_buf+8,(char *)&virt_in_mask,4);
    				memcpy((char*)shared_buf+12,(char *)&virt_in_states,4);
    				memcpy((u8*)shared_buf+16,(u8*)force_bus_bin_data,MAX_BIN_CARDS);
    				memcpy((u8*)shared_buf+16+MAX_BIN_CARDS,(u8*)force_bus_out_data,MAX_OUT_CARDS*2);
    				memcpy((char*)shared_buf+16+MAX_BIN_CARDS+(MAX_OUT_CARDS*2),(char *)&virt_in2_mask,4);
    				memcpy((char*)shared_buf+16+MAX_BIN_CARDS+(MAX_OUT_CARDS*2)+4,(char *)&virt_in2_states,4);

//    				memcpy((char*)shared_buf+16+MAX_BIN_CARDS+(MAX_OUT_CARDS*2)+4+4,(char *)&force_bus_bin_data_ench,MAX_BIN_CARDS);

    				break;

    			case DSP_CMD_GET_GI:
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = sizeof(shared_buf);

    				if(ev_reg_log==NULL)
    				{
    					msg->p3 = 0;
    					break;
    				}
    				else
    					msg->p3 = ev_reg_log->events_count;

    				if(msg->p3>1024)
    					msg->p3=1024;

    				for(i=0;i<msg->p3;i++)
    				{
    					struct event_args *ev_args;
    					struct event_logic *ev_log;
    					u32 data;

    					ev_args = (struct event_args *)log_manager.log_element[ev_reg_log->element_num[i]].fun_args_ptr;
    					ev_log = (struct event_logic *)log_manager.log_element[ev_reg_log->element_num[i]].fun_log_ptr;

    					data=((u32)ev_args->params.fun<<16)|((u32)ev_args->params.inf<<8)|ev_log->prev_state;
    					memcpy((char*)shared_buf+(i<<2),(char *)&data,4);
    				}
    				break;

    			case DSP_CMD_SET_VIRT_IN:
    				tmpstate=virt_in_states & ~msg->p1;
    				virt_in_states = tmpstate|(msg->p1 & msg->p2);
    				break;

    			case DSP_CMD_SET_VIRT_IN2:
    				tmpstate=virt_in2_states & ~msg->p1;
    				virt_in2_states = tmpstate|(msg->p1 & msg->p2);
    				break;

    			case DSP_CMD_FORCE_OUT_STATES:
    				msg->p1 = CMD_ACK;
    				msg->p2 = dev_ctrl_state;
    				memcpy((u8*)force_bus_out_data,(u8*)shared_buf,MAX_OUT_CARDS*2);
    				break;

    			case DSP_CMD_FORCE_BIN_STATES:
    				memcpy((u8*)force_bus_bin_data,(u8*)shared_buf,MAX_BIN_CARDS);
    				if(msg->p1==0xBEEF)
    					memcpy((u8*)force_bus_bin_data_ench,(u8*)shared_buf+MAX_BIN_CARDS,MAX_BIN_CARDS);
    				msg->p1 = CMD_ACK;
    				msg->p2 = dev_ctrl_state;
    				break;

    			case DSP_CMD_FORCE_AN_STATES:
    				msg->p1 = CMD_ACK;
    				msg->p2 = dev_ctrl_state;
    				memcpy((u8*)&genpar,(u8*)shared_buf,sizeof(genpar));
    				break;

    			case DSP_CMD_GET_AN_STATES:
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = sizeof(genpar);
    				memcpy((u8*)shared_buf,(u8*)&genpar,sizeof(genpar));
    				break;

    			case DSP_CMD_GET_SHARED_BUF:
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = sizeof(shared_buf);
    				break;

    			case DSP_CMD_UPDATE_CFG:
    				msg->p1 = CMD_ERR;

    				for(i=0;i<cfg_lut_elements;i++)
    				{
    					if(!strcmp(cfg_lut[i].name,line->name))
    					{
    						if(cfg_lut[i].type == line->type)
    						{
    							switch(line->type)
    							{
									case ARG_TYPE_BOOL:
										switch(cfg_lut[i].size)
										{
											case sizeof(unsigned char):
												if(line->bool_val)
													*((unsigned char*)cfg_lut[i].addr)|=cfg_lut[i].bit_mask;
												else
													*((unsigned char*)cfg_lut[i].addr)&=~cfg_lut[i].bit_mask;
												msg->p1=CMD_ACK;
												break;

											case sizeof(unsigned short):
												if(line->bool_val)
													*((unsigned short*)cfg_lut[i].addr)|=cfg_lut[i].bit_mask;
												else
													*((unsigned short*)cfg_lut[i].addr)&=~cfg_lut[i].bit_mask;
												msg->p1=CMD_ACK;
												break;

											case sizeof(unsigned int):
												if(line->bool_val)
													*((unsigned int*)cfg_lut[i].addr)|=cfg_lut[i].bit_mask;
												else
													*((unsigned int*)cfg_lut[i].addr)&=~cfg_lut[i].bit_mask;
												msg->p1=CMD_ACK;
												break;

											default:
												msg->p1=CMD_ERR;
												break;
										}
										break;

									case ARG_TYPE_DOUBLE:
		    							msg->p1=CMD_ACK;
										memcpy((char *)cfg_lut[i].addr,(char *)&line->double_val,cfg_lut[i].size);
										break;
									case ARG_TYPE_LONG:
		    							msg->p1=CMD_ACK;
										memcpy((char *)cfg_lut[i].addr,(char *)&line->long_val,cfg_lut[i].size);
										break;
									case ARG_TYPE_TEXT:
		    							msg->p1=CMD_ACK;
										memcpy((char *)cfg_lut[i].addr,(char *)line->text_val,cfg_lut[i].size);
										break;
									default:
		    							msg->p1=CMD_ERR;
										break;
    							}

    							if(msg->p1==CMD_ACK && (cfg_lut[i].flags & NEED_RELOAD_IC))
    								reload_ic_cfg();

    							break;

    						}
    						else
    						{
    							msg->p1=CMD_ERR;
    							break;
    						}
    					}
    				}
    				break;

    			case DSP_CMD_GET_REG_INF:
    				memcpy((u8*)shared_buf,(u8*)&regs,sizeof(regs));
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = offset;
    				break;

    			case DSP_CMD_GET_DDR_REG_INF:
    				memcpy((u8*)shared_buf,(u8*)&ddr_regs,sizeof(ddr_regs));
    				msg->p1 = (Uint32)shared_buf;
    				msg->p2 = offset;
    				break;

    			case DSP_CMD_GET_REG_MULTIPLIERS:
    				if(dfr_drv_log_ptr == NULL) // dfr driver not initialized?
    				{
    					msg->p1 = CMD_ERR;
    					break;
    				}

    				msg->p1 = CMD_ACK;
					off = (u8 *)shared_buf;

					msg->p2 = dfr_drv_log_ptr->an_count;


					for(i=0;i<dfr_drv_log_ptr->an_count;i++)
					{
						struct rec_an_logic *an_log;
						struct rec_buf_logic *an_buf_log;
						struct rec_float_args *float_args;
						struct rec_float_logic *float_log;
						struct dfr_an_comtrade_params an_comtrade_params;

						if(dfr_drv_log_ptr->element_num[i] & ELEMENT_IS_REC_FLOAT)
						{
							float_args = (struct rec_float_args *)log_manager.log_element[dfr_drv_log_ptr->element_num[i] & 0x3FFF].fun_args_ptr;
							float_log = (struct rec_float_logic *)log_manager.log_element[dfr_drv_log_ptr->element_num[i] & 0x3FFF].fun_log_ptr;
							an_comtrade_params.multiplier=float_log->mul;
							an_comtrade_params.primary=float_args->params.pierw;
							an_comtrade_params.secondary=float_args->params.wtor;
							an_comtrade_params.unit=float_args->params.jednostka | AN_IS_FLOAT;
						}
						else if(dfr_drv_log_ptr->element_num[i] & ELEMENT_IS_REC_BUF)
						{
							an_buf_log = (struct rec_buf_logic *)log_manager.log_element[dfr_drv_log_ptr->element_num[i] & 0x3FFF].fun_log_ptr;
							an_comtrade_params.multiplier=an_buf_log->an_params->multiplier;
							an_comtrade_params.primary=an_buf_log->an_params->znam_pierw;
							an_comtrade_params.secondary=an_buf_log->an_params->znam_wtor;
							an_comtrade_params.unit=an_buf_log->an_params->jednostka & 0x7FFFFFFF;
						}
						else
						{
							an_log = (struct rec_an_logic *)log_manager.log_element[dfr_drv_log_ptr->element_num[i] & 0x3FFF].fun_log_ptr;
							an_comtrade_params.multiplier=an_log->an_params->multiplier;
							an_comtrade_params.primary=an_log->an_params->znam_pierw;
							an_comtrade_params.secondary=an_log->an_params->znam_wtor;
							an_comtrade_params.unit=an_log->an_params->jednostka & 0x7FFFFFFF;
						}

						memcpy(off,(u8 *)&an_comtrade_params,sizeof(an_comtrade_params));
						off+=sizeof(an_comtrade_params);
					}
    				break;

    			case DSP_CMD_GET_REG_MULTIPLIERS_DDR:
    				if(ddr_drv_log_ptr == NULL) // ddr driver not initialized?
    				{
    					msg->p1 = CMD_ERR;
    					break;
    				}

    				msg->p1 = CMD_ACK;
					off = (u8 *)shared_buf;

					msg->p2 = ddr_drv_log_ptr->an_count;

					for(i=0;i<ddr_drv_log_ptr->an_count;i++)
					{
						struct rec_float_args *float_args;
						struct rec_float_logic *float_log;
						struct dfr_an_comtrade_params an_comtrade_params;

						if(ddr_drv_log_ptr->element_num[i] & ELEMENT_IS_REC_FLOAT)
						{
							float_args = (struct rec_float_args *)log_manager.log_element[ddr_drv_log_ptr->element_num[i] & 0x3FFF].fun_args_ptr;
							float_log = (struct rec_float_logic *)log_manager.log_element[ddr_drv_log_ptr->element_num[i] & 0x3FFF].fun_log_ptr;
							an_comtrade_params.multiplier=float_log->mul;
							an_comtrade_params.primary=float_args->params.pierw;
							an_comtrade_params.secondary=float_args->params.wtor;
							an_comtrade_params.unit=float_args->params.jednostka | AN_IS_FLOAT;
						}
						memcpy(off,(u8 *)&an_comtrade_params,sizeof(an_comtrade_params));
						off+=sizeof(an_comtrade_params);
					}
    				break;

    			case DSP_CMD_ACK_REG:
    				if(msg->p1<MAX_REG_BANKS)
    				{
    					if(regs.bank[msg->p1].state == BANK_FILLED)
    						regs.bank[msg->p1].state = BANK_EMPTY;
    				}
    				break;

    			case DSP_CMD_ACK_DDR_REG:
    				if(msg->p1<DDR_MAX_REG_BANKS)
    			 	{
    					if(ddr_regs.bank[msg->p1].state == BANK_FILLED)
    						ddr_regs.bank[msg->p1].state = BANK_EMPTY;
    				}
    				break;

    			case DSP_CMD_CLEAR_RELAYS:
    				for(i=0;i<MAX_OUT_CARDS;i++)
    					ic->out_set[i]=0;
    				msg->p1 = CMD_ACK;
    				break;

    			case DSP_CMD_TIME_SYNC:
    				may_sync_hw = (first_tsync || (msg->p2<=950000 && msg->p2>=50000 && cur_time.tv_usec>=10 && cur_time.tv_usec<=990))?1:0;
    				may_sync_sw = (first_tsync || (msg->p2<=950000 && msg->p2>=50000 && cur_time_sw.tv_usec>=10 && cur_time_sw.tv_usec<=990))?1:0;

    				timesync_method=msg->p3 & 0xFF;
    				timesync_bits=(msg->p3>>8) & 0xFF;

    				if(timesync_bits & CFG_TSYNC_USE_SWCLK)
    					cur_time_old = cur_time_sw;
    				else
    					cur_time_old = cur_time;

    				if((timesync_method!=SYNC_METHOD_IRIG_B && timesync_method!=SYNC_METHOD_IRIG_B_ZPRAE && (timesync_method!=SYNC_METHOD_CUSTOM || !(timesync_bits & CFG_TSYNC_FROM_DSP)))||first_tsync)
    				{
        				if(may_sync_sw)
        				{
							cur_time_sw.tv_sec = msg->p1;
        					if(!(timesync_bits & CFG_TSYNC_USE_SWPPS) || pps3_timeout_cnt>60000)
        						cur_time_sw.tv_usec = msg->p2 / 1000;
        				}

        				if(may_sync_hw)
    					{
    						cur_time.tv_sec=msg->p1;
    						first_tsync=0;
    	    				if(!ext_sync)
    	    					cur_time.tv_usec=msg->p2 / 1000;
    					}
    				}

    				msg->p1=cur_time_old.tv_sec;
    				msg->p2=cur_time_old.tv_usec;
    				msg->p3=(dev_ctrl_state&DEV_CTRL_STATE_IRIGB_FIX_OK)?1:0;

    				break;

    			case DSP_CMD_CFG_STATE:
    				if(msg->p1==SET_CFG_CHANGE)
    					dev_ctrl_state|=DEV_CTRL_STATE_CFG_CHANGE;
    				else if(msg->p1==SET_CFG_ERR)
    					dev_ctrl_state|=DEV_CTRL_STATE_CFG_ERR;
    				else if(msg->p1==SET_CFG_OK)
    					dev_ctrl_state&=~DEV_CTRL_STATE_CFG_ERR;

    				if(msg->p2 & 0x01)
    					dev_ctrl_state|=DEV_CTRL_STATE_PTP_OK;
    				else
    					dev_ctrl_state&=~DEV_CTRL_STATE_PTP_OK;
    				if(msg->p2 & 0x02)
    					dev_ctrl_state|=DEV_CTRL_STATE_NTP_OK;
    				else
    					dev_ctrl_state&=~DEV_CTRL_STATE_NTP_OK;

    				mki7_sfplinks=msg->p3;
    				mki7_2_sfplinks=msg->p3>>8;

    				break;

    			case DSP_CMD_SET_EVENT_FILTER:
    				events_reg_filter_act = msg->p1 ? 1 : 0;
    				events_reg_filter_period = msg->p2 > 65535 ? 65535 : msg->p2;
    				events_reg_filter_trans_limit = msg->p3 > 127 ? 127 : msg->p3;
    				break;

    			case DSP_CMD_LOGMAN_STOP:
    				logman_stop();
    				msg->p1 = CMD_ACK;
    				break;

    			case DSP_CMD_LOGMAN_RESET:
    				logman_reset();
    				msg->p1 = CMD_ACK;
    				break;

    			case DSP_CMD_LOGMAN_PUSHFUN:
    				if(!(ret=logman_pushfunc(msg->p2,(void*)shared_buf,msg->p3)))
    					msg->p1 = CMD_ACK;
    				else
    				{
    					msg->p1 = CMD_ERR;
    					msg->p2 = ret;
    				}

    				msg->p3 = (u32)log_manager.cur_buf_ptr;
    				break;

    			case DSP_CMD_LOGMAN_START:
    				saved_bank = msg->p1>5?0:msg->p1;
    				if(!(ret = logman_start()))
    					msg->p1 = CMD_ACK;
    				else
    				{
    					msg->p1 = CMD_ERR;
    					msg->p2 = ret;
    				}

    				break;

    			case DSP_CMD_DEBUGLOG:
    				if(msg->p1)
    					dev_ctrl_state|=DEV_CTRL_STATE_SD_ERR;
    				else if(dev_ctrl_state & DEV_CTRL_STATE_SD_ERR)
    					dev_ctrl_state&=~DEV_CTRL_STATE_SD_ERR;

    				dev_ctrl_state&=0x0000FFFF;
    				dev_ctrl_state|=(msg->p2&0xFFFF)<<16;

    				msg->p1 = CMD_ACK;
    				dbg.delta_period = ic->delta_period_50M;
    				dbg.phase_corr = ic->phase_corr;
    				dbg.sync_reg = ic->sync_reg;
    				dbg.max_elements = MAX_LOG_ELEMENTS;
    				dbg.nets_bufsize = LOGMAN_NETSDATA_SIZE;
    				memcpy((u8*)shared_buf,(u8*)&dbg,sizeof(dbg));
    				break;

    			case DSP_CMD_GET_EV_BUF:
    				msg->p1 = CMD_ACK;
    				memcpy((u8*)shared_buf,(u8*)&ev_db,sizeof(ev_db));
    				break;

    			case DSP_CMD_GET_PROFILE_BUF:
    				msg->p1 = (Uint32)shared_buf;
    				memcpy((u8*)shared_buf,(u8*)&log_profile,sizeof(log_profile));
    				break;

    			case DSP_CMD_GET_LOGIC_EL_PARAMS:
    				msg->p1 = (Uint32)shared_buf;

    				i=0;
    				while(log_elements[i].id!=EOF_ELEMENT && log_elements[i].id<1024 && i<2048)
    				{
    					shared_buf[i]=((u32)log_elements[i].log_size<<16) |(u32)log_elements[i].args_size;
    					i++;
    				}

    				msg->p2=i;
    				break;

    			case DSP_CMD_START_PROFILER:
    				memset(&log_profile,0,sizeof(log_profile));
    				dbg.logman_cycle_time_max=0;
    				log_manager.status|=LOGMAN_STATUS_PROFILING;
    				msg->p1 = CMD_ACK;
    				break;

    			case DSP_CMD_STOP_PROFILER:
    				log_manager.status&=~LOGMAN_STATUS_PROFILING;
    				msg->p1 = CMD_ACK;
    				break;

    			case DSP_CMD_ETH_ON:
					memcpy(eth.hwaddr,(char*)shared_buf,sizeof(eth.hwaddr));
					memcpy(eth.name,(char*)shared_buf+sizeof(eth.hwaddr),sizeof(eth.name));
					memcpy((char *)&eth.dev_no,(char*)shared_buf+sizeof(eth.hwaddr)+sizeof(eth.name),sizeof(eth.dev_no));
					memcpy((char *)&eth.unicast_ip,(char*)shared_buf+sizeof(eth.hwaddr)+sizeof(eth.name)+sizeof(eth.dev_no),sizeof(eth.unicast_ip));

					eth.ip=msg->p1;
					eth.netmask=msg->p2;
					eth.gateway=msg->p3;
					eth.flags|=ETH_GOT_SETTINGS;

					lwIPInit(0, eth.hwaddr, eth.ip, eth.netmask, eth.gateway, IPADDR_USE_STATIC);

					memcpy((u8 *)bcast_nfo.id,"ZP6",3);
					memcpy((u8 *)bcast_nfo.dev_name,"DSP ",4);
					memcpy((u8 *)bcast_nfo.dev_name+4,eth.name,16);
					bcast_nfo.dev_name[20]=0;
					bcast_nfo.mlb_type=ZPRAE_MLB12_TYPE;
					bcast_nfo.dev_type=0;
					bcast_nfo.dev_num=eth.dev_no;
					memcpy((u8 *)bcast_nfo.mac,eth.hwaddr,6);

					eth.flags|=ETH_INITIALIZED;
					Hwi_enableInterrupt(10);
					Hwi_enableInterrupt(11);
/*
					EMACTxIntPulseDisable(EMAC_0_BASE, EMAC_CTRL_0_BASE, 0, 0);
					EMACRxIntPulseDisable(EMAC_0_BASE, EMAC_CTRL_0_BASE, 0, 0);
					Hwi_disableInterrupt(10);
					Hwi_disableInterrupt(11);
					sitaraif_save_descriptors();
*/
    				msg->p1 = CMD_ACK;
    				break;

    			case DSP_CMD_ETH_OFF:
    				msg->p1 = CMD_ACK;
    				//if(eth.flags & ETH_ACTIVE)
    				{
						//EMACTxIntPulseDisable(EMAC_0_BASE, EMAC_CTRL_0_BASE, 1, 1);
						//EMACRxIntPulseDisable(EMAC_0_BASE, EMAC_CTRL_0_BASE, 1, 1);
						Hwi_disableInterrupt(10);
						Hwi_disableInterrupt(11);
						eth.flags&=~ETH_ACTIVE;
    				}

    				break;

    			case DSP_CMD_ETH_OFF_ACK:
    				msg->p1 = CMD_ACK;
    				eth.flags|=ETH_OFF_ACK;

    				break;

    			default:
    				msg->cmd = CMD_ERR;
    				msg->p1 = CMD_ERR;
    				break;
    		}

    		MessageQ_put(msgqueue_id_remote, (MessageQ_Msg)msg);
    	}

    }
}

