Table access functions. More...
#include "inc/freeEMS.h"
#include "inc/commsISRs.h"
#include "inc/tableLookup.h"
Go to the source code of this file.
Defines | |
#define | TABLELOOKUP_C |
Functions | |
unsigned short | lookupPagedMainTableCellValue (mainTable *Table, unsigned short realRPM, unsigned short realLoad, unsigned char RAMPage) |
Main table read function. | |
unsigned short | lookupTwoDTableUS (twoDTableUS *Table, unsigned short Value) |
Two D table read function. | |
unsigned short | setAxisValue (unsigned short index, unsigned short value, unsigned short axis[], unsigned short length, unsigned short errorBase) |
Set an axis value. | |
unsigned short | setPagedMainTableCellValue (unsigned char RPageValue, mainTable *Table, unsigned short RPMIndex, unsigned short LoadIndex, unsigned short cellValue) |
Set a main table cell value. | |
unsigned short | setPagedMainTableRPMValue (unsigned char RPageValue, mainTable *Table, unsigned short RPMIndex, unsigned short RPMValue) |
Set an RPM axis value. | |
unsigned short | setPagedMainTableLoadValue (unsigned char RPageValue, mainTable *Table, unsigned short LoadIndex, unsigned short LoadValue) |
Set a load axis value. | |
unsigned short | setPagedTwoDTableCellValue (unsigned char RPageValue, twoDTableUS *Table, unsigned short cellIndex, unsigned short cellValue) |
Set a two D table cell value. | |
unsigned short | setPagedTwoDTableAxisValue (unsigned char RPageValue, twoDTableUS *Table, unsigned short axisIndex, unsigned short axisValue) |
Set a two D axis value. | |
unsigned short | validateMainTable (mainTable *Table) |
Validate a main table. | |
unsigned short | validateTwoDTable (twoDTableUS *Table) |
Validate a two D table. |
Table access functions.
Functions for writing to and reading from all of the different table types.
Definition in file tableLookup.c.
#define TABLELOOKUP_C |
Definition at line 37 of file tableLookup.c.
unsigned short lookupPagedMainTableCellValue | ( | mainTable * | Table, | |
unsigned short | realRPM, | |||
unsigned short | realLoad, | |||
unsigned char | RAMPage | |||
) |
Main table read function.
Looks up a value from a main table using interpolation.
The process :
Take a table with two movable axis sets and two axis lengths, loop to find which pairs of axis values and indexs we are between, interpolate two pairs down to two values, interpolate two values down to one value.
Table size :
To reduce the table size from 19x24 to something smaller, simply reduce the RPMLength and LoadLength fields to lower values. Increasing the size of either axis is not currently possible.
Values outside the table :
Given that the axis lists are in order, a data point outside the table will give the value adjacent to it, and one outside one of the four corners will give the corner value. This is a clean and reasonable behaviour in my opinion.
Reminder : X/RPM is horizontal, Y/Load is vertical
Table | is a pointer to the table to read from. | |
realRPM | is the current RPM for which a table value is required. | |
realLoad | is the current load for which a table value is required. | |
RAMPage | is the RAM page that the table is stored in. |
Definition at line 113 of file tableLookup.c.
References mainTable::Load, mainTable::LoadLength, RPAGE, mainTable::RPM, mainTable::RPMLength, and mainTable::Table.
Referenced by generateDerivedVars().
00113 { 00114 00115 /* Save the RPAGE value for restoration and switch pages. */ 00116 unsigned char oldRPage = RPAGE; 00117 RPAGE = RAMPage; 00118 00119 /* Find the bounding axis values and indices for RPM */ 00120 unsigned char lowRPMIndex = 0; 00121 unsigned char highRPMIndex = Table->RPMLength - 1; 00122 /* If never set in the loop, low value will equal high value and will be on the edge of the map */ 00123 unsigned short lowRPMValue = Table->RPM[0]; 00124 unsigned short highRPMValue = Table->RPM[Table->RPMLength -1]; 00125 00126 unsigned char RPMIndex; 00127 for(RPMIndex=0;RPMIndex<Table->RPMLength;RPMIndex++){ 00128 if(Table->RPM[RPMIndex] < realRPM){ 00129 lowRPMValue = Table->RPM[RPMIndex]; 00130 lowRPMIndex = RPMIndex; 00131 }else if(Table->RPM[RPMIndex] > realRPM){ 00132 highRPMValue = Table->RPM[RPMIndex]; 00133 highRPMIndex = RPMIndex; 00134 break; 00135 }else if(Table->RPM[RPMIndex] == realRPM){ 00136 lowRPMValue = Table->RPM[RPMIndex]; 00137 highRPMValue = Table->RPM[RPMIndex]; 00138 lowRPMIndex = RPMIndex; 00139 highRPMIndex = RPMIndex; 00140 break; 00141 } 00142 } 00143 00144 /* Find the bounding cell values and indices for Load */ 00145 unsigned char lowLoadIndex = 0; 00146 unsigned char highLoadIndex = Table->LoadLength -1; 00147 /* If never set in the loop, low value will equal high value and will be on the edge of the map */ 00148 unsigned short lowLoadValue = Table->Load[0]; 00149 unsigned short highLoadValue = Table->Load[Table->LoadLength -1]; 00150 00151 unsigned char LoadIndex; 00152 for(LoadIndex=0;LoadIndex<Table->LoadLength;LoadIndex++){ 00153 if(Table->Load[LoadIndex] < realLoad){ 00154 lowLoadValue = Table->Load[LoadIndex]; 00155 lowLoadIndex = LoadIndex; 00156 }else if(Table->Load[LoadIndex] > realLoad){ 00157 highLoadValue = Table->Load[LoadIndex]; 00158 highLoadIndex = LoadIndex; 00159 break; 00160 }else if(Table->Load[LoadIndex] == realLoad){ 00161 lowLoadValue = Table->Load[LoadIndex]; 00162 highLoadValue = Table->Load[LoadIndex]; 00163 lowLoadIndex = LoadIndex; 00164 highLoadIndex = LoadIndex; 00165 break; 00166 } 00167 } 00168 00169 /* Obtain the four corners surrounding the spot of interest */ 00170 unsigned short lowRPMLowLoad = Table->Table[(Table->LoadLength * lowRPMIndex) + lowLoadIndex]; 00171 unsigned short lowRPMHighLoad = Table->Table[(Table->LoadLength * lowRPMIndex) + highLoadIndex]; 00172 unsigned short highRPMLowLoad = Table->Table[(Table->LoadLength * highRPMIndex) + lowLoadIndex]; 00173 unsigned short highRPMHighLoad = Table->Table[(Table->LoadLength * highRPMIndex) + highLoadIndex]; 00174 00175 /* Restore the ram page before doing the math */ 00176 RPAGE = oldRPage; 00177 00178 /* Find the two side values to interpolate between by interpolation */ 00179 unsigned short lowRPMIntLoad = lowRPMLowLoad + (((signed long)((signed long)lowRPMHighLoad - lowRPMLowLoad) * (realLoad - lowLoadValue))/ (highLoadValue - lowLoadValue)); 00180 unsigned short highRPMIntLoad = highRPMLowLoad + (((signed long)((signed long)highRPMHighLoad - highRPMLowLoad) * (realLoad - lowLoadValue))/ (highLoadValue - lowLoadValue)); 00181 00182 /* Interpolate between the two side values and return the result */ 00183 return lowRPMIntLoad + (((signed long)((signed long)highRPMIntLoad - lowRPMIntLoad) * (realRPM - lowRPMValue))/ (highRPMValue - lowRPMValue)); 00184 }
unsigned short lookupTwoDTableUS | ( | twoDTableUS * | Table, | |
unsigned short | Value | |||
) |
Two D table read function.
Looks up a value from a two D table using interpolation.
Table | is a pointer to the table to read from. | |
Value | is the position value used to lookup the return value. |
Definition at line 198 of file tableLookup.c.
References twoDTableUS::Axis, and twoDTableUS::Values.
Referenced by generateDerivedVars().
00198 { 00199 00200 /* Find the bounding axis indices, axis values and lookup values */ 00201 unsigned char lowIndex = 0; 00202 unsigned char highIndex = 15; 00203 /* If never set in the loop, low value will equal high value and will be on the edge of the map */ 00204 unsigned short lowAxisValue = Table->Axis[0]; 00205 unsigned short highAxisValue = Table->Axis[15]; 00206 unsigned short lowLookupValue = Table->Values[0]; 00207 unsigned short highLookupValue = Table->Values[15]; 00208 00209 unsigned char Index; 00210 for(Index=0;Index<16;Index++){ 00211 if(Table->Axis[Index] < Value){ 00212 lowIndex = Index; 00213 lowAxisValue = Table->Axis[Index]; 00214 lowLookupValue = Table->Values[Index]; 00215 }else if(Table->Axis[Index] > Value){ 00216 highIndex = Index; 00217 highAxisValue = Table->Axis[Index]; 00218 highLookupValue = Table->Values[Index]; 00219 break; 00220 }else if(Table->Axis[Index] == Value){ 00221 return Table->Values[Index]; // If right on, just return the value 00222 } 00223 } 00224 00225 00226 /* Interpolate and return the value */ 00227 return lowLookupValue + (((signed long)((signed long)highLookupValue - lowLookupValue) * (Value - lowAxisValue))/ (highAxisValue - lowAxisValue)); 00228 }
unsigned short setAxisValue | ( | unsigned short | index, | |
unsigned short | value, | |||
unsigned short | axis[], | |||
unsigned short | length, | |||
unsigned short | errorBase | |||
) |
Set an axis value.
Sets the value of an axis cell in a table. This is used when configuring a table via a communication interface.
index | The position of the axis cell to adjust. | |
value | The value to set the axis cell to. | |
axis | A pointer to the axis array to adjust. | |
length | The length of the axis array. | |
errorBase | The base value to add error code offsets to. |
Definition at line 246 of file tableLookup.c.
References invalidAxisIndex, and invalidAxisOrder.
Referenced by setPagedMainTableLoadValue(), setPagedMainTableRPMValue(), and setPagedTwoDTableAxisValue().
00246 { 00247 if(index >= length){ 00248 return errorBase + invalidAxisIndex; 00249 }else{ 00250 if(index > 0){ 00251 /* Ensure value isn't lower than the one below */ 00252 if(axis[index - 1] > value){ 00253 return errorBase + invalidAxisOrder; 00254 } 00255 } 00256 if(index < (length -1)){ 00257 /* Ensure value isn't higher than the one above */ 00258 if(value > axis[index + 1]){ 00259 return errorBase + invalidAxisOrder; 00260 } 00261 } 00262 } 00263 00264 /* If we got this far all is well, set the value */ 00265 axis[index] = value; 00266 return 0; 00267 }
unsigned short setPagedMainTableCellValue | ( | unsigned char | RPageValue, | |
mainTable * | Table, | |||
unsigned short | RPMIndex, | |||
unsigned short | LoadIndex, | |||
unsigned short | cellValue | |||
) |
Set a main table cell value.
Sets the value of a cell in a main table. This is used when configuring a table via a communication interface.
RPageValue | The page of RAM that the table is in. | |
Table | A pointer to the table to adjust. | |
RPMIndex | The RPM position of the cell to adjust. | |
LoadIndex | The load position of the cell to adjust. | |
cellValue | The value to set the cell to. |
Definition at line 285 of file tableLookup.c.
References invalidMainTableLoadIndex, invalidMainTableRPMIndex, mainTable::LoadLength, RPAGE, and mainTable::Table.
Referenced by decodePacketAndRespond().
00285 { 00286 unsigned char oldRPage = RPAGE; 00287 unsigned short errorID = 0; 00288 RPAGE = RPageValue; 00289 if(RPMIndex < Table->RPMLength){ 00290 if(LoadIndex < Table->LoadLength){ 00291 Table->Table[(Table->LoadLength * RPMIndex) + LoadIndex] = cellValue; 00292 }else{ 00293 errorID = invalidMainTableLoadIndex; 00294 } 00295 }else{ 00296 errorID = invalidMainTableRPMIndex; 00297 } 00298 RPAGE = oldRPage; 00299 return errorID; 00300 }
unsigned short setPagedMainTableLoadValue | ( | unsigned char | RPageValue, | |
mainTable * | Table, | |||
unsigned short | LoadIndex, | |||
unsigned short | LoadValue | |||
) |
Set a load axis value.
Sets the value of a load axis cell in a table. This is used when configuring the table via a comms interface.
RPageValue | The page of RAM that the table is in. | |
Table | is a pointer to the table to adjust. | |
LoadIndex | The load position of the cell to adjust. | |
LoadValue | The value to set the load axis cell to. |
Definition at line 340 of file tableLookup.c.
References errorBaseMainTableLoad, mainTable::Load, mainTable::LoadLength, RPAGE, and setAxisValue().
Referenced by decodePacketAndRespond().
00340 { 00341 unsigned char oldRPage = RPAGE; 00342 RPAGE = RPageValue; 00343 unsigned short errorID = setAxisValue(LoadIndex, LoadValue, Table->Load, Table->LoadLength, errorBaseMainTableLoad); 00344 RPAGE = oldRPage; 00345 return errorID; 00346 }
unsigned short setPagedMainTableRPMValue | ( | unsigned char | RPageValue, | |
mainTable * | Table, | |||
unsigned short | RPMIndex, | |||
unsigned short | RPMValue | |||
) |
Set an RPM axis value.
Sets the value of an RPM axis cell in a table. This is used when configuring the table via a comms interface.
RPageValue | The page of RAM that the table is in. | |
Table | is a pointer to the table to adjust. | |
RPMIndex | The RPM position of the cell to adjust. | |
RPMValue | The value to set the RPM axis cell to. |
Definition at line 317 of file tableLookup.c.
References errorBaseMainTableRPM, RPAGE, mainTable::RPM, mainTable::RPMLength, and setAxisValue().
Referenced by decodePacketAndRespond().
00317 { 00318 unsigned char oldRPage = RPAGE; 00319 RPAGE = RPageValue; 00320 unsigned short errorID = setAxisValue(RPMIndex, RPMValue, Table->RPM, Table->RPMLength, errorBaseMainTableRPM); 00321 RPAGE = oldRPage; 00322 return errorID; 00323 }
unsigned short setPagedTwoDTableAxisValue | ( | unsigned char | RPageValue, | |
twoDTableUS * | Table, | |||
unsigned short | axisIndex, | |||
unsigned short | axisValue | |||
) |
Set a two D axis value.
Sets the value of an axis cell in a table. This is used when configuring the table via a comms interface.
RPageValue | The page of RAM that the table is in. | |
Table | is a pointer to the table to adjust. | |
axisIndex | The position of the axis cell to adjust. | |
axisValue | The value to set the axis cell to. |
Definition at line 390 of file tableLookup.c.
References twoDTableUS::Axis, errorBaseTwoDTableAxis, RPAGE, and setAxisValue().
Referenced by decodePacketAndRespond().
00390 { 00391 unsigned char oldRPage = RPAGE; 00392 RPAGE = RPageValue; 00393 unsigned short errorID = setAxisValue(axisIndex, axisValue, Table->Axis, 16, errorBaseTwoDTableAxis); 00394 RPAGE = oldRPage; 00395 return errorID; 00396 }
unsigned short setPagedTwoDTableCellValue | ( | unsigned char | RPageValue, | |
twoDTableUS * | Table, | |||
unsigned short | cellIndex, | |||
unsigned short | cellValue | |||
) |
Set a two D table cell value.
Sets the value of a cell in a two D table. This is used when configuring the table via a comms interface.
RPageValue | The page of RAM that the table is in. | |
Table | is a pointer to the table to adjust. | |
cellIndex | The position of the cell to adjust. | |
cellValue | The value to set the cell to. |
Definition at line 363 of file tableLookup.c.
References invalidTwoDTableIndex, RPAGE, and twoDTableUS::Values.
Referenced by decodePacketAndRespond().
00363 { 00364 if(cellIndex > 15){ 00365 return invalidTwoDTableIndex; 00366 }else{ 00367 unsigned char oldRPage = RPAGE; 00368 RPAGE = RPageValue; 00369 Table->Values[cellIndex] = cellValue; 00370 RPAGE = oldRPage; 00371 return 0; 00372 } 00373 }
unsigned short validateMainTable | ( | mainTable * | Table | ) |
Validate a main table.
Check that the configuration of the table is valid. Assumes pages are correctly set.
Table | is a pointer to the table to be validated. |
Definition at line 410 of file tableLookup.c.
References invalidMainTableLoadLength, invalidMainTableLoadOrder, invalidMainTableMainLength, invalidMainTableRPMLength, invalidMainTableRPMOrder, mainTable::Load, mainTable::LoadLength, MAINTABLE_MAX_LOAD_LENGTH, MAINTABLE_MAX_MAIN_LENGTH, MAINTABLE_MAX_RPM_LENGTH, mainTable::RPM, and mainTable::RPMLength.
Referenced by decodePacketAndRespond().
00410 { 00411 /* If required and only if required extend this to take r and f pages and check */ 00412 /* any main table, not just a freshly received untrusted ones in linear space */ 00413 00414 if(Table->RPMLength > MAINTABLE_MAX_RPM_LENGTH){ 00415 return invalidMainTableRPMLength; 00416 }else if(Table->LoadLength > MAINTABLE_MAX_LOAD_LENGTH){ 00417 return invalidMainTableLoadLength; 00418 }else if((Table->RPMLength * Table->LoadLength) > MAINTABLE_MAX_MAIN_LENGTH){ 00419 return invalidMainTableMainLength; 00420 }else{ 00421 /* Check the order of the RPM axis */ 00422 unsigned char i; 00423 for(i=0;i<(Table->RPMLength - 1);i++){ 00424 if(Table->RPM[i] > Table->RPM[i+1]){ 00425 return invalidMainTableRPMOrder; 00426 } 00427 } 00428 /* Check the order of the Load axis */ 00429 unsigned char j; 00430 for(j=0;j<(Table->LoadLength - 1);j++){ 00431 if(Table->Load[j] > Table->Load[j+1]){ 00432 return invalidMainTableLoadOrder; 00433 } 00434 } 00435 /* If we made it this far all is well */ 00436 return 0; 00437 } 00438 }
unsigned short validateTwoDTable | ( | twoDTableUS * | Table | ) |
Validate a two D table.
Check that the order of the axis values is correct and therefore that the table is valid too.
Table | is a pointer to the table to be validated. |
Definition at line 452 of file tableLookup.c.
References twoDTableUS::Axis, invalidTwoDTableAxisOrder, and TWODTABLEUS_LENGTH.
Referenced by decodePacketAndRespond().
00452 { 00453 /* Check the order of the axis */ 00454 unsigned char i; 00455 for(i=0;i<(TWODTABLEUS_LENGTH - 1);i++){ 00456 if(Table->Axis[i] > Table->Axis[i+1]){ 00457 return invalidTwoDTableAxisOrder; 00458 } 00459 } 00460 return 0; 00461 }