#include #include #include #include #include #include #include #include "rs232.c" #define MAX_NO_IP_VARS 1500 #define NO_VP_VARS 39 #define NO_VPD_BYTES 74 /* No. of recv bytes of vp display vars; this includes cpu32 pad bytes for struct alignment */ main() { struct inputs { /* User inputs */ char isc_enable; char no_cool_cof,no_mat_cof,no_map_cof,no_tps_cof,no_bat_cof,no_baro_cof; float cool_cof[5],mat_cof[5],map_cof[5],tps_cof[5],bat_cof[5],baro_cof[5], accg_cof[5]; short int cool_lim1,cool_lim11,cool_lim2,cool_def; short int mat_lim1,mat_lim2,mat_def; short int map_lim1,map_lim2,map_def; short int tps_lim1,tps_lim2,tps_def; short int bat_lim1,bat_lim2,bat_def; short int baro_lim1,baro_lim2,baro_def; short int inj_lim1,inj_lim2,t_inj_bkpt,t_inj_ramp,t_inj_close; short int bat_comp1_slpe,bat_comp2_slpe; unsigned char num_teeth,max_add_teeth,deg_per_tooth; short int no_temp,warm_tempa[30],warm_enrich_table[30],warm_spark_table[30], ism_pos_table[30],acc_temp_table[30]; unsigned long t_strt_enrich,t_strt_enrich_tail,t_aft_strt_enrich, t_aft_strt_enrich_min,t_aft_strt_enrich_tail,tmax_we; short int strt_enrich_const,strt_enrich_tempconst, aft_strt_enrich_const,aft_strt_enrich_tempconst; long t_xisc_const; short int ptemp_xisc_const; unsigned long t_burst,t_burst_tail,t_acc_tail; short int tps_acc,map_acc,acc0,acc_pw0,acc_burst; float acc_wght1,acc_wght2; unsigned short int ism_maxsteps,time_bet_steps1,time_bet_stepsn; unsigned char step_rate_cnt; short int rev_lim,del_rpm; float mass_air_coeff,veaf_table[20][20],spark_table[16][16],inj_flow_ramp, inj_flow_max,inj_flow_close,spk_adv_max; short int no_vmaps,no_vrpms,veaf_maps[20],veaf_rpms[20], no_smaps,no_srpms,spark_maps[16],spark_rpms[16]; short int pw_min,max_duty_cycle,cyl_fuel[8],cyl_spark[8]; short int stop_inj,exh_close,deg_reach_valve_air,inj_adv; float fuel_spd_cof; unsigned long t_fpump_shut; short int rpm_clr_choke,tps_clr_choke,start_inj_batch; } *ip,ipst; /* Need ipst on pc */ struct variables { /* Program variables */ /* Start std display variables */ short int rpm; short int cool_temp,mat_temp,map_press,map_dot,tps_dot,tps_pos, bat_v100,baro_press,bat_comp1,bat_comp2; char check_eng[8]; short int pw; float spark_advance; short int cyl_no,pw_deg,start_inj_rel; short int acc_enrich,acc_pw; short int pm_fuel,pm_spark,pm_isc,pm_spare; char after_warmup; short int strt_enrich,aft_strt_enrich,warmup_enrich,warmup_spark,ism_pos_cmd; unsigned long clock_time; short int pcpu_remain,accg; /* End std display variables */ } *vp,vpst; /* Need vpst on pc */ /* Tables */ char cnvti[MAX_NO_IP_VARS]; unsigned short int offseti[MAX_NO_IP_VARS]; unsigned short int offsetu[MAX_NO_IP_VARS]; /* unpadded offset */ char pad_ip[MAX_NO_IP_VARS]; char bytesi[4] = {1,2,4,4}; char vcnvt[NO_VP_VARS] = {2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1, 2,4,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,2,2}; char pad[NO_VP_VARS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}; /* no. of cpu32 pad bytes for vp structure. If add new vp var, change last pad no. and add 0 pad for the new variable. */ FILE *fili,*fild; char fild_open_flag,menu_choice; char *ch_ptr,*ip_ptr,*vp_ptr,*vp_buf_ptr; char vp_buf[NO_VPD_BYTES]; char var_no_strng[6],value_strng[80],new_value,ctmp; char rs232_inbuf[512],rs232_outbuf[512]; short int var_no,ix,jx,drate,no_ip_vars,no_vp_bytes; unsigned short int byte_offset,no_bytes,no_vp_bytes_pc; char err,ans,save_flag,cnvt,xcmd; unsigned char kchar,kchar2,butn; float maph,mapf,coolf,matf,baroh,barof,tpsf,batf,spark_corr; float enrch1,enrch2,enrch3,wsprk,enrch4; unsigned long clksec,delta_t; char pcalc_enable,pcalc_start; unsigned long t_start; short int rpm_pcalc[6],del_rpm,rpm_start,ipcalc,npcalc; float ptime,accgf; union all_types { char v1; short int v2; int v4; float vf; } value; ip = &ipst; vp = &vpst; ip_ptr = (char *) &ipst; vp_ptr = (char *) &vpst; no_vp_bytes = NO_VPD_BYTES; no_vp_bytes_pc = sizeof(vpst); drate = 250; /* display update rate (ms) */ pcalc_enable = 'n'; rpm_pcalc[0] = 0; del_rpm = 0; npcalc = 0; fild_open_flag = 0; fili = fopen("EFINPUT.DAT","r+"); /* ASCII file with value of each ip variable and its byte_offset and type on a separate line */ no_ip_vars = -1; /* Fill arrays offseti & cnvti; count no_ip_vars */ while(fgets(value_strng,79,fili) != NULL) { /* read record */ no_ip_vars++; value_strng[15] = '\0'; /* get padded(cpu32) byte offset from file */ offseti[no_ip_vars] = atoi(&value_strng[8]); value_strng[43] = '\0'; /* get variable type from file */ if(strcmp(&value_strng[32],"char ") == 0) cnvti[no_ip_vars] = 1; if(strcmp(&value_strng[32],"shrt int ") == 0) cnvti[no_ip_vars] = 2; if(strcmp(&value_strng[32],"int ") == 0) cnvti[no_ip_vars] = 3; if(strcmp(&value_strng[32],"float ") == 0) cnvti[no_ip_vars] = 4; /* calculate unpadded(pc) byte offset */ if(no_ip_vars == 0) offsetu[0] = 0; else offsetu[no_ip_vars] = offsetu[no_ip_vars - 1] + bytesi[cnvti[no_ip_vars - 1] - 1]; } for(ix=0; ix < no_ip_vars; ix++) { pad_ip[ix] = (offseti[ix+1] - offseti[ix]) - bytesi[cnvti[ix] - 1]; } pad_ip[no_ip_vars] = 0; no_ip_vars++; /* Open com port */ rs_initport(RS_PORT1,RS_B2400,RS_NOPAR,RS_DBIT8,RS_SBIT1,512U, rs232_inbuf,512U,rs232_outbuf); /* Main Menu */ MAINMENU: clrscr(); /* clear screen */ gotoxy(20,5); printf("1 = ALTER INDIVIDUAL INPUTS"); gotoxy(20,7); printf("2 = DOWNLOAD INPUT FILE"); gotoxy(20,9); printf("3 = DISPLAY ENGINE FUNCTIONS"); gotoxy(20,11); printf("4 = CALCULATE DTs BETWEEN RPMs"); gotoxy(20,13); printf("X = EXIT"); printf("%c",7); /* ring bell */ menu_choice = getch(); switch (menu_choice) { case '1': /* Alter individual inputs */ clrscr(); gotoxy(1,2); ENTVAR: printf("Enter Input Variable No.: "); gets(var_no_strng); if(var_no_strng[0] == 'x' || var_no_strng[0] == 'X') goto MAINMENU; var_no = atoi(var_no_strng); if(var_no < 0 || var_no >= no_ip_vars) { printf("%c",7); printf("%c",7); goto ENTVAR; } printf("Enter Value: "); gets(value_strng); if(value_strng[0] == 'x' || value_strng[0] == 'X') goto MAINMENU; rs_sndbyt('C'); cnvt = cnvti[var_no]; /* Note: no error checking */ if(cnvt == 1) value.v1 = atoi(value_strng); if(cnvt == 2) value.v2 = atoi(value_strng); if(cnvt == 3) value.v4 = atol(value_strng); if(cnvt == 4) value.vf = atof(value_strng); no_bytes = bytesi[cnvt - 1]; byte_offset = offseti[var_no]; /* send as 2 big endian bytes; no_bytes is 1st nibble */ xcmd = ((char)no_bytes << 4) | (char)(byte_offset >> 8); rs_sndbyt(xcmd); rs_sndbyt((char)byte_offset); /* convert value to big endian */ ch_ptr = (char *)&value; if(cnvt == 2) { ctmp = *ch_ptr; *ch_ptr = *(ch_ptr + 1); *(ch_ptr + 1) = ctmp; } if((cnvt == 3) || (cnvt == 4)) { ctmp = *ch_ptr; *ch_ptr = *(ch_ptr + 3); *(ch_ptr + 3) = ctmp; ctmp = *(ch_ptr + 1); *(ch_ptr + 1) = *(ch_ptr + 2); *(ch_ptr + 2) = ctmp; } /* note: value is now big endian */ rs_sndstr(no_bytes,ch_ptr); /* Do readback */ err=0; rs_sndbyt('I'); xcmd = ((char)no_bytes << 4) | (char)(byte_offset >> 8); rs_sndbyt(xcmd); rs_sndbyt((char)byte_offset); ch_ptr = (char *)&value; for(ix=0; ix < no_bytes; ix++) { while(rs_inrcvd() <= 0); new_value=rs_getbyt(); if(new_value != *(ch_ptr + ix)) err = 1; } if(err == 0) { /* Update EFINPUT file also */ fseek(fili,(79 * (unsigned long)var_no + 44),SEEK_SET); /* each record 79 bytes, including '|' & new line & \0 ; value_strng starts @ byte 45 */ for(ix = strlen(value_strng); ix < 16; ix++) { value_strng[ix] = ' '; /* get rid of end of strng & blank rest of field */ } fwrite(value_strng,1,16,fili); goto ENTVAR; } else { /* readback failed */ printf("Transmission Error - Try Again \n"); goto ENTVAR; } case '2': /* Download entire input file */ clrscr(); rs_sndbyt('$'); printf("Input File Being Downloaded \n"); for(ix = 0; ix < no_ip_vars; ix++) { fseek(fili,(79 * (unsigned long)ix + 44),SEEK_SET); fread(value_strng,1,16,fili); value_strng[16] = '\0'; cnvt = cnvti[ix]; if(cnvt == 1) value.v1 = atoi(value_strng); if(cnvt == 2) value.v2 = atoi(value_strng); if(cnvt == 3) value.v4 = atol(value_strng); if(cnvt == 4) value.vf = atof(value_strng); no_bytes = bytesi[cnvt - 1]; /* convert value to big endian */ ch_ptr = (char *)&value; if(cnvt == 2) { ctmp = *ch_ptr; *ch_ptr = *(ch_ptr + 1); *(ch_ptr + 1) = ctmp; } if((cnvt == 3) || (cnvt == 4)) { ctmp = *ch_ptr; *ch_ptr = *(ch_ptr + 3); *(ch_ptr + 3) = ctmp; ctmp = *(ch_ptr + 1); *(ch_ptr + 1) = *(ch_ptr + 2); *(ch_ptr + 2) = ctmp; /* Note: value is now big endian */ } /* Fill ip structure(unpadded on pc) with values from EFINPUT file */ for(jx = 0; jx < no_bytes; jx++) { *(ip_ptr + offsetu[ix] + jx) = *(ch_ptr + jx); } /* Send value + appropriate pad bytes to cpu32 */ no_bytes += pad_ip[ix]; rs_sndstr(no_bytes,ip_ptr + offsetu[ix]); } VERIFY: rs_sndbyt('/'); printf("File Downloaded - Now Being Verified \n"); err = 0; for(ix = 0; ix < no_ip_vars; ix++) { no_bytes = bytesi[cnvti[ix] - 1]; for(jx = 0; jx < no_bytes + pad_ip[ix]; jx++) { while(rs_inrcvd() <= 0); new_value = rs_getbyt(); if(jx < no_bytes) { /* ignore pad bytes */ if(new_value != *(ip_ptr + offsetu[ix] + jx)) err = 1; } } } if(err == 0) { printf("File Verified \n"); goto MAINMENU; } else { printf("Transmission Error - Want to Try Again (y/n)? \n"); ans = getch(); if(ans == 'Y' || ans == 'y') { rs_sndbyt('$'); printf("Input File Being Downloaded \n"); rs_sndstr(sizeof(*ip),ip_ptr); goto VERIFY; } else goto MAINMENU; } case '3': /* Display engine functions */ clrscr(); rs_sndbyt('%'); /* request frame of display data from cpu332 */ /* Set up display headings */ gotoxy(1,1); printf(" Clock MAP PW PW Strt_inj_ Spark\n"); printf(" (sec) RPM inHg(KPa) (microsec) (deg) rel(deg) (deg)\n"); printf(" ----- --- --------- ---------- ----- -------- -----\n"); gotoxy(1,6); printf(" Cool MAT BARO TPS BAT Bat_cmp1 Bat_cmp2\n"); printf(" (F) (F) inHg(KPa) (p opn) (volts) (usec) (usec)\n"); printf(" ---- --- --------- ------- ------- -------- --------\n"); gotoxy(1,11); printf(" After Strt Aft_strt Warmup Warmup Ism_Pos\n"); printf(" Warmup Enrich Enrich Enrich Spark Cmd\n"); printf(" ------ ------ ------ ------ ----- -----\n"); gotoxy(1,16); printf(" Tps_dot Map_dot Acc Acc_pw Acc_g Pcpu_rem\n"); printf(" (p/sec) (KPa/sec) Enrich (microsec) (g) (percent)\n"); printf(" ------- -------- ------ --------- --- ---------\n"); gotoxy(1,21); printf(" Eng CLT MAT MAP TPS BAT BAR INJ Fuel Sprk ISC\n"); printf(" ----- --- --- --- --- --- --- --- ---- ---- ---\n"); save_flag = 0; while(rs_inrcvd() < no_vp_bytes); rs_getstr(no_vp_bytes,&vp_buf[0]); GETDISP: /* convert display data to little endian */ ch_ptr = vp_ptr; vp_buf_ptr = &vp_buf[0]; for (ix=0; ix < NO_VP_VARS; ix++) { if(vcnvt[ix] == 1) { *ch_ptr = *vp_buf_ptr; ch_ptr++; vp_buf_ptr++; } if(vcnvt[ix] == 2) { *ch_ptr = *(vp_buf_ptr + 1); *(ch_ptr + 1) = *vp_buf_ptr; ch_ptr += 2; vp_buf_ptr += 2; } if((vcnvt[ix] == 3) || (vcnvt[ix] == 4)) { *ch_ptr = *(vp_buf_ptr + 3); *(ch_ptr + 1) = *(vp_buf_ptr + 2); *(ch_ptr + 2) = *(vp_buf_ptr + 1); *(ch_ptr + 3) = *vp_buf_ptr; ch_ptr += 4; vp_buf_ptr += 4; } vp_buf_ptr += pad[ix]; /* pad out cpu32 struct var to align next word; word size on pc =1 byte, so don't need to pad for struct alignment. */ } /* end for loop */ rs_sndbyt('%'); /* request next frame of display data */ rs_timer(0); /* zero out pc timer (msec); resoln ~ .055 sec */ barof = (vp->baro_press / 10.0); mapf = (vp->map_press / 10.0); maph = (barof - mapf) * .2953; /* equiv vac in in Hg */ clksec = vp->clock_time / 10000.0; /* tpu time since synch: cnvt fm ms/10 to sec */ spark_corr = vp->spark_advance - 9.0; /* 9.0 = ((float).12 * ip->deg_per_tooth) */ gotoxy(1,4); printf(" %6ld %5u %4.1f(%5.1f) %6u %4d %4d %5.1f",clksec, vp->rpm,maph,mapf,vp->pw,vp->pw_deg,vp->start_inj_rel,spark_corr); coolf = (vp->cool_temp / 10.0); matf = (vp->mat_temp / 10.0); baroh = barof * .2953; tpsf = (vp->tps_pos / 10.0); batf = (vp->bat_v100 / 100.0); gotoxy(1,9); printf(" %5.1f %5.1f %4.1f(%5.1f) %5.2f %5.2f %5d %5d", coolf,matf,baroh,barof,tpsf,batf,vp->bat_comp1,vp->bat_comp2); enrch1 = (vp->strt_enrich / 100.0); enrch2 = (vp->aft_strt_enrich / 100.0); enrch3 = (vp->warmup_enrich / 100.0); wsprk = (vp->warmup_spark / 10.0); gotoxy(1,14); printf(" %1d %5.2f %5.2f %5.2f %5.1f %4u", vp->after_warmup, enrch1,enrch2,enrch3,wsprk,vp->ism_pos_cmd); enrch4 = (vp->acc_enrich / 100.0); gotoxy(1,19); accgf = vp->accg/1000.; printf(" %6d %6d %5.2f %6d %6.3f %5d", vp->tps_dot,vp->map_dot,enrch4,vp->acc_pw,accgf,vp->pcpu_remain); gotoxy(1,23); printf(" %2d %2d %2d %2d %2d %2d %2d %2d %4d %4d %4d", vp->check_eng[0],vp->check_eng[1],vp->check_eng[2], vp->check_eng[3], vp->check_eng[4],vp->check_eng[5],vp->check_eng[6],vp->check_eng[7], vp->pm_fuel,vp->pm_spark,vp->pm_isc); if(save_flag == 1) { if(fild_open_flag == 0) { fild = fopen("EFOUTPUT.DAT","wb"); fild_open_flag = 1; } fwrite(vp_ptr,no_vp_bytes_pc,1,fild); gotoxy(65,24); printf("Saving"); } else { gotoxy(65,24); printf(" "); } if(pcalc_enable == 'y') { /* Calculate and display dt between rpms */ if(vp->rpm < rpm_pcalc[0]) pcalc_start = 1; /* if drop below, restart clock */ if(pcalc_start == 1) { if(vp->rpm >= rpm_pcalc[0]) { pcalc_start = 2; ipcalc = 1; t_start = vp->clock_time; /* start clock (ms x 10) */ rpm_start = vp->rpm; } } else if(pcalc_start == 2) { if(vp->rpm >= rpm_pcalc[ipcalc]) { ptime = (float)(rpm_pcalc[ipcalc] - rpm_pcalc[ipcalc - 1]) / (vp->rpm - rpm_start); /* standardize dt so it represents dt between rpm_upper and _lower */ ptime *= ((vp->clock_time - t_start) / 10000.); /* sec */ gotoxy( -8 + ipcalc*11,24); if(ipcalc == 1) printf("Dt= %8.4f",ptime); else printf(" %8.4f",ptime); if(ipcalc < npcalc) { ipcalc++; t_start = vp->clock_time; rpm_start = vp->rpm; } else /* stop clock */ pcalc_start = 0; } } } /* end power calc */ while(rs_inrcvd() < no_vp_bytes); rs_getstr(no_vp_bytes,&vp_buf[0]); /* Read char from keyboard buffer */ if(rs_keyhit()) { kchar = getch(); switch (kchar) { case 'x': case 'X': goto MAINMENU; case 's': case 'S': save_flag = 1; break; case 'h': case 'H': save_flag = 0; break; case 0: /* Function key */ kchar2 = getch(); butn = 99; if((kchar2 >= 59) && (kchar2 <= 68)) butn = kchar2 - 58; if(kchar2 == 133) butn = 11; if(kchar2 == 134) butn = 12; if(butn != 99) { rs_sndbyt('B'); rs_sndbyt(butn); } } /* end kchar switch */ } /* end keyhit check */ do { delta_t = rs_timer(1) / .0182; /* elapsed time (ms) since rs_timer(0) */ if(delta_t >= drate) break; /* delay so display rate = drate msec */ } while(1); goto GETDISP; case '4': /* Calculate dt between rpms */ clrscr(); gotoxy(1,2); printf("RPM_lower = [%d] = ",rpm_pcalc[0]); gets(value_strng); if(strlen(value_strng) > 0) rpm_pcalc[0] = atoi(value_strng); /* No error check */ printf("del_RPM = [%d] = ",del_rpm); gets(value_strng); if(strlen(value_strng) > 0) del_rpm = atoi(value_strng); /* No error check */ printf("no_RPM = [%d] = ",npcalc); gets(value_strng); if(strlen(value_strng) > 0) { npcalc = atoi(value_strng); if(npcalc > 5) npcalc = 5; } if(npcalc > 0) { for(ipcalc = 1; ipcalc <= npcalc; ipcalc++) rpm_pcalc[ipcalc] = rpm_pcalc[ipcalc - 1] + del_rpm; } printf("dt_rpm_enable = [%d] = ",pcalc_enable); kchar = getch(); if(kchar == 'y' || kchar == 'Y') pcalc_enable = 'y'; if(kchar == 'n' || kchar == 'N') pcalc_enable = 'n'; pcalc_start = 0; goto MAINMENU; case 'x': case 'X': if(fild_open_flag == 1) fclose(fild); fclose(fili); rs_close(); clrscr(); goto FINISHED; } /* end menu choice switch */ printf("%c",7); printf("%c",7); goto MAINMENU; FINISHED: return(0); }