Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef RMP_HELPER_H
00040 #define RMP_HELPER_H
00041
00042 #include <assert.h>
00043
00044 #include <RmpType.h>
00045
00046 namespace segway
00047 {
00048 static const size_t RMP_CMD_BODY_SIZE = sizeof(uint16_t) + 2 * sizeof(uint32_t);
00049 static const size_t RMP_CMD_HEADER_IDX = 0;
00050 static const size_t RMP_CMD_VAL1_IDX = sizeof(uint16_t);
00051 static const size_t RMP_CMD_VAL2_IDX = sizeof(uint16_t) + sizeof(uint32_t);
00052
00053 static const size_t CRC_TABLE_SIZE = 256;
00054 static const uint16_t CRC_ADJUSTMENT = 0xA001;
00055 static const size_t CRC_SIZE = sizeof(uint16_t);
00056 static const size_t CRC_FEEDBACK_SIZE = sizeof(uint32_t);
00057
00064 inline void ConvertUint16ToBytes(const uint16_t& rData, uint8_t* pByte, size_t size)
00065 {
00066 assert(sizeof(uint16_t) <= size);
00067
00068 pByte[0] = static_cast<uint8_t>((rData & 0xFF00) >> 8);
00069 pByte[1] = static_cast<uint8_t>((rData & 0x00FF) >> 0);
00070 }
00071
00078 inline void ConvertUint32ToBytes(const uint32_t& rData, uint8_t* pByte, size_t size)
00079 {
00080 assert(sizeof(uint32_t) <= size);
00081
00082 pByte[0] = static_cast<uint8_t>((rData & 0xFF000000) >> 24);
00083 pByte[1] = static_cast<uint8_t>((rData & 0x00FF0000) >> 16);
00084 pByte[2] = static_cast<uint8_t>((rData & 0x0000FF00) >> 8);
00085 pByte[3] = static_cast<uint8_t>((rData & 0x000000FF) >> 0);
00086 }
00087
00094 inline uint16_t ConvertBytesToUint16(const uint8_t* pByte, size_t size)
00095 {
00096 assert(size >= sizeof(uint16_t));
00097
00098 return ((static_cast<uint16_t>(pByte[0]) << 8) & 0xFF00) |
00099 ((static_cast<uint16_t>(pByte[1]) << 0) & 0x00FF);
00100 }
00101
00108 inline uint32_t ConvertBytesToUint32(const uint8_t* pByte, size_t size)
00109 {
00110 assert(size >= sizeof(uint32_t));
00111
00112 return ((static_cast<uint32_t>(pByte[0]) << 24) & 0xFF000000) |
00113 ((static_cast<uint32_t>(pByte[1]) << 16) & 0x00FF0000) |
00114 ((static_cast<uint32_t>(pByte[2]) << 8) & 0x0000FF00) |
00115 ((static_cast<uint32_t>(pByte[3]) << 0) & 0x000000FF);
00116 }
00117
00123 inline uint32_t ConvertFloatToUint32(float data)
00124 {
00125 return (*((uint32_t*)&data));
00126 }
00127
00133 inline float ConvertUint32ToFloat(uint32_t data)
00134 {
00135 return (*((float*)&data));
00136 }
00137
00145 inline void ConvertCommandToBytes(uint16_t commandId, uint32_t value1, uint32_t value2, Bytes& rBytes)
00146 {
00147 rBytes.resize(RMP_CMD_BODY_SIZE);
00148
00149 ConvertUint16ToBytes(commandId, &rBytes[RMP_CMD_HEADER_IDX], sizeof(uint16_t));
00150 ConvertUint32ToBytes(value1, &rBytes[RMP_CMD_VAL1_IDX], sizeof(uint32_t));
00151 ConvertUint32ToBytes(value2, &rBytes[RMP_CMD_VAL2_IDX], sizeof(uint32_t));
00152 }
00153
00157 struct CrcTable
00158 {
00162 CrcTable()
00163 {
00164 for (uint16_t byte = 0; byte < CRC_TABLE_SIZE; ++byte)
00165 {
00166 uint16_t value = 0;
00167 uint16_t k = byte;
00168
00169 for (uint16_t j = 0; j < 8; ++j)
00170 {
00171 if (((value ^ k) & 0x0001) == 0x0001)
00172 {
00173 value = (value >> 1) ^ CRC_ADJUSTMENT;
00174 }
00175 else
00176 {
00177 value >>= 1;
00178 }
00179
00180 k >>= 1;
00181 }
00182
00183 m_Entries[byte] = value;
00184 }
00185 }
00186
00192 uint16_t& operator[](size_t idx)
00193 {
00194 assert(idx < CRC_TABLE_SIZE);
00195
00196 return m_Entries[idx];
00197 }
00198
00204 const uint16_t& operator[](size_t idx) const
00205 {
00206 assert(idx < CRC_TABLE_SIZE);
00207
00208 return m_Entries[idx];
00209 }
00210
00211 private:
00215 uint16_t m_Entries[CRC_TABLE_SIZE];
00216 };
00217
00224 inline uint16_t GetCrc(Bytes& rBytes, size_t size)
00225 {
00226 static const CrcTable crcTable;
00227
00228 uint16_t crc = 0;
00229
00230 assert(size <= rBytes.size());
00231
00232 for (size_t i = 0; i < size; ++i)
00233 {
00234 uint64_t tmp = crc ^ rBytes[i];
00235 crc = (crc >> 8) ^ crcTable[tmp & 0x00FF];
00236 }
00237
00238 return crc;
00239 }
00240
00245 inline void AppendCrc16(Bytes& rBytes)
00246 {
00247 uint16_t crc = GetCrc(rBytes, rBytes.size());
00248 uint8_t crcBytes[2];
00249 ConvertUint16ToBytes(crc, crcBytes, 2);
00250
00251 rBytes.push_back(crcBytes[0]);
00252 rBytes.push_back(crcBytes[1]);
00253 }
00254
00261 inline bool IsCrcValid(Bytes& rBytes, size_t size)
00262 {
00263 uint16_t computedCrc = GetCrc(rBytes, size - CRC_SIZE);
00264 uint16_t receivedCrc = ConvertBytesToUint16(&rBytes[size - CRC_SIZE], sizeof(uint16_t));
00265
00266 if (computedCrc != receivedCrc)
00267 {
00268 return false;
00269 }
00270
00271 return true;
00272 }
00273 }
00274
00275 #endif // RMP_HELPER_H