Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00022
00023
00024
00025
00026 #ifndef _icl_hardware_can_CANMESSAGEHELPER_H
00027 #define _icl_hardware_can_CANMESSAGEHELPER_H
00028
00029 #include "icl_core/BaseTypes.h"
00030 #include "icl_hardware_can/tCanMessage.h"
00031 #include "icl_hardware_can/tCanMatrixParser.h"
00032
00033 namespace icl_hardware {
00034 namespace can {
00035
00036
00037
00038
00039 void constructCanMessageData(unsigned char *_data, int value, const unsigned int start_bit, const unsigned int signal_length, bool little_endian)
00040 {
00041 assert(start_bit > 0);
00042 assert(signal_length > 0);
00043 assert((start_bit-1)+signal_length <= 64);
00044
00045 int64_t data = static_cast<int64_t>(value);
00046 int offset = 0;
00047
00048 if (little_endian)
00049 {
00050 unsigned int number_of_bytes = static_cast<unsigned int>(((signal_length-1)/8))+1;
00051 int64_t tmp_data = 0;
00052
00053
00054 for (unsigned int i= 0; i < number_of_bytes; ++i)
00055 {
00056 tmp_data <<= 8;
00057 tmp_data |= (data & 0xFF);
00058 data >>= 8;
00059 }
00060 data = tmp_data;
00061
00062 if (signal_length < 8)
00063 {
00064 offset =2*(start_bit%8 == 0? 1:start_bit%8)-8;
00065 }
00066 }
00067
00068
00069 data <<= 64 - (start_bit-offset) - signal_length;
00070
00071
00072 for (int i=7; i >= 0; --i)
00073 {
00074 _data[i] = static_cast<unsigned char>(data & 0xFF);
00075 data >>= 8;
00076 }
00077 }
00078
00079 double parseCanMessage(const tCanMessage &message, const unsigned int start_bit, const unsigned int signal_length, const bool little_endian, const bool signedness, const double factor, const double offset)
00080 {
00081
00082
00083
00084
00085 uint32_t rawValue = 0;
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 uint8_t bit_len = signal_length;
00116 uint8_t start_offset = (start_bit-1) & 7;
00117 uint8_t start_byte = (start_bit-1) / 8;
00118 uint8_t data;
00119 int8_t work_byte;
00120 uint8_t shift;
00121
00122
00123
00124 if(little_endian == false) {
00125 uint8_t end_byte = start_byte + (7 + bit_len - start_offset - 1)/8;
00126 uint8_t end_offset = (start_offset - bit_len + 1) & 7;
00127
00128
00129 for(work_byte = start_byte; work_byte <= end_byte; work_byte++) {
00130
00131 data = message.data[work_byte];
00132
00133
00134 if(work_byte == start_byte && start_offset != 7) {
00135
00136 data &= (uint8_t)~0 >> (7 - start_offset);
00137 shift = start_offset + 1;
00138 } else {
00139 shift = 8;
00140 }
00141 if(work_byte == end_byte && end_offset != 0) {
00142
00143 data >>= end_offset;
00144 shift -= end_offset;
00145 }
00146
00147
00148 rawValue <<= shift;
00149 rawValue |= data;
00150 }
00151 } else {
00152
00153 uint8_t end_byte = start_byte + (bit_len + start_offset - 1)/8;
00154 uint8_t end_offset = (start_offset + bit_len - 1) & 7;
00155
00156 for(work_byte = end_byte; work_byte >= start_byte; work_byte--) {
00157 data = message.data[work_byte];
00158 if(work_byte == end_byte && end_offset != 7) {
00159 data &= (uint8_t)~0 >> (7 - end_offset);
00160 shift = end_offset + 1;
00161 } else {
00162 shift = 8;
00163 }
00164 if(work_byte == start_byte && start_offset != 0) {
00165 data >>= start_offset;
00166 shift -= start_offset;
00167 }
00168 rawValue <<= shift;
00169 rawValue |= data;
00170 }
00171 }
00172
00173 double physicalValue;
00174
00175
00176 if(signedness && (bit_len < 32)) {
00177 int32_t m = 1<< (bit_len-1);
00178 rawValue = ((int32_t)rawValue ^ m) - m;
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 if(signedness) {
00193 physicalValue = (double)(int32_t)rawValue
00194 * factor + offset;
00195 } else {
00196 physicalValue = (double) rawValue
00197 * factor + offset;
00198 }
00199 return physicalValue;
00200 }
00201
00202 template <typename T>
00203 static bool parseCanMessage(const tCanMessage &message,
00204 const unsigned int start_bit,
00205 const unsigned int signal_length,
00206 const T factor,
00207 const T offset,
00208 const T lower_border,
00209 const T upper_border,
00210 const bool little_endian,
00211 const bool signedness,
00212 T &data)
00213 {
00214 data = static_cast<T>(parseCanMessage(message, start_bit, signal_length, little_endian, signedness, factor, offset));
00215 if ( (data < lower_border) || (data > upper_border) )
00216 {
00217 return false;
00218 }
00219 return true;
00220 }
00221
00222 template <typename T>
00223 static bool parseCanMessage(const tCanMessage &message,
00224 const CanMatrixElement &matrix,
00225 T &data)
00226 {
00227 data = static_cast<T>(parseCanMessage(message, matrix.start_bit, matrix.signal_length, matrix.little_endian, matrix.signedness, matrix.conversion, matrix.offset));
00228 if ( (data < matrix.lower_border) || (data > matrix.upper_border) )
00229 {
00230 return false;
00231 }
00232 return true;
00233 }
00234
00235 }
00236 }
00237
00238 #endif // _icl_hardware_can_CANMESSAGEHELPER_H