/* * comm.c * * Created on: 01-08-2013 * Author: Krzysztof Jakubczyk */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 /// 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;ip2 = 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<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<kob_bin & (1<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;ip3;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;iname)) { 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*)®s,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;ian_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;ian_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->p1p1].state == BANK_FILLED) regs.bank[msg->p1].state = BANK_EMPTY; } break; case DSP_CMD_ACK_DDR_REG: if(msg->p1p1].state == BANK_FILLED) ddr_regs.bank[msg->p1].state = BANK_EMPTY; } break; case DSP_CMD_CLEAR_RELAYS: for(i=0;iout_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 *)ð.dev_no,(char*)shared_buf+sizeof(eth.hwaddr)+sizeof(eth.name),sizeof(eth.dev_no)); memcpy((char *)ð.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); } } }