/* задача опpоса Ремиконта 130 */ #include "complex.h" #include "screen.h" typedef struct /* запись опроса дискр. парам. из ШИФ */ { byte nom_r; byte nom_a; word int vals; } imD130; word_s scanR130(controller *ptr_c,byte *masask,word_s lask,byte *answ,word_s mlansw); byte masinv[2]={ 0x00, 0x4e }; char no_mem_taskr130[] = "TASKR130.C - Мало памяти"; /*-------------------------------------------------------------------*/ void taskR130(controller *ptr_c) { word_s i,j,k,num_ds,fno; word_s kz,val,val1,val2,val3,val4,val5,val6,begin,INV; analog *ptr_a; digit *ptr_d; byte askreg[5]={ 1, 0, 2, 0x4e, 0 }; byte askpar[6]={ 1, 0, 4, 0x4e, 0, 0 }; byte *answ; word_s *codinv; imD130 *p_ds; if((answ = (byte *)calloc(1,160))==NULL) { eprintf(RED_,no_mem_taskr130); return; } num_ds=0; for(i=0; i < ptr_c->num_dp; i++) if(!(ptr_c->d_ptr+i)->type_var) { /* если из ШИФ ремиконта */ fno=1; for(j=0; jd_ptr+j)->type_var) if((ptr_c->d_ptr+j)->nomR130==(ptr_c->d_ptr+i)->nomR130 && (ptr_c->d_ptr+j)->abR130==(ptr_c->d_ptr+i)->abR130) { fno=0; break; } if(fno) num_ds++; } if((answ = (byte *)calloc(142+num_ds,sizeof(imD130)))==NULL) { eprintf(RED_,no_mem_taskr130); return; } codinv=(word_s *)(answ+72); p_ds=(imD130 *)(answ+142); k=0; for(i=0; i < ptr_c->num_dp; i++) if(!(ptr_c->d_ptr+i)->type_var) { /* если из ШИФ ремиконта */ fno=1; for(j=0; jd_ptr+j)->type_var) if((ptr_c->d_ptr+j)->nomR130==(ptr_c->d_ptr+i)->nomR130 && (ptr_c->d_ptr+j)->abR130==(ptr_c->d_ptr+i)->abR130) { fno=0; (ptr_c->d_ptr+i)->nom_a2=(ptr_c->d_ptr+j)->nom_a2; break; } if(fno) { (p_ds+k)->nom_r=(ptr_c->d_ptr+i)->nomR130; (p_ds+k)->nom_a=(ptr_c->d_ptr+i)->abR130; (ptr_c->d_ptr+i)->nom_a2=k; k++; } } INV=0; for(i=0, ptr_a=ptr_c->a_ptr; i < ptr_c->num_ap; i++, ptr_a++) if(ptr_a->nomR130 && /* если включен в опрос */ ptr_a->nomin_var && /* задан сигнал в ИНВ шлюза */ (!ptr_a->type_mech && !ptr_a->nom_ab || /* для нерегулируемого или */ ptr_a->type_mech==PULS && !ptr_a->nomin_pos)) /* для ПИМ в РИМ */ INV++; for(i=0, ptr_d=ptr_c->d_ptr; i < ptr_c->num_dp; i++, ptr_d++) if(ptr_d->nomR130 && /* если включен в опрос */ ptr_d->type_var && /* задан выход в ИНВ шлюза */ (ptr_d->nom_var !=-1 || ptr_d->nom_vr2 !=-1 || /* и хотя бы один */ ptr_d->nom_vr3 !=-1 || ptr_d->nom_vr4 !=-1)) /* входной сигн.в нем */ INV++; begin=1; while(!endrun) { wait_flag_set(ptr_c->flag, 0L); clear_flag(ptr_c->flag); if(INV) { for(i=0; i<30; i++) codinv[i]=0; kz = scanR130(ptr_c,masinv,2,answ,66); /* ИНВ */ if(!kz && !answ[2]) for(i=0; i<30; i++) codinv[i]=*(word_s *)(answ+3+i*2); } for(i=0, ptr_a=ptr_c->a_ptr; i < ptr_c->num_ap; i++, ptr_a++) { if(ptr_a->mod_cod==M_INP) continue; /* если ручной ввод */ if(ptr_a->nolog) continue; /* если логич. запpет обpаб. */ if(!ptr_a->type_mech) { /* если не контур, т.е. простой */ if(!ptr_a->nomin_var) { ptr_a->novalid=1; continue; } /* нет вых */ if(!ptr_a->nom_ab) { /* параметр в ИНВ */ val1=codinv[ptr_a->nomin_var-1]; if(!(val1&1)) { ptr_a->novalid=1; continue; } /* ОШ при опр ИНВ */ else val1=(val1&0xfffe)*K_R130; } else { /* иначе если параметр в ремик */ askpar[1]=ptr_a->nomR130; askpar[4]=ptr_a->nom_ab; askpar[5]=ptr_a->nomin_var; kz = scanR130(ptr_c,askpar,6,answ,32); if(kz || answ[2] != 1 || answ[3] != ptr_a->nomR130 || answ[4] != 4 || answ[5] != 0x52 || answ[6] != ptr_a->nom_ab || answ[7] != ptr_a->nomin_var) { ptr_a->novalid=1; continue; } val1=((*(word_s *)(answ+8))&0xfffe)*K_R130; } } else { /* если контур */ if(!ptr_a->contur130) { /* не задан контур */ ptr_a->novalid=1; continue; } askreg[1]=ptr_a->nomR130; askreg[4]=ptr_a->contur130; kz = scanR130(ptr_c,askreg,5,answ,32); if(kz || answ[2] != 1 || answ[3] != ptr_a->nomR130 || answ[4] != 2 || answ[5] != 0x52 || answ[6] != ptr_a->contur130) { ptr_a->novalid=1; continue; } val1=((*(word_s *)(answ+11))&0xfffe)*K_R130; /* переменная */ val2=((*(word_s *)(answ+9))&0xfffe)*K_R130; /* задание */ val3=((*(word_s *)(answ+15))&0xfffe)*K_R130; /* выход */ val4=((*(word_s *)(answ+13))&0xfffe)*K_R130; /* расогласование */ val5=(*(word_s *)(answ+17)); /* режим */ if(val5&0x10) val5=MAN; else val5=AUTO; if(ptr_a->nomin_var) /* если задан ПИМ для РИМ */ if(!ptr_a->nomin_pos) /* если ПИМ в ИНВ */ val6=(codinv[ptr_a->nomin_var-1]&0xfffe) * K_R130; else { /* иначе если ПИМ в ремик */ askpar[1]=ptr_a->nomR130; askpar[4]=ptr_a->nomin_pos; askpar[5]=ptr_a->nomin_var; kz = scanR130(ptr_c,askpar,6,answ,32); if(kz || answ[2] != 1 || answ[3] != ptr_a->nomR130 || answ[4] != 4 || answ[5] != 0x52 || answ[6] != ptr_a->nomin_pos || answ[7] != ptr_a->nomin_var) val6=ptr_a->pos_cod; else val6=((*(word_s *)(answ+8))&0xfffe)*K_R130; } } if(val1 < -(ADC_SC>>3)) ptr_a->novalid=1; if(val1 < 0) val1=0; else if(val1 > ADC_SC) val1=ADC_SC; if(ptr_a->var_cod == val1 && !begin) ptr_a->dif_var = 0; else { ptr_a->dif_var = 1; ptr_a->var_cod = val1; ptr_a->var_tech = valtec(ptr_a,ptr_a->var_cod); if(ptr_a->min_reg && val1 < ptr_a->min_reg) ptr_a->bound_reg = 1; else if(ptr_a->max_reg && val1 > ptr_a->max_reg) ptr_a->bound_reg = 2; else ptr_a->bound_reg = 0; if(ptr_a->min_al && val1 < ptr_a->min_al) ptr_a->bound_al = 1; else if(ptr_a->max_al && val1 > ptr_a->max_al) ptr_a->bound_al = 2; else ptr_a->bound_al = 0; } ptr_a->novalid=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->set_cod == val2 && !begin) ptr_a->dif_set = 0; else { ptr_a->dif_set = 1; if(val2 >= 0 && val2 <= ADC_SC) ptr_a->set_cod = val2; } } if(ptr_a->out_din) ptr_a->out_din = 0; else { if(ptr_a->out_cod == val3 && !begin) ptr_a->dif_out = 0; else { ptr_a->dif_out = 1; if(val3 >= 0 && val3 <= ADC_SC) ptr_a->out_cod = val3; } } if(ptr_a->dif_cod == val4 && !begin) ptr_a->dif_dif = 0; else { ptr_a->dif_dif = 1; ptr_a->dif_cod = val4; } if(ptr_a->mod_din) ptr_a->mod_din = 0; else { if(ptr_a->mod_cod == val5 && !begin) ptr_a->dif_mod = 0; else { ptr_a->dif_mod = 1; ptr_a->mod_cod = val5; } } if(ptr_a->nomin_var) { /* PULS с ПИМ */ if(ptr_a->pos_cod == val6 && !begin) ptr_a->dif_pos = 0; else { ptr_a->dif_pos = 1; if(val6 >= 0 && val6 <= ADC_SC) ptr_a->pos_cod = val6; } } } } for(k=0; kvals=0xffff; for(k=0; knom_r; askpar[4]=(p_ds+k)->nom_a; askpar[5]=1; kz = scanR130(ptr_c,askpar,6,answ,32); if(kz || answ[2] != 1 || answ[3] != (p_ds+k)->nom_r || answ[4] != 4 || answ[5] !=0x52 || answ[6] != (p_ds+k)->nom_a || answ[7] !=1) continue; (p_ds+k)->vals = *(word_s *)(answ+8) >> 1; } for(i=0, ptr_d=ptr_c->d_ptr; i < ptr_c->num_dp; i++, ptr_d++) { if(ptr_d->nolog) continue; if(!ptr_d->type_var && !ptr_d->abR130) { /* если ни ИНВ, ни алгоблок */ ptr_d->novalid=1; continue; } if(ptr_d->type_var) { /* если из ИНВ шлюза */ val1=codinv[ptr_d->type_var-1]; if(!(val1&1)) { ptr_d->novalid=1; continue; } /* ОШ при опр ИНВ */ val1 >>= 1; } else { /* иначе если из ремиконта */ val1=(p_ds+ptr_d->nom_a2)->vals; if(val1==0xffff) { ptr_d->novalid=1; continue; } } ptr_d->novalid = 0; if(ptr_d->nom_var !=-1) { /* если вход задан */ val = (val1 >> ptr_d->nom_var) & 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 !=-1) { /* если вход задан */ val = (val1 >> ptr_d->nom_vr2) & 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 !=-1) { /* если вход задан */ val = (val1 >> ptr_d->nom_vr3) & 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 !=-1) { /* если вход задан */ val = (val1 >> ptr_d->nom_vr4) & 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->abR130) { /* если вдруг заданы выходные сигналы */ if(ptr_d->nom_dout !=-1) { /* если выход задан */ val = (val1 >> ptr_d->nom_dout) & 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 !=-1) { /* если выход задан */ val = (val1 >> ptr_d->nom_dot2) & 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 !=-1) { /* если выход задан */ val = (val1 >> ptr_d->nom_dot3) & 1; if(ptr_d->val_ot3 == val && !begin) ptr_d->dif_ot3 = 0; else { ptr_d->dif_ot3 = 1; ptr_d->val_ot3 = val; } } } } begin = 0; } } /*-----------------------------------------------------------------*/ word_s scanR130(controller *ptr_c,byte *masask,word_s lask,byte *answ,word_s mlansw) { word_s rept, c0, c1; word_s i, k, kz, staff, KS; funcptr send; fptr receive; byte askmas[128] = { 16, 2 }; for(KS=37,k=2,i=0; i 255) KS -= 255; askmas[k]=masask[i]; if(askmas[k++]==16) askmas[k++]=16; } askmas[k++]=16; askmas[k++]=3; askmas[k++]=KS; if(ptr_c->nomport < 0x80) { send = ad8_send; receive = ad8_receive; } else { send = v24_sendask; receive = v24_receive; } while(request_resource(ptr_c->port_rsc,0L)); /* захват поpта-pесурса */ rept=2; BEGIN: ptr_c->port->flags=0; send(ptr_c->port, askmas, k); /* запpос */ t_delay(5L); /* не удалять ! */ c0 = 256; ASK0: kz = --c0; if(kz ==-1) goto END; kz = receive(ptr_c->port, 36L); if(kz == -1) goto END; if(kz != 0x10) goto ASK0; answ[0] = 0x10; c1 = 256; ASK1: kz = --c1; if(kz ==-1) goto END; kz = receive(ptr_c->port, 2L); if(kz == -1) goto END; if(kz == 0x10) goto ASK1; if(kz != 0x02) goto ASK0; answ[1] = 0x02; KS = 0x12; staff = 1; i = 2; ASKI: kz = receive(ptr_c->port, 2L); if(kz == -1) goto END; answ[i] = kz; if(answ[i-1]==0x10 && answ[i]==0x10 && staff) { staff=0; goto ASKI; } staff = 1; KS += kz; if(KS > 255) KS -= 255; if(++i == mlansw) { kz=-1; goto END; } if(answ[i-2] != 0x10 || answ[i-1] != 0x03) goto ASKI; kz = receive(ptr_c->port, 2L); if(kz == -1) goto END; answ[i++] = kz; if(KS != kz) goto ASKI; if(answ[5]==0x50) { /* если подтверждение */ if(answ[6]==0) kz=0; else { if(answ[7]==0x10) kz=(((answ[6]<<3)|(masask[1]&0x07))<<7)|(masask[4]&0x7f); else kz=((answ[8]<<3)|(answ[7] & 0x07))<<7; } if(kz || masask[3]==0x49) goto FIN; /* если kz или команда */ kz=-1; goto END; /* на запрос получ. подвержд. на команду */ } if(masask[0] != answ[2]) { kz=-1; goto END; } if(masask[0] != 1) { kz=0; goto END; } if(masask[1] != answ[3] || masask[2] != answ[4] || answ[5] != 0x52) { kz=-1; goto END; } if(masask[2]==5) { kz=0; goto END; } if(masask[4] != answ[6]) { kz=-1; goto END; } if((masask[2]==1 || masask[2]==4) && masask[5] != answ[7]) { kz=-1; goto END; } kz=0; END: if(ptr_c->port->flags) kz=-1; if(kz && --rept) goto BEGIN; FIN: release_resource(ptr_c->port_rsc); /* освоб.поpта-pесуpса */ ptr_c->kz=kz; kz_com(ptr_c->kz,ptr_c); return kz; } //------------------------- Вывод сообщений об ошибках опроса ------------------ word_s kz_mesage_R130(controller *pc,word_s kz,word_s chn,word_s kz_old) { word_s chn1,ps; if(pc->nomport < 0x80) chn1 = (pc->basaddr&0x0f)/2; // МПО8 else chn1=pc->nom_ord; // COMы if(chn1!=chn || kz_old!= kz) { switch((word)kz>>10) { case 0x3f : ps = "НЕТ СВЯЗИ "; break; case 0x1f : ps = "РЕМИКОНТ НЕ В СЕТИ "; break; case 0x20 : ps = "ПОТЕРЯ СООБЩЕНИЯ "; break; case 0x22 : case 0x23 : case 0x2a : ps = "ОШ.типа,вида сообщ."; break; case 0x2b : ps = "ШЛЮЗ НЕ В СЕТИ "; break; case 0x2c : ps = "ОШ.в пакете из сети"; break; case 0x02 : ps = "нет алгор.ЗДН в ОКО"; break; case 0x03 : ps = "в ОКО нет внешн.здн"; break; case 0x04 : ps = "в ЗДН нет прогр.здн"; break; case 0x05 : ps = "нет алгор.РУЧ в ОКО"; break; case 0x06 : ps = "нет алгор.ЗДЛ в ОКО"; break; case 0x07 : ps = "ЗАПРЕТ ручн.задания"; break; case 0x0c : ps = "в ОКО нет дист.реж."; break; case 0x0d : ps = "в РУЧ блок.авт.реж."; break; case 0x0e : ps = "РУЧ откл; связан вх"; break; case 0x10 : ps = "команда не разреш. "; break; case 0x12 : ps = "предыд.ком;нет прог"; break; case 0x13 : ps = "НЕ коэффициент "; break; case 0x15 : ps = "ОШ. вход алгоблока "; break; case 0x16 : ps = "ОШ. выход алгоблока"; break; case 0x17 : case 0x24 : case 0x25 : ps = "ОШ. номер алгоблока"; break; case 0x18 : ps = "НЕ КОМАНДНЫЙ РЕЖИМ "; break; default : ps = "ОШИБКА ОБМЕНА "; } if(kz==-1) fgtext(RED_,280,337,"Кольцо %d: %s",chn1+1,ps); else fgtext(RED_,280,337,"Кольцо %d: %s %1d%3d",chn1+1,ps,(kz>>7)&0x07,kz&0x7f); } return(chn1); }