Various minor optimisations - Replace custom divide operation with div
This commit is contained in:
parent
781c6b72dc
commit
5870a47558
|
@ -89,15 +89,15 @@ void sendValues(int length)
|
|||
response[3] = 0x00; //baro
|
||||
response[4] = currentStatus.MAP; //map
|
||||
response[5] = 0x00; //mat
|
||||
response[6] = 0x00; //Coolant
|
||||
response[6] = 0x00; //Coolant ADC
|
||||
response[7] = currentStatus.tpsADC; //TPS (Raw 0-255)
|
||||
response[8] = 0x00; //battery voltage
|
||||
response[9] = 0x00; //O2
|
||||
response[10] = 0x00; //Exhaust gas correction (%)
|
||||
response[11] = 0x00; //Air Correction (%)
|
||||
response[12] = 0x00; //Warmup enrichment (%)
|
||||
response[13] = (currentStatus.RPM / 100); //rpm / 100
|
||||
response[14] = (currentStatus.PW / 100); //Pulsewidth 1 divided by 10 (in ms)
|
||||
response[13] = div(currentStatus.RPM, 100).quot; //rpm / 100
|
||||
response[14] = div(currentStatus.PW, 100).quot; //Pulsewidth 1 divided by 10 (in ms)
|
||||
response[15] = 0x00; //acceleration enrichment (ms)
|
||||
response[16] = 0x00; //Barometer correction (%)
|
||||
response[17] = 0x00; //Total GammaE (%)
|
||||
|
|
|
@ -12,8 +12,8 @@ byte correctionsTotal()
|
|||
|
||||
byte correctionWUE()
|
||||
{
|
||||
//Not yet implemented
|
||||
return 100;
|
||||
//Possibly reduce the frequency this runs at (Costs about 50 loops per second)
|
||||
return 100 + table2D_getValue(WUETable, currentStatus.coolant);
|
||||
}
|
||||
|
||||
byte correctionASE()
|
||||
|
@ -38,8 +38,9 @@ Calculates the % change of the throttle over time (%/second) and performs a look
|
|||
|
||||
byte correctionAccel()
|
||||
{
|
||||
int rateOfChange = (1000000 / (currentLoopTime - previousLoopTime)) * (currentStatus.TPS - currentStatus.TPSlast); //This is the % per second that the TPS has moved
|
||||
currentStatus.tpsDOT = rateOfChange / 10;
|
||||
int rateOfChange = div(1000000, (currentLoopTime - previousLoopTime)).quot * (currentStatus.TPS - currentStatus.TPSlast); //This is the % per second that the TPS has moved
|
||||
//int rateOfChange = div( (1000000 * (currentStatus.TPS - currentStatus.TPSlast)), (currentLoopTime - previousLoopTime)).quot; //This is the % per second that the TPS has moved
|
||||
currentStatus.tpsDOT = div(rateOfChange, 10).quot;
|
||||
|
||||
if (rateOfChange > configPage1.tpsThresh)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,10 @@ struct statuses {
|
|||
byte tpsDOT;
|
||||
byte VE;
|
||||
byte O2;
|
||||
byte coolant;
|
||||
byte coolantADC;
|
||||
byte IAT;
|
||||
byte iatADC;
|
||||
byte advance;
|
||||
volatile byte squirt;
|
||||
byte engine;
|
||||
|
|
160
math.h
160
math.h
|
@ -1,163 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Ambroz Bizjak
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef AMBRO_AVR_ASM_DIV_32_32_LARGE
|
||||
#define AMBRO_AVR_ASM_DIV_32_32_LARGE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DIVIDE_32_32_ITER_0_7(i) \
|
||||
" lsl %D[n]\n" \
|
||||
" rol __tmp_reg__\n" \
|
||||
" cp __tmp_reg__,%A[d]\n" \
|
||||
" cpc __zero_reg__,%B[d]\n" \
|
||||
" cpc __zero_reg__,%C[d]\n" \
|
||||
" cpc __zero_reg__,%D[d]\n" \
|
||||
" brcs zero_bit_" #i "__%=\n" \
|
||||
" sub __tmp_reg__,%A[d]\n" \
|
||||
" ori %D[q],1<<(7-" #i ")\n" \
|
||||
"zero_bit_" #i "__%=:\n"
|
||||
|
||||
#define DIVIDE_32_32_ITER_8_15(i) \
|
||||
" lsl %C[n]\n" \
|
||||
" rol __tmp_reg__\n" \
|
||||
" rol %D[n]\n" \
|
||||
" cp __tmp_reg__,%A[d]\n" \
|
||||
" cpc %D[n],%B[d]\n" \
|
||||
" cpc __zero_reg__,%C[d]\n" \
|
||||
" cpc __zero_reg__,%D[d]\n" \
|
||||
" brcs zero_bit_" #i "__%=\n" \
|
||||
" sub __tmp_reg__,%A[d]\n" \
|
||||
" sbc %D[n],%B[d]\n" \
|
||||
" ori %C[q],1<<(15-" #i ")\n" \
|
||||
"zero_bit_" #i "__%=:\n"
|
||||
|
||||
#define DIVIDE_32_32_ITER_16_23(i) \
|
||||
" lsl %B[n]\n" \
|
||||
" rol __tmp_reg__\n" \
|
||||
" rol %D[n]\n" \
|
||||
" rol %C[n]\n" \
|
||||
" cp __tmp_reg__,%A[d]\n" \
|
||||
" cpc %D[n],%B[d]\n" \
|
||||
" cpc %C[n],%C[d]\n" \
|
||||
" cpc __zero_reg__,%D[d]\n" \
|
||||
" brcs zero_bit_" #i "__%=\n" \
|
||||
" sub __tmp_reg__,%A[d]\n" \
|
||||
" sbc %D[n],%B[d]\n" \
|
||||
" sbc %C[n],%C[d]\n" \
|
||||
" ori %B[q],1<<(23-" #i ")\n" \
|
||||
"zero_bit_" #i "__%=:\n"
|
||||
|
||||
#define DIVIDE_32_32_ITER_24_30(i) \
|
||||
" lsl %A[n]\n" \
|
||||
" rol __tmp_reg__\n" \
|
||||
" rol %D[n]\n" \
|
||||
" rol %C[n]\n" \
|
||||
" rol %B[n]\n" \
|
||||
" cp __tmp_reg__,%A[d]\n" \
|
||||
" cpc %D[n],%B[d]\n" \
|
||||
" cpc %C[n],%C[d]\n" \
|
||||
" cpc %B[n],%D[d]\n" \
|
||||
" brcs zero_bit_" #i "__%=\n" \
|
||||
" sub __tmp_reg__,%A[d]\n" \
|
||||
" sbc %D[n],%B[d]\n" \
|
||||
" sbc %C[n],%C[d]\n" \
|
||||
" sbc %B[n],%D[d]\n" \
|
||||
" ori %A[q],1<<(31-" #i ")\n" \
|
||||
"zero_bit_" #i "__%=:\n"
|
||||
|
||||
/**
|
||||
* Division uint32_t/uint32_t.
|
||||
*
|
||||
* Cycles in worst case: 384
|
||||
* = 5 + (8 * 9) + (8 * 11) + (8 * 13) + (7 * 15) + 10
|
||||
*/
|
||||
static inline uint32_t fastDivide32(uint32_t n, uint32_t d)
|
||||
{
|
||||
uint32_t q;
|
||||
|
||||
asm(
|
||||
" clr %A[q]\n"
|
||||
" clr %B[q]\n"
|
||||
" clr %C[q]\n"
|
||||
" clr %D[q]\n"
|
||||
" clr __tmp_reg__\n"
|
||||
DIVIDE_32_32_ITER_0_7(0)
|
||||
DIVIDE_32_32_ITER_0_7(1)
|
||||
DIVIDE_32_32_ITER_0_7(2)
|
||||
DIVIDE_32_32_ITER_0_7(3)
|
||||
DIVIDE_32_32_ITER_0_7(4)
|
||||
DIVIDE_32_32_ITER_0_7(5)
|
||||
DIVIDE_32_32_ITER_0_7(6)
|
||||
DIVIDE_32_32_ITER_0_7(7)
|
||||
DIVIDE_32_32_ITER_8_15(8)
|
||||
DIVIDE_32_32_ITER_8_15(9)
|
||||
DIVIDE_32_32_ITER_8_15(10)
|
||||
DIVIDE_32_32_ITER_8_15(11)
|
||||
DIVIDE_32_32_ITER_8_15(12)
|
||||
DIVIDE_32_32_ITER_8_15(13)
|
||||
DIVIDE_32_32_ITER_8_15(14)
|
||||
DIVIDE_32_32_ITER_8_15(15)
|
||||
DIVIDE_32_32_ITER_16_23(16)
|
||||
DIVIDE_32_32_ITER_16_23(17)
|
||||
DIVIDE_32_32_ITER_16_23(18)
|
||||
DIVIDE_32_32_ITER_16_23(19)
|
||||
DIVIDE_32_32_ITER_16_23(20)
|
||||
DIVIDE_32_32_ITER_16_23(21)
|
||||
DIVIDE_32_32_ITER_16_23(22)
|
||||
DIVIDE_32_32_ITER_16_23(23)
|
||||
DIVIDE_32_32_ITER_24_30(24)
|
||||
DIVIDE_32_32_ITER_24_30(25)
|
||||
DIVIDE_32_32_ITER_24_30(26)
|
||||
DIVIDE_32_32_ITER_24_30(27)
|
||||
DIVIDE_32_32_ITER_24_30(28)
|
||||
DIVIDE_32_32_ITER_24_30(29)
|
||||
DIVIDE_32_32_ITER_24_30(30)
|
||||
" lsl %A[n]\n"
|
||||
" rol __tmp_reg__\n"
|
||||
" rol %D[n]\n"
|
||||
" rol %C[n]\n"
|
||||
" rol %B[n]\n"
|
||||
" cp __tmp_reg__,%A[d]\n"
|
||||
" cpc %D[n],%B[d]\n"
|
||||
" cpc %C[n],%C[d]\n"
|
||||
" cpc %B[n],%D[d]\n"
|
||||
" sbci %A[q],-1\n"
|
||||
|
||||
: [q] "=&a" (q),
|
||||
[n] "=&r" (n)
|
||||
: "[n]" (n),
|
||||
[d] "r" (d)
|
||||
);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
//Replace the standard arduino map() function to use the above
|
||||
//Replace the standard arduino map() function to use the div function instead
|
||||
long fastMap(long x, long in_min, long in_max, long out_min, long out_max)
|
||||
{
|
||||
return fastDivide32( ((x - in_min) * (out_max - out_min)) , ((in_max - in_min) + out_min) );
|
||||
return div( ((x - in_min) * (out_max - out_min)) , ((in_max - in_min) + out_min) ).quot;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -208,7 +208,7 @@ void loop()
|
|||
noInterrupts();
|
||||
unsigned long revolutionTime = (toothOneTime - toothOneMinusOneTime); //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that)
|
||||
interrupts();
|
||||
currentStatus.RPM = fastDivide32(US_IN_MINUTE, revolutionTime); //Calc RPM based on last full revolution time
|
||||
currentStatus.RPM = div(US_IN_MINUTE, revolutionTime).quot; //Calc RPM based on last full revolution time
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -222,17 +222,18 @@ void loop()
|
|||
//Uncomment the following for testing
|
||||
/*
|
||||
currentStatus.hasSync = true;
|
||||
currentStatus.TPS = 100;
|
||||
currentStatus.RPM = 5500;
|
||||
*/
|
||||
|
||||
//***SET STATUSES***
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
currentStatus.TPSlast = currentStatus.TPS;
|
||||
currentStatus.MAP = map(analogRead(pinMAP), 0, 1023, 0, 100); //Get the current MAP value
|
||||
currentStatus.tpsADC = map(analogRead(pinTPS), 0, 1023, 0, 255); //Get the current raw TPS ADC value and map it into a byte
|
||||
currentStatus.TPS = map(currentStatus.tpsADC, configPage1.tpsMin, configPage1.tpsMax, 0, 100); //Take the raw TPS ADC value and convert it into a TPS% based on the calibrated values
|
||||
currentStatus.O2 = map(analogRead(pinO2), 0, 1023, 117, 358); //Get the current O2 value. Calibration is from AFR values 7.35 to 22.4, then multiplied by 16 (<< 4). This is the correct calibration for an Innovate Wideband 0v - 5V unit
|
||||
currentStatus.MAP = fastMap(analogRead(pinMAP), 0, 1023, 0, 100); //Get the current MAP value
|
||||
currentStatus.coolant = fastMap(analogRead(pinCLT), 0, 1023, 0, 255); //Get the current raw CLT value
|
||||
currentStatus.iatADC = fastMap(analogRead(pinIAT), 0, 1023, 0, 255); //Get the current raw IAT value
|
||||
currentStatus.tpsADC = fastMap(analogRead(pinTPS), 0, 1023, 0, 255); //Get the current raw TPS ADC value and map it into a byte
|
||||
currentStatus.TPS = fastMap(currentStatus.tpsADC, configPage1.tpsMin, configPage1.tpsMax, 0, 100); //Take the raw TPS ADC value and convert it into a TPS% based on the calibrated values
|
||||
currentStatus.O2 = fastMap(analogRead(pinO2), 0, 1023, 117, 358); //Get the current O2 value. Calibration is from AFR values 7.35 to 22.4, then multiplied by 16 (<< 4). This is the correct calibration for an Innovate Wideband 0v - 5V unit
|
||||
|
||||
//Always check for sync
|
||||
//Main loop runs within this clause
|
||||
|
@ -282,14 +283,14 @@ void loop()
|
|||
if (crankAngle > 360) { crankAngle -= 360; }
|
||||
|
||||
//How fast are we going? Need to know how long (uS) it will take to get from one tooth to the next. We then use that to estimate how far we are between the last tooth and the next one
|
||||
unsigned long timePerDegree = fastDivide32( (toothOneTime - toothOneMinusOneTime), (triggerToothAngle * configPage2.triggerTeeth)); //The time (uS) it is currently taking to move 1 degree (fastDivide version)
|
||||
crankAngle += fastDivide32( (micros() - toothLastToothTime), timePerDegree); //Estimate the number of degrees travelled since the last tooth (fastDivide version)
|
||||
unsigned long timePerDegree = div( (toothOneTime - toothOneMinusOneTime), (triggerToothAngle * configPage2.triggerTeeth)).quot; //The time (uS) it is currently taking to move 1 degree (fastDivide version)
|
||||
crankAngle += div( (micros() - toothLastToothTime), timePerDegree).quot; //Estimate the number of degrees travelled since the last tooth
|
||||
|
||||
//Determine next firing angles
|
||||
int injector1StartAngle = 355 - ( fastDivide32(currentStatus.PW, timePerDegree) ); //This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. I am using 355 as the point at which the injector MUST be closed by. See http://www.extraefi.co.uk/sequential_fuel.html for more detail
|
||||
int injector1StartAngle = 355 - ( div(currentStatus.PW, timePerDegree).quot ); //This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. I am using 355 as the point at which the injector MUST be closed by. See http://www.extraefi.co.uk/sequential_fuel.html for more detail
|
||||
|
||||
if (currentStatus.RPM > ((int)(configPage2.SoftRevLim * 100)) ) { currentStatus.advance -= configPage2.SoftLimRetard; } //Softcut RPM limit (If we're above softcut limit, delay timing by configured number of degrees)
|
||||
int ignition1StartAngle = 360 - currentStatus.advance - (fastDivide32((configPage2.dwellRun*100), timePerDegree) ); // 360 - desired advance angle - number of degrees the dwell will take
|
||||
int ignition1StartAngle = 360 - currentStatus.advance - (div((configPage2.dwellRun*100), timePerDegree).quot ); // 360 - desired advance angle - number of degrees the dwell will take
|
||||
|
||||
|
||||
//Finally calculate the time (uS) until we reach the firing angles and set the schedules
|
||||
|
|
|
@ -182,7 +182,8 @@ int get3DTableValue(struct table3D fromTable, int Y, int X)
|
|||
{ p = ((long)(X - xMinValue) << 8); } //This only occurs if the requested X value was equal to one of the X axis bins
|
||||
else
|
||||
{
|
||||
p = ((long)(X - xMinValue) << 8) / (xMaxValue - xMinValue); } //This is the standard case
|
||||
p = ((long)(X - xMinValue) << 8) / (xMaxValue - xMinValue); //This is the standard case
|
||||
}
|
||||
|
||||
long q;
|
||||
if (yMaxValue == yMinValue)
|
||||
|
|
1
utils.h
1
utils.h
|
@ -31,7 +31,6 @@ int PW(int REQ_FUEL, byte VE, byte MAP, int corrections, int injOpen, byte TPS)
|
|||
//return (REQ_FUEL * (float)(VE/100.0) * (float)(MAP/100.0) * (float)(corrections/100.0) + injOpen);
|
||||
|
||||
//100% float free version, does sacrifice a little bit of accuracy. Accuracy loss is in the order of 0.1ms (100uS)
|
||||
|
||||
int iVE = ((int)VE << 7) / 100;
|
||||
int iMAP = ((int)MAP << 7) / 100;
|
||||
int iCorrections = (corrections << 7) / 100;
|
||||
|
|
Loading…
Reference in New Issue