00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <p24FJ64GA002.h>
00019
00020 #include "types.h"
00021 #include "table.h"
00022 #include "ssm.h"
00023
00024 #include "libadc.h"
00025 #include "librtc.h"
00026 #include "libuart.h"
00027
00028
00029
00030
00031
00032
00033 #define SSM_SHIFT(x,y) (x - (x - y) / 2.0)
00034
00035
00036 #define TIRE_WIDTH 235
00037 #define TIRE_FLAT 45
00038 #define TIRE_INCH 17
00039
00040
00041 #define GEAR_F 3.900
00042 #define GEAR_1 3.636
00043 #define GEAR_2 2.375
00044 #define GEAR_3 1.761
00045 #define GEAR_4 1.346
00046 #define GEAR_5 1.062
00047 #define GEAR_6 0.842
00048 #define GEAR_7 0.001
00049
00050
00051
00052
00053
00054 SSM_T ssm;
00055 SSM_DATA_T ssm_data;
00056
00057
00058
00059
00060
00061 static inline BOOL SSM_openssm(void);
00062 static inline void SSM_log(void);
00063 static inline BOOL SSM_openport(void);
00064 static inline void SSM_write_packet(void);
00065 static inline BOOL SSM_read_packet(pSSM_T ssm, pSSM_DATA_T data);
00066 static inline unsigned char SSM_calc_gear(pSSM_T ssm, pSSM_DATA_T data);
00067
00068
00069
00070
00071
00072 void SSM_init(void)
00073 {
00074
00075 ssm.tire_width = TIRE_WIDTH;
00076 ssm.tire_flat = TIRE_FLAT;
00077 ssm.tire_inch = TIRE_INCH;
00078 ssm.gear_ratio[0] = GEAR_F;
00079 ssm.gear_ratio[1] = GEAR_1;
00080 ssm.gear_ratio[2] = GEAR_2;
00081 ssm.gear_ratio[3] = GEAR_3;
00082 ssm.gear_ratio[4] = GEAR_4;
00083 ssm.gear_ratio[5] = GEAR_5;
00084 ssm.gear_ratio[6] = GEAR_6;
00085 ssm.gear_ratio[7] = GEAR_7;
00086 ssm.price = 100;
00087
00088
00089 ssm.tire_circle = SSM_TIRE_R(ssm.tire_width, ssm.tire_flat, ssm.tire_inch);
00090
00091 ssm.mode = SSM_MODE_OPENSSM;
00092
00093 ssm.wait = 1500;
00094 ssm.last = rtc.tick;
00095 ssm.cycle = 0xffff;
00096 ssm.error = 0x0000;
00097
00098 UART1_buf_clear();
00099 UART2_buf_clear();
00100 return;
00101 }
00102
00103
00104
00105
00106
00107 BOOL SSM_main(void)
00108 {
00109 static unsigned char mode = 0xff;
00110
00111
00112 switch(ssm.mode){
00113
00114
00115
00116 case SSM_MODE_OPENSSM:
00117
00118
00119 if(mode != ssm.mode){
00120 UART1_init(115200);
00121 UART2_init( 4800);
00122 }
00123
00124 mode = ssm.mode;
00125 return(SSM_openssm());
00126 break;
00127
00128
00129
00130 case SSM_MODE_OPENPORT:
00131 default:
00132
00133
00134 if(mode != ssm.mode){
00135 UART1_init( 4800);
00136 UART2_init( 4800);
00137 }
00138
00139 mode = ssm.mode;
00140 return(SSM_openport());
00141 break;
00142 }
00143
00144
00145 return(FALSE);
00146 }
00147
00148
00149
00150
00151
00152 static inline BOOL SSM_openssm(void)
00153 {
00154 static unsigned int tick = 0;
00155 static unsigned char flag = 0;
00156
00157
00158 if(RTC_get_ticks(tick, rtc.tick) < ssm.wait) return(FALSE);
00159 tick = rtc.tick;
00160
00161 if(!SSM_read_packet(&ssm, &ssm_data)){
00162 ssm.error++;
00163
00164
00165 if(ssm.error >> 1){
00166 SSM_write_packet();
00167 ssm.cycle = 0xffff;
00168 }
00169 } else {
00170 ssm.cycle = RTC_get_ticks(ssm.last, rtc.tick);
00171 ssm.last = rtc.tick;
00172 SSM_write_packet();
00173 }
00174
00175
00176 if(UART1_getch() == ' ') flag++;
00177 if(flag % 2) SSM_log();
00178
00179 return(TRUE);
00180 }
00181
00182
00183
00184
00185
00186 static inline void SSM_log(void)
00187 {
00188 double sec;
00189
00190
00191 sec = rtc.sec + (double)rtc.msec / 1000.0;
00192 UART1_putint(rtc.hour);
00193 UART1_putch(':');
00194 UART1_putint(rtc.min);
00195 UART1_putch(':');
00196 UART1_putdouble(sec, 3);
00197 UART1_putch(',');
00198
00199
00200 UART1_putint(ssm_data.engine);
00201 UART1_putch(',');
00202 UART1_putint(ssm_data.speed);
00203 UART1_putch(',');
00204 UART1_putint(ssm_data.throttle);
00205 UART1_putch(',');
00206 UART1_putint(ssm_data.shift);
00207 UART1_putch(',');
00208 UART1_putint(ssm_data.coolant);
00209 UART1_putch(',');
00210 UART1_putint(ssm_data.intakeair);
00211 UART1_putch(',');
00212 UART1_putdouble(ssm_data.battery, 1);
00213 UART1_putch(',');
00214 UART1_putdouble(ssm_data.fuel, 1);
00215 UART1_putch(',');
00216 UART1_putint(ssm_data.maf);
00217 UART1_putch(',');
00218 UART1_putdouble(ssm_data.afr, 1);
00219 UART1_putch(',');
00220 UART1_putint(ssm_data.knock);
00221 UART1_putch(',');
00222 UART1_putint(ssm_data.ignition);
00223 UART1_putch(',');
00224
00225
00226 UART1_putint(adc.adc[0]);
00227 UART1_putch(',');
00228 UART1_putint(adc.adc[1]);
00229 UART1_putch(',');
00230 UART1_putint(adc.adc[2]);
00231
00232 UART1_putch('¥r');
00233 UART1_putch('¥n');
00234
00235 return;
00236 }
00237
00238
00239
00240
00241
00242
00243 static inline BOOL SSM_openport(void)
00244 {
00245 int buf;
00246
00247 while((buf = UART1_getch()) > 0){
00248 UART2_putch(buf);
00249 }
00250
00251 while((buf = UART2_getch()) > 0){
00252 UART1_putch(buf);
00253 }
00254
00255 return(TRUE);
00256 }
00257
00258
00259
00260
00261
00262 static inline void SSM_write_packet(void)
00263 {
00264 unsigned char i;
00265 const unsigned char packet[] = {
00266 0x80, 0x10, 0xf0, 0x29, 0xa8, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x15,
00267 0x00, 0x00, 0x10, 0x00, 0x00, 0x24, 0x00, 0x00, 0x08, 0x00, 0x00, 0x12, 0x00, 0x00, 0x1c,
00268 0x00, 0x00, 0x13, 0x00, 0x00, 0x14, 0x00, 0x00, 0x46, 0x00, 0x00, 0x11, 0x00, 0x00, 0x22,
00269 0x8d,
00270 };
00271
00272 UART2_buf_clear();
00273 for(i = 0; i < sizeof(packet); i++){
00274 UART2_putch(packet[i]);
00275 }
00276
00277 return;
00278 }
00279
00280 static inline BOOL SSM_read_packet(pSSM_T ssm, pSSM_DATA_T data)
00281 {
00282 int buf;
00283 unsigned char i;
00284 double fuel;
00285
00286 static unsigned char read_packet[ 18 ];
00287
00288
00289 i = 0;
00290 while((buf = UART2_getch()) != -1 && i < 45){
00291
00292 i++;
00293 }
00294 i = 0;
00295 while((buf = UART2_getch()) != -1 && i < 18){
00296 read_packet[i] = (unsigned char)buf;
00297 i++;
00298 }
00299
00300
00301 if(read_packet[ 0] != 0x80) return(FALSE);
00302 if(read_packet[ 1] != 0xf0) return(FALSE);
00303 if(read_packet[ 2] != 0x10) return(FALSE);
00304 if(read_packet[ 3] != 0x0e) return(FALSE);
00305 if(read_packet[ 4] != 0xe8) return(FALSE);
00306
00307
00308 data->engine = ((read_packet[ 5] << 8) + read_packet[ 6]) >> 2;
00309 data->throttle = (double)((int)read_packet[ 7] * 100) / 255.0;
00310 data->speed = read_packet[ 8];
00311 data->boost = (((double)read_packet[ 9] - 128.0) * 37.0) / 3570.0;
00312 data->coolant = (int)read_packet[10] - 40;
00313 data->intakeair = (int)read_packet[11] - 40;
00314 data->battery = (double)read_packet[12] * 0.08;
00315 data->shift = SSM_calc_gear(ssm, data);
00316 data->maf = (double)(((unsigned int)read_packet[13] << 8) + (unsigned int)read_packet[14]) / 100.0;
00317 data->afr = ((double)read_packet[15] / 128.0) * 14.7;
00318 data->ignition = (read_packet[16] - 128) >> 1;
00319 data->knock = (read_packet[17] - 128) >> 1;
00320
00321
00322 if(data->engine > 0){
00323 fuel = (data->maf / data->afr) / 761.0;
00324 } else {
00325 fuel = 0;
00326 }
00327
00328 data->fuel = ((double)data->speed / 3600.0) / fuel;
00329 data->fuel_rate = fuel * 1000;
00330
00331 return(TRUE);
00332 }
00333
00334
00335
00336
00337
00338 static inline unsigned char SSM_calc_gear(pSSM_T ssm, pSSM_DATA_T data)
00339 {
00340 double ratio;
00341 unsigned char shift;
00342
00343
00344 if(data->engine < 1000) return(0);
00345 if(data->speed == 0) return(0);
00346
00347
00348 ratio = (data->engine / (data->speed * ssm->gear_ratio[ SSM_GEAR_FINAL ]) * ssm->tire_circle * 60.0);
00349 ratio /= 1000000.0;
00350
00351
00352 if(SSM_SHIFT(ssm->gear_ratio[SSM_GEAR_1], ssm->gear_ratio[SSM_GEAR_2]) <= ratio) shift = SSM_GEAR_1;
00353 if(SSM_SHIFT(ssm->gear_ratio[SSM_GEAR_1], ssm->gear_ratio[SSM_GEAR_2]) > ratio) shift = SSM_GEAR_2;
00354 if(SSM_SHIFT(ssm->gear_ratio[SSM_GEAR_2], ssm->gear_ratio[SSM_GEAR_3]) > ratio) shift = SSM_GEAR_3;
00355 if(SSM_SHIFT(ssm->gear_ratio[SSM_GEAR_3], ssm->gear_ratio[SSM_GEAR_4]) > ratio) shift = SSM_GEAR_4;
00356 if(SSM_SHIFT(ssm->gear_ratio[SSM_GEAR_4], ssm->gear_ratio[SSM_GEAR_5]) > ratio) shift = SSM_GEAR_5;
00357 if(SSM_SHIFT(ssm->gear_ratio[SSM_GEAR_5], ssm->gear_ratio[SSM_GEAR_6]) > ratio) shift = SSM_GEAR_6;
00358 if(SSM_SHIFT(ssm->gear_ratio[SSM_GEAR_6], ssm->gear_ratio[SSM_GEAR_7]) > ratio) shift = SSM_GEAR_7;
00359
00360 return(shift);
00361 }