00001 /* FreeEMS - the open source engine management system 00002 * 00003 * Copyright 2008, 2009, 2010 Fred Cooke, Philip L Johnson 00004 * 00005 * This file is part of the FreeEMS project. 00006 * 00007 * FreeEMS software is free software: you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation, either version 3 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * FreeEMS software is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with any FreeEMS software. If not, see http://www.gnu.org/licenses/ 00019 * 00020 * We ask that if you make any changes to this file you email them upstream to 00021 * us at admin(at)diyefi(dot)org or, even better, fork the code on github.com! 00022 * 00023 * Thank you for choosing FreeEMS to run your engine! 00024 */ 00025 00026 00039 #define UTILS_C 00040 #include "inc/freeEMS.h" 00041 #include "inc/commsISRs.h" 00042 #include "inc/utils.h" 00043 #include <string.h> 00044 00045 00055 unsigned short safeAdd(unsigned short addend1, unsigned short addend2){ 00056 if((SHORTMAX - addend1) > addend2){ 00057 return addend1 + addend2; 00058 }else{ 00059 return SHORTMAX; 00060 } 00061 } 00062 00063 00073 unsigned short safeTrim(unsigned short addend1, signed short addend2){ 00074 00075 if(addend2 < 0){ 00076 if(addend1 > -addend2){ 00077 return addend1 + addend2; 00078 }else{ 00079 return 0; 00080 } 00081 }else if(addend2 > 0){ 00082 if(addend2 < (SHORTMAX - addend1)){ 00083 return addend1 + addend2; 00084 }else{ 00085 return SHORTMAX; 00086 } 00087 }else{ 00088 return addend1; 00089 } 00090 } 00091 00092 00104 unsigned short safeScale(unsigned short baseValue, unsigned short scaler){ 00105 /* Perform the scaling */ 00106 unsigned short scaled = ((unsigned long)baseValue * scaler) / SHORTHALF; 00107 00108 /* If the trim is greater than 100% then the trimmedPW MUST be larger */ 00109 /* If it's less than 100% it can't have overflowed */ /* If it's not larger, it overflowed */ 00110 if((scaler > SHORTHALF) && (baseValue > scaled)){ 00111 return SHORTMAX; 00112 }else{ 00113 return scaled; 00114 } 00115 } 00116 00117 00128 void setupPagedRAM(unsigned char bool){ 00129 if(bool){ 00130 currentFuelRPage = RPAGE_FUEL_ONE; 00131 currentTimeRPage = RPAGE_TIME_ONE; 00132 currentTuneRPage = RPAGE_TUNE_ONE; 00133 }else{ 00134 currentFuelRPage = RPAGE_FUEL_TWO; 00135 currentTimeRPage = RPAGE_TIME_TWO; 00136 currentTuneRPage = RPAGE_TUNE_TWO; 00137 } 00138 00139 RPAGE = currentTuneRPage; 00140 } 00141 00142 00151 void resetToNonRunningState(){ 00152 /* Reset RPM to zero */ 00153 RPM0 = 0; 00154 RPM1 = 0; 00155 00156 /* Ensure tacho reads lowest possible value */ 00157 engineCyclePeriod = ticksPerCycleAtOneRPM; 00158 00159 /* Clear all sync flags to lost state */ 00160 //coreStatusA &= CLEAR_RPM_VALID; 00161 coreStatusA &= CLEAR_PRIMARY_SYNC; 00162 //coreStatusA &= CLEAR_SECONDARY_SYNC; 00163 00164 // TODO more stuff needs resetting here, but only critical things. 00165 } 00166 00167 00174 void adjustPWM(){ 00175 PWMDTY0 = ATD0DR0 >> 2; // scale raw adc to a duty 00176 PWMDTY1 = ATD0DR1 >> 2; // scale raw adc to a duty 00177 PWMDTY2 = ATD0DR2 >> 2; // scale raw adc to a duty 00178 PWMDTY3 = ATD0DR3 >> 2; // scale raw adc to a duty 00179 PWMDTY4 = ATD0DR4 >> 2; // scale raw adc to a duty 00180 PWMDTY5 = ATD0DR5 >> 2; // scale raw adc to a duty 00181 PWMDTY6 = ATD0DR6 >> 2; // scale raw adc to a duty 00182 PWMDTY7 = ATD0DR7 >> 2; // scale raw adc to a duty (user led instead at the moment, see init) 00183 } 00184 00185 00194 void sampleEachADC(ADCArray *Arrays){ 00195 /* ATD0 */ 00196 Arrays->IAT = ATD0DR0; 00197 Arrays->CHT = ATD0DR1; 00198 Arrays->TPS = ATD0DR2; 00199 Arrays->EGO = ATD0DR3; 00200 Arrays->MAP = ATD0DR4; 00201 Arrays->AAP = ATD0DR5; 00202 Arrays->BRV = ATD0DR6; 00203 Arrays->MAT = ATD0DR7; 00204 00205 /* ATD1 */ 00206 Arrays->EGO2 = ATD1DR0; 00207 Arrays->IAP = ATD1DR1; 00208 Arrays->MAF = ATD1DR2; 00209 Arrays->SpareADC3 = ATD1DR3; 00210 Arrays->SpareADC4 = ATD1DR4; 00211 Arrays->SpareADC5 = ATD1DR5; 00212 Arrays->SpareADC6 = ATD1DR6; 00213 Arrays->SpareADC7 = ATD1DR7; 00214 } 00215 00216 00225 void sampleLoopADC(ADCArray *Arrays){ 00226 // get the address of the ADC array 00227 unsigned short addr = (unsigned short)Arrays; 00228 00229 //sendUS(addr); 00230 unsigned char loop; 00231 /* (value of((address of ADCArrays struct) + (offset to start of bank(0 or half struct length)) + (offset to particular ADC (loopcounter * 4)) + (offset to correct element(0 or 2)))) = 00232 * (value of((address of ARRAY block) + (loop counter * 2))) */ 00233 00234 for(loop=0;loop<16;loop += 2){ 00235 /* Do the first block */ 00236 DVUSP(addr + loop) = DVUSP(ATD0_BASE + loop); 00237 00238 /* Do the second block */ 00239 DVUSP(addr + 16 + loop) = DVUSP(ATD1_BASE + loop); 00241 } 00242 } 00243 00244 00245 /* @brief Read ADCs with memcpy() 00246 * 00247 * Read ADCs into the correct bank using two fixed calls to memcpy() 00248 * 00249 * @author Fred Cooke 00250 * 00251 * @param Arrays a pointer to an ADCArray struct to store ADC values in. 00252 * 00253 * @warning this will corrupt your comms if you use it... don't use it 00254 * @bug this will corrupt your comms if you use it... don't use it 00255 * 00256 void sampleBlockADC(ADCArray *Arrays){ 00257 memcpy(Arrays, (void*)ATD0_BASE, 16); 00258 memcpy(Arrays+16, (void*)ATD1_BASE, 16); 00259 }*/ 00260 00261 00270 void sleep(unsigned short ms){ 00271 unsigned short j, k; 00272 for(j=0;j<ms;j++){ 00273 for(k=0;k<5714;k++){ 00274 } 00275 } 00276 } 00277 00278 00289 void sleepMicro(unsigned short us){ 00290 unsigned short j, k; 00291 for(j=0;j<us;j++){ 00292 for(k=0;k<6;k++){ 00293 } 00294 } 00295 } 00296 00297 00309 unsigned char checksum(unsigned char *block, unsigned short length){ 00310 unsigned char sum = 0; 00311 while (length-- > 0){ 00312 sum += *block++; 00313 } 00314 return sum; 00315 } 00316 00317 00329 unsigned short stringCopy(unsigned char* dest, unsigned char* source){ 00330 short length = -1; 00331 do { 00332 *dest++ = *source++; 00333 length++; 00334 } while(*(source-1) != 0); 00335 return (unsigned short) length; 00336 } 00337 00343 unsigned short compare(unsigned char* original, unsigned char* toCheck, unsigned short length){ 00344 unsigned short i; 00345 for(i=0;i<length;i++){ 00346 if(original[i] != toCheck[i]){ 00347 return i + 1; // zero = success 00348 } 00349 } 00350 return 0; 00351 }