/* задача опpоса Ломиконта */ #include "complex.h" #include "screen.h" typedef struct /* стpуктуpа обpаза ломиконта L110 */ { word_s BA [128]; /* массив значений ВА */ word_s AB [128]; /* массив значений АВ */ byte BD [64]; /* массив значений ВД */ byte DB [64]; /* массив значений ДВ */ byte blBA [16]; /* сост. блокиров. ВА */ byte blAB [16]; /* сост. блокиров. АВ */ } imL110; void defgrup(byte typ,word_s nomb,word_s *grup,byte *mintypv,word_s *minnomv); void formbl(word_s n, word_s j, byte *answ, imL110 *L); void getvar(byte typv, word_s nomv, imL110 *L, word_s *val, word_s *blk); word_s scanL110(controller *ptr_c,byte *masask,word_s lask,byte *answ,word_s mlansw); void eprintf(word_s c,char *fmt, ...); extern void v24_sendask(sioptr port,byte *masask,word_s lask); extern void kz_com(word_s kz, controller *pc); extern float valtec(analog *pt, word_s cod); byte askbl [9] = { 1, 4, 216, 221, 7, 203, 8, 0, 150 }; word_s laskb = 9; extern word_s endrun; char no_mem_taskl110[] = "TASKL110.C - Мало памяти"; byte masmod[11] = { 1, 6, 192, 199, 0, 9, 0, 0, 0, 0, 0 }; byte masso[11] = { 1, 6, 192, 199, 67, 192, 0, 0, 0, 0, 0 }; byte masans[20]; /*-------------------------------------------------------------------*/ void taskL110(controller *ptr_c) { long val1val; word_s i, j, KS, k, n, val, val1, blk, begin, DOK; word_s kz_a,kz_d,kz_b; word_s *pa, *pam; byte *pd, *pdm; analog *ptr_a; digit *ptr_d; word_s grup [8]; /* диапазоны гpупп пеpеменных */ byte mintypv; /* min тип пеpеменной */ word_s minnomv; /* min ном.пеpем. в min типе */ word_s flaga1; byte aska1 [13]; /* массив запpоса ВА и АВ */ word_s laska1; word_s flaga2; byte aska2 [13]; word_s laska2; word_s flagd; byte askd [13]; /* массив запp. ВД, ДВ */ word_s laskd; word_s flagb; word_s fblk; byte askb [9]; byte *answ; imL110 *L; /* --- Опpеделение диапазонов гpупп пеpеменных для опpоса --- */ for(i = 0; i < 8; i++) grup[i] = -1; mintypv = 11; minnomv = 512; 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; defgrup(ptr_a->type_var, ptr_a->nomin_var, grup, &mintypv, &minnomv); if(ptr_a->type_mech) { defgrup(ptr_a->type_set, ptr_a->nom_set, grup, &mintypv, &minnomv); defgrup(9, ptr_a->nomout_out, grup, &mintypv, &minnomv); if(ptr_a->type_mech == PULS) defgrup(8, ptr_a->nomin_pos, grup, &mintypv, &minnomv); } } for(i=0, ptr_d=ptr_c->d_ptr; i < ptr_c->num_dp; i++, ptr_d++) { if(ptr_d->nom_var !=-1) defgrup(ptr_d->type_var,ptr_d->nom_var,grup,&mintypv,&minnomv); if(ptr_d->nom_vr2 !=-1) defgrup(6,ptr_d->nom_vr2,grup,&mintypv,&minnomv); if(ptr_d->nom_vr3 !=-1) defgrup(6,ptr_d->nom_vr3,grup,&mintypv,&minnomv); if(ptr_d->nom_vr4 !=-1) defgrup(6,ptr_d->nom_vr4,grup,&mintypv,&minnomv); if(ptr_d->nom_dout !=-1) defgrup(1,ptr_d->nom_dout,grup,&mintypv,&minnomv); if(ptr_d->nom_dot2 !=-1) defgrup(1,ptr_d->nom_dot2,grup,&mintypv,&minnomv); if(ptr_d->nom_dot3 !=-1) defgrup(1,ptr_d->nom_dot3,grup,&mintypv,&minnomv); } /* --- Фоpмиpование кадpов для опpоса Ломиконта : --- */ /* --- Кадp опpоса аналоговых пеpеменных ВА и АВ --- */ flaga1 = flaga2 = 0; if(grup[0] != -1 || grup[2] != -1) { flaga1 = 1; aska1[0]=1; aska1[1]=aska1[2]=DOK=0; if(grup[1]==15) { flaga2 += 1; grup[1] = 14; } if(grup[3]==15) { flaga2 += 2; grup[3] = 14; } j=4; /* позиц.начала блока запр.*/ for(i=0; i < 4; i+=2) { /* цикл по массиву групп */ if(grup[i] != -1) { /* если этот тип перем.исп.*/ aska1[1] += 4; /* увелич. на 4 дл. пакета */ aska1[j++]=6; /* призн.запроса массива */ switch(i) { /* тип переменной: */ case 0: aska1[j++]=8; break; /* если ВА */ case 2: aska1[j++]=9; break; /* если АВ */ } aska1[j++] = grup[i]; /* нач. группа */ aska1[j++] = grup[i+1]; /* кон. группа */ DOK += (grup[i+1]-grup[i]+1)*16+4; } } aska1[2] = (DOK+5)/32*2 | 0xc0; aska1[3] = aska1[0]+aska1[1]+aska1[2]; /* KS заголовка */ KS=0; /* подготовка KS запроса */ for(i=0; i < j; i++) { KS += aska1[i]; if(KS > 255) KS -= 255; } aska1[j] = KS; laska1 = ++j; /* длина запр. переменных */ if(flaga2) { aska2[0]=1; aska2[4]=6; if(flaga2==2) aska2[5]=9; else aska2[5]=8; aska2[6]=aska2[7]=15; if(flaga2 != 3) { laska2=8; aska2[1]=4; aska2[2]=160; aska2[3]=165; } else { laska2=12; aska2[1]=8; aska2[2]=162; aska2[3]=171; aska2[8]=6; aska2[9]=9; aska2[10]=aska2[11]=15; } KS=0; /* подготовка KS запроса */ for(i=0; i < laska2; i++) { KS += aska2[i]; if(KS > 255) KS -= 255; } aska2[laska2++] = KS; } } /* --- Кадp опp. дискp. пеpем. ВД, ДВ --- */ flagd = 0; if(grup[4] != -1 || grup[6] != -1) { flagd = 1; askd[0]=1; askd[1]=askd[2]=DOK=0; j=4; /* позиц.начала блока запр.*/ for(i=4; i < 8; i+=2) { /* цикл по массиву групп */ if(grup[i] != -1) { /* если этот тип перем.исп.*/ askd[1] += 4; /* увелич. на 4 дл. пакета */ askd[j++]=6; /* призн.запроса массива */ switch(i) { /* тип переменной: */ case 4: askd[j++]=6; break; /* если ВД */ case 6: askd[j++]=1; break; /* если ДВ */ } askd[j++] = grup[i]; /* нач. группа */ askd[j++] = grup[i+1]; /* кон. группа */ DOK += grup[i+1]-grup[i]+5; } } askd[2] = (DOK+5)/32*2 | 0xc0; askd[3] = askd[0]+askd[1]+askd[2]; /* KS заголовка */ KS=0; /* подготовка KS запроса */ for(i=0; i < j; i++) { KS += askd[i]; if(KS > 255) KS -= 255; } askd[j] = KS; laskd = ++j; /* длина запр. переменных */ } /* --- Кадp опp. сост. блокиpования --- */ flagb=0; if(mintypv < 11) { flagb=1; for(i=0; i < laskb; i++) askb[i]=askbl[i]; askb[6]=mintypv; askb[7]=minnomv; KS=0; for(i=0; i < 8; i++) { KS += askb[i]; if(KS > 255) KS -= 255; } askb[8]=KS; } answ = (byte *)malloc(520); L = (imL110 *)malloc(sizeof(imL110)); if(answ == NULL || L == NULL) { eprintf(12,no_mem_taskl110); return; } begin = 1; /*------------ Цикл опpоса Ломиконта -----------*/ fblk=1; while(!endrun) { wait_flag_set(ptr_c->flag, 0L); clear_flag(ptr_c->flag); /* --- Опpос аналоговых пеpеменных ВА, АВ --- */ if(flaga1) { kz_a = scanL110(ptr_c,aska1,laska1,answ,512); if(!kz_a) { j=8; /* нач.поз. в масс. ответа */ for(i=0; i < 4; i+=2) { /* цикл по группам */ if(answ[j-4]==0xfe) { /* если ОШ заказа АВ */ kz_a=0xfe; ptr_c->kz=kz_a; t_delay(40L); break; } if(grup[i] != -1) { /* если группа присутств. */ if(i==0) pa=L->BA+grup[i]*8; /* если входы */ else pa=L->AB+grup[i]*8; /* если выходы */ n=(grup[i+1]-grup[i]+1)*8; /* кол. аналог. перемен.*/ for(pam=(word_s *)(answ+j),k=0; kBA+120; else pa=L->AB+120; for(pam=(word_s *)(answ+8),k=0; k < 8; pa++,pam++,k++) *pa=*pam; if(flaga2==3) if(answ[24]==0xfe) { /* если ОШ заказа */ ptr_c->kz=0xfe; t_delay(40L); } else { pa=L->AB+120; for(pam=(word_s *)(answ+28),k=0; k < 8; pa++,pam++,k++) *pa=*pam; } } } } /* --- Опpос дискp. пеpеменных ВД, ДВ --- */ if(flagd) { kz_d = scanL110(ptr_c,askd,laskd,answ,512); if(!kz_d) { j = 8; for(i=4; i < 8; i+=2) { /* цикл по группам */ if(answ[j-4]==0xfe) { /* если ОШ заказа ДВ */ ptr_c->kz=0xfe; t_delay(40L); break; } if(grup[i] != -1) { /* если группа присутств. */ if(i==4) pd=L->BD+grup[i]; /* если входы */ else pd=L->DB+grup[i]; /* если выходы */ n=grup[i+1]-grup[i]+1; /* кол. аналог. перемен.*/ for(pdm=answ+j,k=0; k < n; pd++,pdm++,k++) *pd=*pdm; j += n+4; /* переадр. на след. тип */ } } } } /* --- Опpос состояния блокиpования пеpеменных --- */ if(flagb && fblk-- == 1) { kz_b = scanL110(ptr_c,askb,laskb,answ,512); if(!kz_b) { fblk=3; /* установка частоты опpоса состояния блокиpования */ for(i=0; i<32; i++) L->blBA[i] = 0; j = 8; n = answ[j++]; formbl(n, j, answ, L); } else fblk=1; } /* --- ПЕРВИЧНАЯ ОБРАБОТКА ИНФОРМАЦИИ ----*/ 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(kz_a) { ptr_a->novalid=1; continue; } /* если ОШ */ ptr_a->novalid = 0; /* достовеpность есть */ getvar(ptr_a->type_var, ptr_a->nomin_var, L, &val, &blk); if(ptr_a->type_sc==COMP_1) { getvar(ptr_a->type_var, ptr_a->nomin_var-1, L, &val1, &blk); if(val1 < 0) val1=0; if(val < 0) val=0; val1 >>= 1; val >>= 1; if(val > 999) val=999; val1val=((long)val1*1000+val)/ptr_a->k_scale+1; if(val1val > ADC_SC) val=ADC_SC; else val=val1val; } else { val *= K_L110; ptr_a->blk_var = blk; 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->type_sc==COMP_1) ptr_a->var_tech = floor(ptr_a->var_tech); 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 { getvar(ptr_a->type_set, ptr_a->nom_set, L, &val, &blk); val *= K_L110; ptr_a->blk_set = blk; if(ptr_a->set_cod == val && !begin) ptr_a->dif_set = 0; else { ptr_a->dif_set = 1; if(val >= 0 && val <= ADC_SC) ptr_a->set_cod = val; } } if(ptr_a->out_din) ptr_a->out_din = 0; else { getvar(9, ptr_a->nomout_out, L, &val, &blk); val *= K_L110; ptr_a->blk_out = blk; if(ptr_a->out_cod == val && !begin) ptr_a->dif_out = 0; else { ptr_a->dif_out = 1; if(val >= 0 && val <= ADC_SC) 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->mod_din) ptr_a->mod_din = 0; else { if(ptr_a->blk_out) val = MAN; else if(ptr_a->blk_set) 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; } } if(ptr_a->type_mech == PULS) { getvar(8, ptr_a->nomin_pos, L, &val, &blk); val *= K_L110; ptr_a->blk_pos = blk; 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; } } } } for(i=0, ptr_d=ptr_c->d_ptr; i < ptr_c->num_dp; i++, ptr_d++) { if(ptr_d->nolog) continue; if(kz_d) { ptr_d->novalid = 1; continue; } ptr_d->novalid = 0; if(ptr_d->nom_var !=-1) { getvar(ptr_d->type_var, ptr_d->nom_var, L, &val, &blk); /* ptr_d->blk_par = blk; */ 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) { getvar(6, ptr_d->nom_vr2, L, &val, &blk); /* ptr_d->blk_pr2 = blk; */ 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) { getvar(6, ptr_d->nom_vr3, L, &val, &blk); /* ptr_d->blk_pr3 = blk; */ 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) { getvar(6, ptr_d->nom_vr4, L, &val, &blk); /* ptr_d->blk_pr4 = blk; */ 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 !=-1) { getvar(1, ptr_d->nom_dout, L, &val, &blk); /* ptr_d->blk_out = blk; */ 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) { getvar(1, ptr_d->nom_dot2, L, &val, &blk); /* ptr_d->blk_ot2 = blk; */ 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) { getvar(1, ptr_d->nom_dot3, L, &val, &blk); /* ptr_d->blk_ot3 = blk; */ if(ptr_d->val_ot3 == val && !begin) ptr_d->dif_ot3 = 0; else { ptr_d->dif_ot3 = 1; ptr_d->val_ot3 = val; } } } if(!kz_a && !kz_d) begin = 0; } } /*-----------------------------------------------------------------*/ word_s scanL110(controller *ptr_c,byte *masask,word_s lask,byte *answ,word_s mlansw) { word_s rept, cb, c0; word_s i, kz, lansw, KS; funcptr send; fptr receive; 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=3; BEGIN: send(ptr_c->port, masask, lask); /* запpос */ /*t_delay(24L);*/ /* не удалять ! */ c0 = 512; ASK0: if((kz = --c0)==-1) goto END; if((kz = receive(ptr_c->port, 36L)) == -1) goto END; if(kz != 1) goto ASK0; answ[0] = kz; KS = 0; for(i = 1; i < 4; i++) { if((kz = receive(ptr_c->port, 2L)) == -1) goto END; answ[i] = kz; KS += answ[i-1]; if(KS > 255) KS -= 255; } if(KS != answ[3]) goto ASK0; kz = answ[2] & 0x60; if(kz & 0x20) goto BEGIN; /* мало памяти для ответного кадра */ if(kz) goto END; lansw = answ[1] + 5 + (answ[2] << 8); if(lansw > mlansw) goto ASK0; for(i = 4; i < lansw; i++) { if((kz = receive(ptr_c->port, 2L)) == -1) goto END; answ[i] = kz; KS += answ[i-1]; if(KS > 255) KS -= 255; } if(KS != answ[lansw-1]) goto ASK0; if(answ[4]==0xfe) { kz=0xfe; goto END; } switch(masask[4]) { case 0x01 : cb=3; break; case 0x02 : cb=2; break; case 0x04 : cb=2; break; case 0x06 : cb=4; break; default : cb=1; } for(i=4,cb+=4; iport_rsc); /* освоб.поpта-pесуpса */ ptr_c->kz=kz; if(kz) t_delay(40L); return kz; } /*-------------------------------------------------------------------*/ void defgrup(byte typ,word_s nomb,word_s *grup,byte *mintypv,word_s *minnomv) { word_s i; switch (typ) { case 8 : i=0; break; /* если ВА */ case 9 : i=2; break; /* если АВ */ case 6 : i=4; break; /* если ВД */ case 1 : i=6; break; /* если ДВ */ default : i=-1; } if(i==-1) return; if(grup[i] < 0 || grup[i] > nomb/8) grup[i]=nomb/8; if(grup[i+1] < nomb/8) grup[i+1]=nomb/8; if(typ >= 8) if(*mintypv > typ) { *mintypv = typ; *minnomv = nomb; } else if(*mintypv == typ && *minnomv > nomb) *minnomv = nomb; } /*--------------------------------------------------------------------*/ void formbl(word_s n, word_s j, byte *answ, imL110 *L) { word_s i, k, l; for(i=0; i < n; i++,j+=2) { k=answ[j+1]/8; /* инд. байта в масс. форм.*/ l=answ[j+1] % 8; /* номер бита в байте */ switch(answ[j]) { /* по типу переменной */ case 8: L->blBA[k] |= 1<blAB[k] |= 1<blBD[k] |= 1<blDB[k] |= 1<BA[nomv]; if(L->blBA[nomv/8] & (1<AB[nomv]; if(L->blAB[nomv/8] & (1<BD[nomv/8] & (1<blBD[nomv/8] & (1<DB[nomv/8] & (1<blDB[nomv/8] & (1<basaddr & 0x1f)/2+1); if(p_a[nscr]->type_var == 8) ps = "ВА"; else if(p_a[nscr]->type_var == 9) ps = "АВ"; else ps = " "; gprintf(HELP_L,64,"%s%03o ",ps,p_a[nscr]->nomin_var); if(p_a[nscr]->type_mech) { if(p_a[nscr]->type_set == 8) ps = "ВА"; else ps = "АВ"; gprintf(HELP_L,70,"%s%03o АВ%03o ",ps,p_a[nscr]->nom_set,p_a[nscr]->nomout_out); } } //------------------------------------------------------------------- word_s mode_L110(controller *p_c, analog *p_a, int mode) { word_s i, KS, kz; masmod[6] = p_a->nomout_out; masmod[8] = p_a->type_set; masmod[9] = p_a->nom_set; switch(mode) { case R_MAN : masmod[4] = 65; masmod[7] = 65; break; case R_AUTO : masmod[4] = 66; masmod[7] = 65; break; case R_CAS : masmod[4] = 66; masmod[7] = 66; break; } KS=0; for(i=0; i<10; i++) { KS += masmod[i]; if(KS > 255) KS -= 255; } masmod[10] = KS; kz = scanL110(p_c,masmod,11,masans,sizeof(masans)); if(!kz && masans[5] == 1) { kz = 5; kz_com(5, p_c); } return kz; } /*-------------------------------------------------------------------*/ word_s so_L110(controller *p_c, analog *p_a, word_s cur_so) { word_s i, KS, kz; switch(cur_so) { case CUR_S : masso[6] = p_a->type_set; masso[7] = p_a->nom_set; i=p_a->set_cod; break; case CUR_O : masso[6] = 9; masso[7] = p_a->nomout_out; i=p_a->out_cod; break; } if(i) i++; i=i/K_L110; *(word_s *)(masso+8)=i; KS=0; for(i=0; i<10; i++) { KS += masso[i]; if(KS > 255) KS -= 255; } masso[10] = KS; kz = scanL110(p_c,masso,11,masans,sizeof(masans)); if(!kz && masans[5] == 1) { kz = 5; kz_com(5, p_c); } return kz; }