// задача опpоса UMC800 #include "complex.h" #include "screen.h" #define MAX_NDAT 120 // max колич. запраш.данных dword takt_cpu(void); #pragma aux takt_cpu = "db 0Fh,31h "\ modify [EDX] \ value [EAX] ; 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 scanU800(controller *ptr_c,byte *mask,word_s lask,byte *mans,word_s lans); word form_ks(unsigned char *st,word_s len); extern float float_intel(byte *bufr); void request_U800(controller *ptr_c); void release_U800(controller *ptr_c); char no_mem_tasku800[] = "TASKU800.C - Мало памяти"; //------------------------------------------------------------------- void taskU800(controller *ptr_c) { extern dword time_virt[]; word_s i, k; word_s l_ask, l_ans; word_s kz, begin, val; dword takt_old; float valf; byte *ask, *ans; analog *ptr_a; digit *ptr_d; l_ask = 14+MAX_NDAT*2; // max длина буфера запроса l_ans = 12+MAX_NDAT*4; // max длина буфера ответа ask = (byte *)calloc(1,l_ask); // буффер запроса blk ans = (byte *)calloc(1,l_ans); // буффер ответов if(ask==NULL || ans==NULL) { eprintf(RED_,no_mem_tasku800); return; } // Формирование запроса входов Блоков и Переменных l_ask=0; ask[0]=0x10; ask[1]=0x02; ask[2]=0x01; ask[3]=0xFF; ask[4]=0xB5; ask[5]=0x00; ask[6]=0x03; ask[7]=0; // здесь будет колич. запрашиваемых данных ask[8]=0x00; ask[9]=0x02; k=10; for(i=0, ptr_a=ptr_c->a_ptr; i < ptr_c->num_ap; i++, ptr_a++) { if(ptr_a->mod_cod==M_INP || !ptr_a->nomin_var) continue; // не задан вход ask[k++]=ptr_a->nomin_var; // номер (алго)блока ask[k++]=0x01; // вход l_ask++; // счетчик колич. данных } for(i=0, ptr_d=ptr_c->d_ptr; i < ptr_c->num_dp; i++, ptr_d++) { if(ptr_d->nom_var > 0) { ask[k++]=ptr_d->nom_var; // номер (алго)блока ask[k++]=0x01; // вход l_ask++; // счетчик колич. данных } if(ptr_d->nom_vr2 > 0) { ask[k++]=ptr_d->nom_vr2; // номер (алго)блока ask[k++]=0x01; // вход l_ask++; // счетчик колич. данных } if(ptr_d->nom_vr3 > 0) { ask[k++]=ptr_d->nom_vr3; // номер (алго)блока ask[k++]=0x01; // вход l_ask++; // счетчик колич. данных } if(ptr_d->nom_vr4 > 0) { ask[k++]=ptr_d->nom_vr4; // номер (алго)блока ask[k++]=0x01; // вход l_ask++; // счетчик колич. данных } if(ptr_d->nom_dout > 0) { ask[k++]=0xFB; // признак того, что это переменная ask[k++]=ptr_d->nom_dout-1; // номер переменной-1 l_ask++; // счетчик колич. данных } if(ptr_d->nom_dot2 > 0) { ask[k++]=0xFB; // признак того, что это переменная ask[k++]=ptr_d->nom_dot2-1; // номер переменной-1 l_ask++; // счетчик колич. данных } if(ptr_d->nom_dot3 > 0) { ask[k++]=0xFB; // признак того, что это переменная ask[k++]=ptr_d->nom_dot3-1; // номер переменной-1 l_ask++; // счетчик колич. данных } } ask[k++]=0; ask[k++]=0; // здесь будет KS ask[k++]=0x10; ask[k++]=0x03; ask[7]=l_ask; // количество данных l_ask=k; // длина запроса в байтах *(word_s *)(ask+l_ask-4)=form_ks(ask+2,l_ask-6); l_ans=ask[7]*4+12; begin = 1; while(!endrun) { /****************************************** wait_flag_set(ptr_c->flag, 0L); clear_flag(ptr_c->flag); *******************************************/ t_delay(ptr_c->period); //----------------- if(yes_P5)takt_old=takt_cpu(); //----------------- request_U800(ptr_c); kz = scanU800(ptr_c,ask,l_ask,ans,l_ans); release_U800(ptr_c); // Разборка ответа и ПЕРВИЧНАЯ ОБРАБОТКА ИНФОРМАЦИИ k=8; for(i=0, ptr_a=ptr_c->a_ptr; i < ptr_c->num_ap; i++, ptr_a++) { if(ptr_a->mod_cod==M_INP || !ptr_a->nomin_var) continue; // не задан вх if(kz) { ptr_a->novalid=1; continue; } ptr_a->novalid=0; if(ptr_a->nolog) { k+=4; continue; } // если логич. запpет обpаб. valf=float_intel(ans+k); k+=4; if(valf > ptr_a->max_sc) { valf=ptr_a->max_sc; ptr_a->novalid=1; } else if(valf < ptr_a->min_sc) { valf=ptr_a->min_sc; ptr_a->novalid=1; } val=(float)ADC_SC*(valf-ptr_a->min_sc)/(ptr_a->max_sc-ptr_a->min_sc); /******** if(valf > 100.0) { valf=100.0; ptr_a->novalid=1; } else if(valf < 0.0) { valf=0.0; ptr_a->novalid=1; } val=valf*ADC_SC/100.0; *******/ 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; } } for(i=0, ptr_d=ptr_c->d_ptr; i < ptr_c->num_dp; i++, ptr_d++) { if(kz) { ptr_d->novalid=1; continue; } if(ptr_d->nolog) { k+=4; continue; } // если логич. запpет обpаб. if(ptr_d->nom_var > 0) { valf=float_intel(ans+k); k+=4; if(valf < 0.5) val=0; else val=1; if(ptr_d->val_par == val) 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) { valf=float_intel(ans+k); k+=4; if(valf < 0.5) val=0; else val=1; if(ptr_d->val_pr2 == val) ptr_d->dif_pr2 = 0; else { ptr_d->dif_pr2 = 1; ptr_d->val_pr2 = val; } } if(ptr_d->nom_vr3 > 0) { valf=float_intel(ans+k); k+=4; if(valf < 0.5) val=0; else val=1; if(ptr_d->val_pr3 == val) ptr_d->dif_pr3 = 0; else { ptr_d->dif_pr3 = 1; ptr_d->val_pr3 = val; } } if(ptr_d->nom_vr4 > 0) { valf=float_intel(ans+k); k+=4; if(valf < 0.5) val=0; else val=1; if(ptr_d->val_pr4 == val) 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; 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; 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; 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; c_write_wpipe(event_chn, val); } } #endif if(ptr_d->nom_dout > 0) { valf=float_intel(ans+k); k+=4; if(valf < 0.5) val=0; else val=1; if(ptr_d->val_out == val) ptr_d->dif_out = 0; else { ptr_d->dif_out = 1; ptr_d->val_out = val; } } if(ptr_d->nom_dot2 > 0) { valf=float_intel(ans+k); k+=4; if(valf < 0.5) val=0; else val=1; if(ptr_d->val_ot2 == val) ptr_d->dif_ot2 = 0; else { ptr_d->dif_ot2 = 1; ptr_d->val_ot2 = val; } } if(ptr_d->nom_dot3 > 0) { valf=float_intel(ans+k); k+=4; if(valf < 0.5) val=0; else val=1; if(ptr_d->val_ot3 == val) ptr_d->dif_ot3 = 0; else { ptr_d->dif_ot3 = 1; ptr_d->val_ot3 = val; } } ptr_d->novalid=0; } if(!kz) begin = 0; //------------ if(yes_P5)time_virt[(ptr_c-c_ptr)] = takt_cpu() - takt_old; //------------ } } //----------------------------------------------------------------- word_s scanU800(controller *ptr_c,byte *mask,word_s lask,byte *mans,word_s lans) { // mask[4]==0xB5 - можно использовать, как признак опроса // mask[4]==0x7В - можно использовать, как признак команды word_s i, kz, rept, bst; rept=1; BEGN: rept--; if(rept < 0) { kz=-1; goto END; } for(i=0; i < lans; i++) mans[i]=0x00; while(v24_receive(ptr_c->port,4L) != -1); /*** printf("ZAPR: lask=%3d lans=%3d\n",lask,lans); for(i=0; iport,mask[i],2L); if(i > 0 && i < lask-2) if(mask[i]==0x10) v24_send(ptr_c->port,mask[i],2L); } i=0; kz=v24_receive(ptr_c->port,40L); if(kz==-1) goto BEGN; mans[i]=kz; for(bst=0, i=1; i < lans; i++) { kz=v24_receive(ptr_c->port,2L); if(kz==-1) break; //if(kz==0x10 && mans[i-1]==0x10) { i--; continue; } if(kz==0x10) { if(bst) { bst=0; i--; continue; } else bst=1; } else bst=0; mans[i]=kz; } while(i && mans[i-1] != 0x03 && mans[i-2] != 0x10) i--; // отбр.хвост if(i != lans || mans[0] != 0x10 || mans[1] != 0x02) goto BEGN; if(mans[2] != 0xff || mans[3] != 0x01 || mans[4] != mask[4]) goto BEGN; if(mans[lans-2] != 0x10 || mans[lans-1] != 0x03) goto BEGN; if(*(word *)(mans+lans-4) != form_ks(mans+2,lans-6)) goto BEGN; for(i=8; i < lans-4; i++) if(mans[i] != 0) break; // проверка прогр. if(i >= lans-4) goto BEGN; // если программирование for(i=8; i < lans-4; i+=4) // 7f 80 00 01 - признак программир. if(mans[i]==0x7f && mans[i+1]==0x80 && mans[i+2]==0x00 && mans[i+3]==0x01) goto BEGN; kz=0; END: /*** printf("OTV : lask=%3d lans=%3d kz=%5d\n",lask,lans,kz); for(i=0; ikz=kz; kz_com(kz,ptr_c); return kz; } //------------------------------------------------------------------- word_s switch_U800(controller *p_c,digit *p_d,word_s nom_do,byte val_do) { word_s kz, l_ask, l_ans; byte ans[16]; static byte set_vd_U800[20] = { 0x10,2,1,0xff,0x7d,0x80,3,1,0,2,0xfb,0,0,0,0,0,0,0,0x10,3 }; /************ if(nom_do==p_d->nom_dout && val_do==p_d->val_out || nom_do==p_d->nom_dot2 && val_do==p_d->val_ot2 || nom_do==p_d->nom_dot3 && val_do==p_d->val_ot3) return 0; **************/ l_ask=20; l_ans=11; set_vd_U800[11]=nom_do-1; if(val_do) { set_vd_U800[12]=0x3f; set_vd_U800[13]=0x80; set_vd_U800[14]=set_vd_U800[15]=0; } else set_vd_U800[12]=set_vd_U800[13]=set_vd_U800[14]=set_vd_U800[15]=0; *(word_s *)(set_vd_U800+l_ask-4)=form_ks(set_vd_U800+2,l_ask-6); request_U800(p_c); kz = scanU800(p_c,set_vd_U800,l_ask,ans,l_ans); // if(kz) kz=scanU800(p_c,set_vd_U800,l_ask,ans,l_ans); // 2 и более на одну PC if(val_do && (p_d->type_com==1 || nom_do==p_d->nom_dot3)) { t_delay(20L); set_vd_U800[12]=set_vd_U800[13]=set_vd_U800[14]=set_vd_U800[15]=0; *(word_s *)(set_vd_U800+l_ask-4)=form_ks(set_vd_U800+2,l_ask-6); kz = scanU800(p_c,set_vd_U800,l_ask,ans,l_ans); // if(kz) kz=scanU800(p_c,set_vd_U800,l_ask,ans,l_ans); } release_U800(p_c); return kz; } //------------------------------------------------------------------- word form_ks(unsigned char *st,word_s len) { word i,j,ks; ks=0xffff; for(i=0; i>= 1; ks ^= 0xA001; } else ks >>= 1; } } return ks; } /*-------------------------------------------------------------------*/ void request_U800(controller *ptr_c) { word_s i; request_resource(ptr_c->port_rsc,0L); // захват поpта-pесурса tsk_outp(ptr_c->basaddr+7,3); // on this port tsk_outp(ptr_c->basaddr+4,0x02); // освободить сеть RTS:=1 for(i=0; i<10; i++) { if((tsk_inp(ptr_c->basaddr+6) & 0x10)) break; // если свободна сеть tsk_outp(ptr_c->basaddr+7,0); // off this port t_delay(2L); tsk_outp(ptr_c->basaddr+7,3); // on this port } tsk_outp(ptr_c->basaddr+4,0x00); // занять сеть RTS:=0 } /*-------------------------------------------------------------------*/ void release_U800(controller *ptr_c) { tsk_outp(ptr_c->basaddr+4,0x02); // освободить сеть RTS:=1 tsk_outp(ptr_c->basaddr+7,0); // off this port release_resource(ptr_c->port_rsc); // освоб.поpта-pесуpса } /*-------------------------------------------------------------------*/ insert_A_U800(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,3), "%3hd", &work_i); a_ptr->nomin_var =(byte)work_i; sscanf(x_db+= 3, "%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; } } /*-------------------------------------------------------------------*/ insert_D_U800(digit * d_ptr) { word_s i, work_i; byte *x_db; for(i=0; i < numrec; i++, d_ptr++) { read(fh, recfil, lenrec); d_ptr->novalid = 1; strncpy(d_ptr->cipher, (x_db = recfil + 1), 9); strncpy(d_ptr->name, (x_db += 9), 25); sscanf(x_db+= 25, "%1hd", &work_i); d_ptr->type_par = (byte)work_i; sscanf(x_db+= 1, "%1hd", &work_i); d_ptr->archive = work_i; sscanf(x_db+= 1, "%1hd", &work_i); d_ptr->reg_tim = work_i; sscanf(z_db(x_db+= 1,2), "%2hd", &work_i); d_ptr->param1 = (byte)work_i; sscanf(z_db(x_db+= 2,3), "%3hd", &d_ptr->nom_var); if(!d_ptr->nom_var) d_ptr->nom_var =-1; sscanf(z_db(x_db+= 3,3), "%3hd", &d_ptr->nom_vr2); if(!d_ptr->nom_vr2) d_ptr->nom_vr2 =-1; sscanf(z_db(x_db+= 3,3), "%3hd", &d_ptr->nom_vr3); if(!d_ptr->nom_vr3) d_ptr->nom_vr3 =-1; sscanf(z_db(x_db+= 3,3), "%3hd", &d_ptr->nom_vr4); if(!d_ptr->nom_vr4) d_ptr->nom_vr4 =-1; sscanf(x_db+= 3, "%1hd", &work_i); d_ptr->type_com = (byte)work_i; sscanf(z_db(x_db+= 1,3), "%3hd", &work_i); if(work_i) d_ptr->nom_dout=work_i; else d_ptr->nom_dout=-1; sscanf(z_db(x_db+= 3,3), "%3hd", &work_i); if(work_i) d_ptr->nom_dot2=work_i; else d_ptr->nom_dot2=-1; sscanf(z_db(x_db+= 3,3), "%3hd", &work_i); if(work_i) d_ptr->nom_dot3=work_i; else d_ptr->nom_dot3=-1; } } //--------------- Инициаллиизация контроллера ----------------------- void enable_U800(void) { word_s l_chan= 512,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!=U800 ) 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_U800(void) { word_s i; controller *ptr_c; for(i = 0, ptr_c = c_ptr; i < c_num; i++, ptr_c++) { if(ptr_c->typcontr==U800 && ptr_c->period) tsk_outp(ptr_c->basaddr+7,0); } }