#define DDC_IDEA_SIMULATOR #define AVB_1553_REAL_DEVICE #ifndef AVB_1553_REAL_DEVICE #include "TS_drv.h" #include "Int.h" #include "Mt.h" #include "BC.h" //#include //#include //#include "time_metrics.h" #include #ifndef WINVER #define WINVER 0x501 #endif #include class SmallMimicDevice { public: struct ddc_mem_t { unsigned long long align; unsigned long tt_base; unsigned long intr_raised; unsigned long long spare[64]; uint16_t ctrl[1024]; unsigned long long spare2[64]; uint16_t mem[8*1024]; unsigned long long spare3[64]; }; HANDLE hSharedEvent; HANDLE hSharedMemory; void* shMemP; volatile ddc_mem_t* ddc_mem; volatile uint16_t* rtg_avb_sim_control__; volatile uint16_t* rtg_avb_sim_dpram__; unsigned int tgt_rt; enum { sh_mem_size=64*1024}; SmallMimicDevice(bool create=false): hSharedEvent(0), hSharedMemory(0), ddc_mem(0), rtg_avb_sim_control__(0), rtg_avb_sim_dpram__(0) { instance=this; shMemP=0; hSharedMemory=::OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "SmallMimic_DDC_SharedMemory"); if (hSharedMemory==NULL || hSharedMemory==INVALID_HANDLE_VALUE) { if (create) { hSharedMemory=::CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sh_mem_size, "SmallMimic_DDC_SharedMemory"); if (!hSharedMemory) { //qDebug()<<"SM: cannot create shared memory"; hSharedMemory=0; } } } if (!hSharedMemory) { //qDebug()<<"SM-DDC Device: cannot open shared memory: Working stand-alone"; } else { shMemP=::MapViewOfFile(hSharedMemory, FILE_MAP_ALL_ACCESS, 0, 0, sh_mem_size); if (!shMemP) { //qDebug()<<"SM-DDC Device: cannot map shared memory - Working stand-alone"; CloseHandle(hSharedMemory); hSharedMemory=0; } else { hSharedEvent=::CreateEventA(0, FALSE, FALSE, "SmallMimic_DDC_Device_Event"); if (!hSharedEvent || hSharedEvent==INVALID_HANDLE_VALUE) { //qDebug()<<"SM: cannot open shared event - Cannot generate pseudo-interrupt"; CloseHandle(hSharedMemory); hSharedMemory=0; hSharedEvent=::CreateEvent(0, FALSE, FALSE, 0); } } } if (!shMemP) { shMemP=new char[sizeof(ddc_mem_t)]; } ddc_mem=reinterpret_cast(shMemP); rtg_avb_sim_control__=&(ddc_mem->ctrl[0]); rtg_avb_sim_dpram__=&(ddc_mem->mem [0]); tgt_rt=0; //qDebug()<<"SM: DDC shared resources succesfully created"; atexit(SmallMimicDevice::staticCleanUp); } uint16_t timetag() { static uint16_t tt; return tt++; } bool checkDdc(unsigned int rt) { if (!rtg_avb_sim_control__) return false; if (rt==0) return true; if (tgt_rt==0) tgt_rt=20; return rt==tgt_rt; } enum intr_type_t { intr_bc_eof=1<<3, intr_eom=1, intr_eom_sa=1<<4}; void intrGenerate(unsigned int type) { ddc_mem->intr_raised|=type; SetEvent(hSharedEvent); } unsigned int intrGenAndClear() { unsigned int i=ddc_mem->intr_raised; ddc_mem->intr_raised=0; return i; } bool intrWait(unsigned int timeout=INFINITE) { DWORD res=::WaitForSingleObject(hSharedEvent, timeout); if (res==WAIT_OBJECT_0) return true; return false; } void writeModeData(unsigned int mc, uint16_t value) { if (mc==17) rtg_avb_sim_dpram__[0x110+1]=value; } void writeMessage(unsigned int rt, unsigned int subaddress, uint16_t* const data, unsigned int size) { if (!checkDdc(rt)) return; uint16_t sp=rtg_avb_sim_dpram__[0x100]; rtg_avb_sim_control__[0x3]=sp; if (sp>0x0FF) return; if (subaddress>31) return; rtg_avb_sim_dpram__[sp+3]=rt|(uint16_t(subaddress)<<5)|size; rtg_avb_sim_dpram__[sp+1]=timetag(); rtg_avb_sim_dpram__[sp+0]=0x8000; rtg_avb_sim_dpram__[0x100]=uint16_t((sp+4) & 0x0FF); int gen_intr=0; if (subaddress==0) { if (size>=0x10) { int n=size-0x10; rtg_avb_sim_dpram__[0x110+n]=data[0]; gen_intr=rtg_avb_sim_dpram__[0x109] & (1< #ifdef USE_MM_TIMER #define TIMEOUT_VAR default_wait_time #else #define TIMEOUT_VAR minor_frame_time #define timeSetEvent(a_, b_, c_, d_, e_) (0) #define timeKillEvent(x_) ((void)(0)) #endif class WorkerThread//: public QThread { public: WorkerThread(void (*cb)(void)): stopMe(false), //mmT(0), hEvent(0), callback(cb) { hEvent=CreateEvent(0, FALSE, FALSE, 0); hCtrlEvent=CreateEvent(0, TRUE, TRUE, 0); ResetEvent(hCtrlEvent); pauseMe=true; minor_frame_time=100; wait_time=&TIMEOUT_VAR; default_wait_time=INFINITE; //start(); //QThread::TimeCriticalPriority); } unsigned int minor_frame_time; unsigned int* wait_time; unsigned int default_wait_time; unsigned int fpos; void setTime(unsigned int ms) { minor_frame_time=ms; } void go() { stopMe=false; fpos=0; if (minor_frame_time<10) minor_frame_time=10; pauseMe=false; SetEvent(hCtrlEvent); mmT=timeSetEvent(minor_frame_time, 0, (LPTIMECALLBACK)hEvent, 0, TIME_PERIODIC|TIME_CALLBACK_EVENT_SET); //|TIME_KILL_SYNCHRONOUS); } virtual void kill() { stop(); stopMe=true; pauseMe=true; CloseHandle(hCtrlEvent); if (hEvent) CloseHandle(hEvent); } virtual void stop() { if (mmT) timeKillEvent(mmT); pauseMe=true; ResetEvent(hCtrlEvent); } protected: volatile bool stopMe; volatile bool pauseMe; MMRESULT mmT; HANDLE hEvent; HANDLE hCtrlEvent; void (*callback)(void); virtual void run() { do { WaitForSingleObject(hCtrlEvent, 1000); for(; !pauseMe && !stopMe;) { DWORD res=WaitForSingleObject(hEvent, *wait_time); //INFINITE); if (res==WAIT_FAILED) break; if (res==WAIT_OBJECT_0 || res==WAIT_TIMEOUT) DdcSimulatore_SimulateBcTick_(); } } while(!stopMe); } }; static WorkerThread* wth; static unsigned int sim_ddc_generated_interrupts; void DdcSimulatore_SimulateBcTick_(bool showDbg) { static unsigned int fpos; if (!sim_frame.bc_running) return; //metricMeasure xx(mSimISR); for(;fpos "<writeMessage(rt, m.cmd_1.subadr, ddc_sim_dt[m.data_table_no].data, m.cmd_1.wcnt); } else if (m.comm_type==MODE) { if (m.cmd_1.wcnt==17) { SmallMimicDevice::instance->writeModeData(11, mc_data[m.cmd_1.wcnt]); SmallMimicDevice::instance->intrGenerate(SmallMimicDevice::intr_eom|SmallMimicDevice::intr_eom_sa); } } } if (m.first_intermessage_routine==IDEA_IMR_INT_ON_END_OF_MESSAGE || m.second_intermessage_routine==IDEA_IMR_INT_ON_END_OF_MESSAGE) { if (bc_isr_handler && (bc_intr_mask & ((1<<4)|(1<<5)|(1<<6)))==0) { S16BIT itype=sim_ddc_rt[rt].simulated ? 0x80 : 0x81; S16BIT param=0; itype=itype|(i<<8); bc_isr_handler(0, itype, param); ++sim_ddc_generated_interrupts; } } if (sim_frame.mon_running) { if (m.comm_type!=IDEA_NOP) { U16BIT header[8+32]; memset(header, 0, sizeof header); if (m.comm_type==TRANSMIT) { void* px=&(m.cmd_1); short* spx=(short*)px; header[2]=*spx; header[1]=*spx; header[0]=2<<6; } else { void* px=&(m.cmd_1); short* spx=(short*)px; header[1]=*spx; header[2]=*spx; header[0]=1<<6; } U32BIT tt_val; ddcRead_mon_rtc(0, &tt_val); header[5]=(tt_val>>16) & 0x0FFFF; header[6]=tt_val & 0x0FFFF; unsigned int x_wc=0; if (m.comm_type==MODE) { if (m.cmd_1.wcnt==17) { x_wc=1; header[8]=mc_data[17]; } } else //if (m.comm_type==RECEIVE) { x_wc=m.cmd_1.wcnt==0 ? 32 : m.cmd_1.wcnt; if (x_wc>32) x_wc=0; for(unsigned int i=0; i32) x_wc=0; header[0]|=x_wc<<8; { unsigned int p=sim_ddc_mon_stack.pos; if ((p+(sizeof header))<(sizeof sim_ddc_mon_stack.buffer)) { unsigned int s=(x_wc+8)*2; memcpy(&sim_ddc_mon_stack.buffer[p], header, s); if (sim_ddc_mon_stack.pos==p) //A simple concurrent test that can lost message { p+=s; sim_ddc_mon_stack.pos=p; } } } } } if (i==IDEA_END_OF_MINOR) { ++fpos; break; } if (i==IDEA_END_OF_MAJOR) { fpos=0; break; } if ((!sim_frame.skip_disabled) && (m.first_intermessage_routine==IDEA_IMR_SKIP_NEXT || m.second_intermessage_routine==IDEA_IMR_SKIP_NEXT)) { ++fpos; continue; } } } IDEA_INFO ddcGetIdeaInfo(Device_p /*pCrd*/) { return sim_info; } Error_t __DECL ddcResetCard(Device_p *pCrd, DRV_CONFIG *config, U16BIT /*LogNum*/) { if (!SmallMimicDevice::instance) { SmallMimicDevice::instance=new SmallMimicDevice; } *pCrd=&fakeDevice; if (config) *config=fakeConfig; if (!wth) wth=new WorkerThread(0); return 0; } Error_t IdeaResetCard(ViInt16 /*CardNo*/, ViInt16 /*Mode*/) { return 0; } Error_t __DECL ddcHaltIdea(Device_p /*pCrd*/) { return 0; } Error_t IdeaShutdown(ViInt16 /*CardNo*/) { return 0; } Error_t __DECL ddcShutDownIdea(Device_p *pCrd) { wth->kill(); *pCrd=0; return 0; } Error_t __DECL ddcIdeaCoreVersion(Device_p /*pCrd*/, char *rtl_core_ver) { strcpy(rtl_core_ver, "GC-DDC-SIM-CORE-1.0"); return 0; } Error_t __DECL ddcCardState(Device_p /*pCrd*/, CARD_STATE *state) { memset(state, 0, sizeof *state); state->bcrt=sim_frame.bc_running ? RUNNING: HALTED; state->mon=sim_frame.mon_running ? RUNNING : HALTED; if (sim_frame.bc_running && sim_frame.mon_running) state->card=RUN_BCRT_MONITOR_STATE; else if (sim_frame.bc_running) state->card=RUN_BCRT_STATE; else if (sim_frame.mon_running) state->card=RUN_MONITOR_STATE; else state->card=HALT_STATE; return 0; } Error_t __DECL ddcIdeaVersion(Device_p /*pCrd*/,char *rtl_ver,char *driver_ver,char *part_no) { if (rtl_ver) strcpy(rtl_ver, "GA-DCC-Sim-RTL-1.0"); if (driver_ver) strcpy(driver_ver, "GA-DCC-Sim-RTL-1.0"); if (part_no) strcpy(part_no, "GA-DCC-Sim-RTL-1.0"); return 0; } Error_t ddcDef_int_mask(Device_p, U16BIT mask) { bc_intr_mask=mask; return 0; } Error_t ddcDef_int_mask_monitor(Device_p /*pCrd*/, U16BIT maskreg) { maskreg=maskreg & 0xF000; bc_intr_mask=bc_intr_mask & 0x0FFF; bc_intr_mask|=maskreg; return 0; } Error_t ddcDef_int_mask_bcrt(Device_p /*pCrd*/, U16BIT maskreg) { maskreg=maskreg & 0x0FFF; bc_intr_mask=bc_intr_mask & 0xF000; bc_intr_mask|=maskreg; return 0; } Error_t ddcSelect_bus(Device_p /*pCrd*/, U16BIT /*bus_a_state*/, U16BIT /*bus_b_state*/) { return 0; } Error_t ddcRead_mon_rtc(Device_p, U32BIT* tt_val) { DWORD tt=GetTickCount(); *tt_val=tt*1000; return 0; } Error_t ddcDef_monitor_stack(Device_p /*pCrd*/, U16BIT /*type*/) { return 0; } Error_t ddcDef_minor_frame_time(Device_p /*pCrd*/, S32BIT val) { sim_frame.m_time=val; wth->setTime(val/1000); return 0; } Error_t ddcDef_table_size(Device_p /*pCrd*/, S16BIT id, S16BIT size) { if (id<0 || id>=SIM_DT_NUM) return 1; ddc_sim_dt[id].size=size; return 0; } Error_t ddcDef_rt_map(Device_p /*pCrd*/, S16BIT /*tadr*/, S16BIT /*tr_bit*/, S16BIT /*sadr*/, S16BIT /*table_id*/) { return 0; } Error_t ddcSetBCRTEvent(Device_p /*pCrd*/, S32BIT (*usr_handler)(Device_p, S16BIT, S16BIT)) { bc_isr_handler=usr_handler; return 0; } Error_t ddcSetMONEvent(Device_p /*pCrd*/, S32BIT (*usr_handler)(Device_p)) { mon_isr_handler=usr_handler; return 0; } Error_t ddcHalt_bcrt(Device_p /*pCrd*/) { sim_frame.bc_running=false; //if (!sim_frame.mon_running) wth->stop(); return 0; } Error_t ddcHalt_mon(Device_p /*pCrd*/) { sim_frame.mon_running=false; //if (!sim_frame.bc_running) // wth->stop(); return 0; } Error_t ddcRun_bc(Device_p /*pCrd*/, S16BIT /*position*/, S32BIT /*times*/) { sim_frame.bc_running=true; //if (!sim_frame.mon_running) wth->go(); return 0; } Error_t ddcRun_mon(Device_p /*pCrd*/) { sim_frame.mon_running=true; //if (!sim_frame.bc_running) // wth->go(); return 0; } Error_t ddcDef_message(Device_p /*pCrd*/, S16BIT id, tagMESSAGE *message) { if (id<1 || id>=1024) return 1; message_table.msg[id]=*message; return 0; } Error_t ddcDef_frame(Device_p /*pCrd*/, S16BIT length, U16BIT *frame) { for(int i=0; i (unsigned int)((*messages)*40)) // s= (*messages)*40; memcpy(buf, sim_ddc_mon_stack.buffer, s); *messages=s/(sizeof(U16BIT)*40); *count=s/2; sim_ddc_mon_stack.pos=0; return 0; } Error_t ddcRead_time_tags(Device_p /*pCrd*/, void * /*buf*/, S16BIT *count) { *count=0; return 0; } Error_t ddcWrite_mode_data(Device_p /*pCrd*/, S16BIT /*tadr*/, S16BIT mode_code, S16BIT val) { mc_data[mode_code]=val; return 0; } Error_t ddcDef_rt(Device_p /*pCrd*/, S16BIT tadr, _tagRT_DEFS * /*rt*/) { sim_ddc_rt[tadr].simulated=true; return 0; } Error_t ddcSet_busy(Device_p /*pCrd*/, S16BIT tadr, S16BIT /*immediate*/) { sim_ddc_rt[tadr].busy=true; return 0; } Error_t ddcDef_emulate_rt(Device_p /*pCrd*/, S16BIT /*tadr*/, S16BIT /*emulate*/) { return 0; } Error_t ddcDecode_mon_message(Device_p /*pCrd*/, U16BIT *buf, MON_MSG *msg) { static volatile int invalid_msg; memset(msg, 0, sizeof *msg); msg->broadcast=0; unsigned int cmode=(buf[0]>>6) & 0x3; unsigned int c1=1; unsigned int c2=2; if (cmode==2) { c1=2; c2=1; } msg->comm_type= cmode==2 ? TRANSMIT : cmode==0 ? MODE : RECEIVE; msg->cmd_1=buf[c1]; msg->cmd_2=buf[c2]; msg->s_cmd_1=*(struct com*)&buf[c1]; msg->s_cmd_2=*(struct com*)&buf[c2]; msg->cmd_1_flag=c1==1 ? 1: 0; msg->cmd_2_flag=c1==1 ? 0 : 1; msg->tx_status=buf[3]; msg->rx_status=buf[4]; msg->word_count=(buf[0]>>8) & 0x3F; msg->data_buf=(S16BIT*)(buf+8); msg->next_msg=(S16BIT*)(buf+8+ msg->word_count); msg->rtc=(buf[5]<<16) | buf[6]; unsigned int ec=(buf[7]>>1) & 0xF; if (ec==0) { if (cmode==2) { msg->stat_r_flag=0; msg->stat_t_flag=1; } else { msg->stat_r_flag=1; msg->stat_t_flag=0; } //msg->rx_status=buf[c1]; //msg->tx_status=buf[c2]; msg->error=NO; msg->error_inf.type=0; } else { msg->error=YES; msg->error_inf.type=TYPE_NO_RESPONSE; msg->stat_r_flag=0; msg->stat_t_flag=0; } if (msg->s_cmd_1.tadr==0) ++invalid_msg; return 0; } Error_t ddcGetErrorMessage(Device_p /*pCrd*/, S32BIT /*error_number*/, char *error_string) { strcpy(error_string, "unknown"); return 0; } Error_t ddcWrite_data(Device_p /*pCrd*/, S16BIT id, S16BIT *buf, S16BIT count, S16BIT pos) { if (id<1 || id>250) return 1; S16BIT n=(count+pos)-1; if (n<0 || n>32) return 2; if (pos<1 || pos>32) return 3; memcpy(&(ddc_sim_dt[id].data[pos-1]), buf, 2*((count-pos)+1)); return 0; } Error_t ddcRead_data(Device_p /*pCrd*/, S16BIT id, S16BIT *buf, S16BIT count) { /* static U16BIT sim_counter; if (id<1 || id>250) return 1; if (count<1 || count>32) return 2; for(int i=0; i<32; ++i) ddc_sim_dt[id].data[i]= ++sim_counter; */ memcpy(buf, ddc_sim_dt[id].data, count*2); return 0; } Error_t ddcRead_message(Device_p /*pCrd*/, S16BIT /*id*/, tagMESSAGE *message) { message->det_error=NO_ERROR; return 0; } bool DdcSimulator_isSimulator() { return true; } #else bool DdcSimulator_isSimulator() { return false; } void DdcSimulator_SimulateBcTick() { } #endif