/* задача опpоса DAMATROL MC512 */ #include "complex.h" #include "screen.h" typedef struct /* структура данных контроллера DMC 512 */ { byte nomc; /* номер контроллера */ byte numd; /* колич. дискр. переменных */ byte pid; /* признак наличия PID в контроллере */ byte nomv; /* начальный номер аналог. переменной */ byte numv; /* количество аналог. переменных */ word_s kza; /* kz опроса аналоговых переменных */ word_s coda[128]; /* массив кодов переменных */ word_s kzm; /* kz опроса переменных режима */ byte modb[16]; /* массив байтов режима PID0-PID15 */ word_s kzd; /* kz опроса дискр. переменных */ byte digv[16]; /* массив байтов дискр. переменных */ } imD512; extern word_s setting(analog *a_ptr,float work_f); extern void koeff_sc(analog *a_ptr); extern byte * z_db(byte *x_db,int len); extern word_s numrec, lenrec, fh, N_MAN; extern char *recfil; word_s scanD512(controller *ptr_c,byte *ask,word_s lask,byte *ans); void ask_analog_D512(word nomv,word numv,imD512 *pic,controller *ptr_c, byte *mask,byte *mans); word form_ks_D512(unsigned char *st,word_s len); char no_mem_taskd512[] = "TASKD512.C - Мало памяти"; /*-------------------------------------------------------------------*/ void taskD512(controller *ptr_c) { word_s i,j,k,begin,val; byte *mask, *mans, *v_min, *v_max, *d_max; analog *ptr_a; digit *ptr_d; imD512 *pcn, *pic; tsk_outp(ptr_c->basaddr+4,0x00); /* RTS:=0 */ tsk_outp(ptr_c->basaddr+7,0); /* off this port */ if((mask = (byte *)calloc(1,160))==NULL) { eprintf(RED_,no_mem_taskd512); return; } mans=mask+16; /* ОПРЕДЕЛЕНИЕ ОПРАШИВАЕМЫХ КОНТРОЛЛЕРОВ И МАССИВОВ ПЕРЕМЕННЫХ */ v_min=mans; v_max=v_min+16; d_max=v_max+16; for(i=0; i<16; i++) { v_min[i]=0xff; v_max[i]=0; mask[i]=0; d_max[i]=0; } for(i=0, ptr_a=ptr_c->a_ptr; i < ptr_c->num_ap; i++, ptr_a++) { if(!ptr_a->param1 || /* если не включен в опрос */ ptr_a->mod_cod==M_INP || /* если ручной ввод */ ptr_a->nolog || /* если логич. запpет обpаб. */ !ptr_a->nomin_var) continue; /* если не задан вход */ k=ptr_a->param1; if(ptr_a->nomin_var < v_min[k]) v_min[k]=ptr_a->nomin_var; if(ptr_a->nomin_var > v_max[k]) v_max[k]=ptr_a->nomin_var; if(ptr_a->type_mech) { mask[k]=1; if(ptr_a->nom_set) { if(ptr_a->nom_set < v_min[k]) v_min[k]=ptr_a->nom_set; if(ptr_a->nom_set > v_max[k]) v_max[k]=ptr_a->nom_set; } if(ptr_a->nomout_out) { if(ptr_a->nomout_out < v_min[k]) v_min[k]=ptr_a->nomout_out; if(ptr_a->nomout_out > v_max[k]) v_max[k]=ptr_a->nomout_out; } if(ptr_a->type_mech==PULS && ptr_a->nomin_pos) { if(ptr_a->nomin_pos < v_min[k]) v_min[k]=ptr_a->nomin_pos; if(ptr_a->nomin_pos > v_max[k]) v_max[k]=ptr_a->nomin_pos; } } } for(i=0, ptr_d=ptr_c->d_ptr; i < ptr_c->num_dp; i++, ptr_d++) { if(!ptr_d->param1 || /* если не включен в опрос */ ptr_d->nolog) continue; /* если логич. запpет обpаб. */ k=ptr_d->param1; if(ptr_d->nom_var > d_max[k]) d_max[k]=ptr_d->nom_var; if(ptr_d->nom_vr2 > d_max[k]) d_max[k]=ptr_d->nom_vr2; if(ptr_d->nom_vr3 > d_max[k]) d_max[k]=ptr_d->nom_vr3; if(ptr_d->nom_vr4 > d_max[k]) d_max[k]=ptr_d->nom_vr4; if(ptr_d->nom_dout > d_max[k]) d_max[k]=ptr_d->nom_dout; if(ptr_d->nom_dot2 > d_max[k]) d_max[k]=ptr_d->nom_dot2; if(ptr_d->nom_dot3 > d_max[k]) d_max[k]=ptr_d->nom_dot3; } for(k=0,i=0; i<16; i++) if(v_max[i] || d_max[i]) k++; /* подсчет контр. */ if(!k) return; /* если нечего опрашивать */ if((pcn = (imD512 *)calloc(k,sizeof(imD512)))==NULL) { eprintf(RED_,no_mem_taskd512); return; } for(pic=pcn,i=0; i<16; i++) if(v_max[i] || d_max[i]) { pic->nomc=i; pic->numd=d_max[i]; pic->pid=mask[i]; pic->nomv=v_min[i]; pic->numv=v_max[i]-v_min[i]+1; pic->kza=pic->kzm=pic->kzd=0; pic++; } begin=1; while(!endrun) { wait_flag_set(ptr_c->flag, 0L); clear_flag(ptr_c->flag); /* ОПРОС КОНТРОЛЛЕРОВ И ЗАПОЛНЕНИЕ МАССИВОВ ПЕРЕМЕННЫХ */ for(pic=pcn,i=0; inumd) { mask[0]=pic->nomc; mask[1]=1; mask[2]=0; mask[3]=0; mask[4]=0; mask[5]=pic->numd; pic->kzd=scanD512(ptr_c,mask,6,mans); if(!pic->kzd) memcpy(pic->digv,mans+3,mans[2]); } if(pic->numv) { mask[0]=pic->nomc; mask[1]=3; mask[2]=0; mask[4]=0; if(pic->numv <= 60) ask_analog_D512(pic->nomv,pic->numv,pic,ptr_c,mask,mans); else if(pic->numv <= 120) { ask_analog_D512(pic->nomv,60,pic,ptr_c,mask,mans); ask_analog_D512(pic->nomv+60,pic->numv-60,pic,ptr_c,mask,mans); } else { ask_analog_D512(pic->nomv,60,pic,ptr_c,mask,mans); ask_analog_D512(pic->nomv+60,60,pic,ptr_c,mask,mans); ask_analog_D512(pic->nomv+120,pic->numv-120,pic,ptr_c,mask,mans); } if(!pic->pid) continue; mask[0]=pic->nomc; mask[1]=1; mask[2]=1; /* старший байт от номера переменной = 328-1 */ mask[3]=71; /* младший - это начало байтов режима */ mask[4]=0; mask[5]=128; /* младший байт от количества = 128 */ pic->kzm=scanD512(ptr_c,mask,6,mans); if(pic->kzm) continue; memcpy(pic->modb,mans+3,16); } } /* ПЕРВИЧНАЯ ОБРАБОТКА ИНФОРМАЦИИ */ for(i=0, ptr_a=ptr_c->a_ptr; i < ptr_c->num_ap; i++, ptr_a++) { if(!ptr_a->param1 || /* если не включен в опрос */ ptr_a->mod_cod==M_INP || /* если ручной ввод */ ptr_a->nolog || /* если логич. запpет обpаб. */ !ptr_a->nomin_var) continue; /* если не задан вход */ for(pic=pcn,j=0; jnomc==ptr_a->param1) break; /* поиск контроллера */ if(pic->kza) { ptr_a->novalid=1; continue; } /* если ОШ */ ptr_a->novalid = 0; /* достовеpность есть */ val=pic->coda[ptr_a->nomin_var]; val *= K_D512; if(val < -(ADC_SC>>3)) ptr_a->novalid=1; if(val < 0) val=0; else if(val > ADC_SC) val=ADC_SC; if(ptr_a->var_cod == val && !begin) ptr_a->dif_var = 0; else { ptr_a->dif_var = 1; ptr_a->var_cod = val; ptr_a->var_tech = valtec(ptr_a,ptr_a->var_cod); if(ptr_a->min_reg && val < ptr_a->min_reg) ptr_a->bound_reg = 1; else if(ptr_a->max_reg && val > ptr_a->max_reg) ptr_a->bound_reg = 2; else ptr_a->bound_reg = 0; if(ptr_a->min_al && val < ptr_a->min_al) ptr_a->bound_al = 1; else if(ptr_a->max_al && val > ptr_a->max_al) ptr_a->bound_al = 2; else ptr_a->bound_al = 0; } /* if(ptr_a->var_cod < ADC_SC/100 || ptr_a->var_cod > ADC_SC-ADC_SC/100) ptr_a->novalid=1; */ if(ptr_a->type_mech) { if(ptr_a->set_din) ptr_a->set_din = 0; else if(ptr_a->nom_set) { val=pic->coda[ptr_a->nom_set]; val *= K_D512; if(val < 0) val=0; else if(val > ADC_SC) val=ADC_SC; if(ptr_a->set_cod == val && !begin) ptr_a->dif_set = 0; else { ptr_a->dif_set = 1; ptr_a->set_cod = val; } } if(ptr_a->out_din) ptr_a->out_din = 0; else if(ptr_a->nomout_out) { val=pic->coda[ptr_a->nomout_out]; val *= K_D512; if(val < 0) val=0; else if(val > ADC_SC) val=ADC_SC; if(ptr_a->out_cod == val && !begin) ptr_a->dif_out = 0; else { ptr_a->dif_out = 1; ptr_a->out_cod = val; } } val = ptr_a->var_cod - ptr_a->set_cod; if(ptr_a->dif_cod == val && !begin) ptr_a->dif_dif = 0; else { ptr_a->dif_dif = 1; ptr_a->dif_cod = val; } if(ptr_a->type_mech == PULS && ptr_a->nomin_pos) { val=pic->coda[ptr_a->nomin_pos]; val *= K_D512; if(ptr_a->pos_cod == val && !begin) ptr_a->dif_pos = 0; else { ptr_a->dif_pos = 1; if(val >= 0 && val <= ADC_SC) ptr_a->pos_cod = val; } } if(pic->kzm) continue; if(ptr_a->mod_din) ptr_a->mod_din = 0; else { if(!(pic->modb[ptr_a->param2]&0x01)) val=MAN; else if(!(pic->modb[ptr_a->param2]&0x02)) val=AUTO; else val = CAS; if(ptr_a->mod_cod == val && !begin) ptr_a->dif_mod = 0; else { ptr_a->dif_mod = 1; ptr_a->mod_cod = val; } } } } for(i=0, ptr_d=ptr_c->d_ptr; i < ptr_c->num_dp; i++, ptr_d++) { if(!ptr_d->param1 || /* если не включен в опрос */ ptr_d->nolog) continue; /* если логич. запpет обpаб. */ for(pic=pcn,j=0; jnomc==ptr_d->param1) break; /* поиск контроллера */ if(pic->kzd) { ptr_d->novalid=1; continue; } /* если ОШ */ ptr_d->novalid = 0; if(ptr_d->nom_var > 0) { val=pic->digv[(ptr_d->nom_var-1)/8] & (1 << ((ptr_d->nom_var-1)%8)); if(val) val=1; if(ptr_d->val_par == val/* && !begin*/) ptr_d->dif_par = 0; else { ptr_d->dif_par = 1; ptr_d->val_par = val; } #if (COUNT) if(ptr_d->reg_tim) { if(ptr_d->val_par) ptr_d->count_tim+=ptr_c->period; else ptr_d->count_stop+=ptr_c->period; } #endif } if(ptr_d->nom_vr2 > 0) { val=pic->digv[(ptr_d->nom_vr2-1)/8] & (1 << ((ptr_d->nom_vr2-1)%8)); if(val) val=1; if(ptr_d->val_pr2 == val/* && !begin*/) ptr_d->dif_pr2 = 0; else { ptr_d->dif_pr2 = 1; ptr_d->val_pr2 = val; } } if(ptr_d->nom_vr3 > 0) { val=pic->digv[(ptr_d->nom_vr3-1)/8] & (1 << ((ptr_d->nom_vr3-1)%8)); if(val) val=1; if(ptr_d->val_pr3 == val/* && !begin*/) ptr_d->dif_pr3 = 0; else { ptr_d->dif_pr3 = 1; ptr_d->val_pr3 = val; } } if(ptr_d->nom_vr4 > 0) { val=pic->digv[(ptr_d->nom_vr4-1)/8] & (1 << ((ptr_d->nom_vr4-1)%8)); if(val) val=1; if(ptr_d->val_pr4 == val/* && !begin*/) ptr_d->dif_pr4 = 0; else { ptr_d->dif_pr4 = 1; ptr_d->val_pr4 = val; } } #if (PROTOC) if(ptr_d->archive) { if(ptr_d->dif_par) { val=ptr_d->val_par; val<<=6; val |=ptr_c->nom_ord; val<<=9; val |=i; val |=0x1000; /*if(!begin)*/ c_write_wpipe(event_chn, val); } if(ptr_d->dif_pr2) { val=ptr_d->val_pr2; val<<=6; val |=ptr_c->nom_ord; val<<=9; val |=i; val |=0x2000; /*if(!begin)*/ c_write_wpipe(event_chn, val); } if(ptr_d->dif_pr3) { val=ptr_d->val_pr3; val<<=6; val |=ptr_c->nom_ord; val<<=9; val |=i; val |=0x3000; /*if(!begin)*/ c_write_wpipe(event_chn, val); } if(ptr_d->dif_pr4) { val=ptr_d->val_pr4; val<<=6; val |=ptr_c->nom_ord; val<<=9; val |=i; val |=0x4000; /*if(!begin)*/ c_write_wpipe(event_chn, val); } } #endif if(ptr_d->nom_dout > 0) { val=pic->digv[(ptr_d->nom_dout-1)/8] & (1 << ((ptr_d->nom_dout-1)%8)); if(val) val=1; if(ptr_d->val_out == val/* && !begin*/) ptr_d->dif_out = 0; else { ptr_d->dif_out = 1; ptr_d->val_out = val; } } if(ptr_d->nom_dot2 > 0) { val=pic->digv[(ptr_d->nom_dot2-1)/8] & (1 << ((ptr_d->nom_dot2-1)%8)); if(val) val=1; if(ptr_d->val_ot2 == val/* && !begin*/) ptr_d->dif_ot2 = 0; else { ptr_d->dif_ot2 = 1; ptr_d->val_ot2 = val; } } if(ptr_d->nom_dot3 > 0) { val=pic->digv[(ptr_d->nom_dot3-1)/8] & (1 << ((ptr_d->nom_dot3-1)%8)); if(val) val=1; if(ptr_d->val_ot3 == val/* && !begin*/) ptr_d->dif_ot3 = 0; else { ptr_d->dif_ot3 = 1; ptr_d->val_ot3 = val; } } } if(!pic->kza && !pic->kzm && !pic->kzd) begin = 0; } } /*-------------------------------------------------------------------*/ void ask_analog_D512(word nomv,word numv,imD512 *pic,controller *ptr_c, byte *mask,byte *mans) { word_s n, j; mask[3]=nomv-1; mask[5]=numv; pic->kza=scanD512(ptr_c,mask,6,mans); if(pic->kza) return; for(n=nomv,j=0; jcoda[n]=mans[j+3]; pic->coda[n] <<= 8; pic->coda[n] |= mans[j+4]; } } /*---------------------------------------------------------------------*/ word form_ks_D512(unsigned char *st,word_s len) { word i,j,ks; ks=0xffff; for(i=0; i>= 1; ks ^= 0xA001; } else ks >>= 1; } } return ks; } /*-------------------------------------------------------------------*/ word_s scanD512(controller *ptr_c,byte *ask,word_s lask,byte *ans) { word_s i,rept,kz,lans; if(ptr_c->port==NULL) return -1; while(request_resource(ptr_c->port_rsc,0L)); /* захват поpта-pесурса */ tsk_outp(ptr_c->basaddr+7,3); /* on this port */ while(1) { while((tsk_inp(ptr_c->basaddr+6) & 0x10)) { tsk_outp(ptr_c->basaddr+7,0); /* off this port */ t_delay(1L); /* пока CTS==1 */ tsk_outp(ptr_c->basaddr+7,3); /* on this port */ } tsk_outp(ptr_c->basaddr+4,0x02); /* RTS:=1 */ tsk_outp(ptr_c->basaddr+7,0); /* off this port */ t_delay(1L); tsk_outp(ptr_c->basaddr+7,3); /* on this port */ if(!(tsk_inp(ptr_c->basaddr+6) & 0x10)) break; /* если CTS==0 */ tsk_outp(ptr_c->basaddr+4,0x00); /* RTS:=0 */ } *(word_s *)(ask+lask)=form_ks_D512(ask,lask); /** while(request_resource(ptr_c->port_rsc,0L)); */ /* захват поpта-pесурса */ rept=2; BEGN: if(!rept--) goto END; for(i=0; iport,ask[i],2L); ANS0: while((kz=v24_receive(ptr_c->port,20L)) != ask[0] && kz !=-1); if(kz==-1) goto BEGN; ans[0]=kz; kz=v24_receive(ptr_c->port,2L); if(kz==-1) goto BEGN; ans[1]=kz; if((ans[1]&0x7f) != ask[1]) goto ANS0; kz=v24_receive(ptr_c->port,2L); if(kz==-1) goto BEGN; ans[2]=kz; if(ans[1]&0x80) lans=5; else switch(ans[1]) { case 1 : case 3 : lans=5+ans[2]; break; case 15: lans=8; break; default: lans=lask+2; } for(i=3; iport,2L); if(kz==-1) goto BEGN; ans[i]=kz; } if(*(word_s *)(ans+lans-2) != form_ks_D512(ans,lans-2)) { kz=0x77; /* ошибка KS */ goto BEGN; } if(ans[1]&0x80) kz=ans[2]; else kz=0; END: tsk_outp(ptr_c->basaddr+4,0x00); /* RTS:=0 */ tsk_outp(ptr_c->basaddr+7,0); /* off this port */ release_resource(ptr_c->port_rsc); /* освоб.поpта-pесуpса */ if(kz) kz=(ask[0]<<8)+(kz&0xff); ptr_c->kz=kz; kz_com(kz,ptr_c); return kz; } /*--------------- Загрузка параметров контроллера -------------------*/ void insert_A_D512(analog * a_ptr) { word_s i, work_i; float work_f; byte *x_db; for(i=0; i < numrec; i++, a_ptr++) { read(fh, recfil, lenrec); a_ptr->novalid = 1; strncpy(a_ptr->cipher, (x_db = recfil + 1), 9); strncpy(a_ptr->name, (x_db+= 9), 25); strncpy(a_ptr->unit, (x_db+= 25), 9); sscanf(x_db+= 9, "%1hd", &work_i); a_ptr->type_sc = (byte)work_i; sscanf(z_db(x_db+= 1,8), "%8f", &a_ptr->min_sc); sscanf(z_db(x_db+= 8,8), "%8f", &a_ptr->max_sc); koeff_sc(a_ptr); sscanf(z_db(x_db+= 8,8), "%8f", &work_f); a_ptr->min_reg = setting(a_ptr,work_f); sscanf(z_db(x_db+= 8,8), "%8f", &work_f); a_ptr->max_reg = setting(a_ptr,work_f); sscanf(z_db(x_db+= 8,8), "%8f", &work_f); a_ptr->min_al = setting(a_ptr,work_f); sscanf(z_db(x_db+= 8,8), "%8f", &work_f); a_ptr->max_al = setting(a_ptr,work_f); sscanf(z_db(x_db+= 8,2), "%2hd", &work_i); a_ptr->param1 =(byte)work_i; sscanf(z_db(x_db+= 2,2), "%2hd", &work_i); a_ptr->nomin_var =(byte)work_i; sscanf(x_db+= 2, "%1hd", &work_i); a_ptr->type_mech = (byte)work_i; if(a_ptr->type_mech==M_INP) { if(a_ptr->k_scale > 0) a_ptr->novalid = 0; a_ptr->type_mech=0; a_ptr->mod_cod=M_INP; N_MAN += 1; } sscanf(z_db(x_db+= 1,2), "%2hd", &work_i); a_ptr->param2 = (byte)work_i; sscanf(z_db(x_db+= 2,2), "%2hd", &work_i); a_ptr->nom_set = (byte)work_i; sscanf(z_db(x_db+= 2,2), "%2hd", &work_i); a_ptr->nomout_out = (byte)work_i; sscanf(z_db(x_db+= 2,2), "%2hd", &work_i); a_ptr->nomin_pos = (byte)work_i; sscanf(x_db+= 2, "%1hd", &work_i); a_ptr->sum_ysr = work_i; } } //-------------------------- Включениие контроллера ---------------------- void enable_D512(void) { word_s l_chan= 256,i; nearptr p_chan; controller * ptr_c; for(i = 0, ptr_c = c_ptr; i < c_num; i++, ptr_c++) { if(ptr_c->period==0 || ptr_c->typcontr!=D512 ) continue; p_chan=calloc(1,l_chan); tsk_outp(ptr_c->basaddr+7,3); // on port ptr_c->nomport=v24_define_port(ptr_c->basaddr,ptr_c->IRQ_line,ptr_c->vector); ptr_c->port=v24_install(ptr_c->nomport,0,p_chan,l_chan,NULL,256); if(!ptr_c->port){ ptr_c->period=0;ptr_c->kz=-1; eprintf(RED_,"Не могу инициализ. COM%d",ptr_c->nomport);continue;} v24_change_baud(ptr_c->port,(long)ptr_c->baud); v24_change_parity(ptr_c->port, PAR_NONE); v24_change_wordlength(ptr_c->port, 8); v24_change_stopbits(ptr_c->port, 1); v24_receive(ptr_c->port,2L); } } //-------------------------- Выключениие контроллера ---------------------- void disable_D512(void) { word_s i; controller *ptr_c; for(i = 0, ptr_c = c_ptr; i < c_num; i++, ptr_c++) { if(ptr_c->typcontr==D512 && ptr_c->period) tsk_outp(ptr_c->basaddr+7,0); } } //-------------------------- Выдача сообщения о нарушении ------------------ word_s kz_mesage_D512(controller *pc,word_s kz,word_s chn,word_s kz_old) { char *ps; if(pc->nom_ord!=chn || kz_old!= kz) { switch(kz&0xff) { case 0xff : ps="Нет связи"; break; case 0x77 : ps="Ош. KS"; break; case 23 : ps="Ош. 23"; break; case 33 : ps="Ош. 33"; break; case 51 : ps="Ош. 51"; break; case 100 : ps="Ош.100"; break; default : ps="Ош. КОД"; break; } fgtext(RED_,280,337,"Кольцо %d Контроллер %d: %s",pc->nomcontr,kz>>8,ps); } return(pc->nom_ord); }