Files
Geely/libs/LinFrame.h

82 lines
2.0 KiB
C++

/*
* LinFrame.h
*
* Created on: 26 дек. 2015 г.
* Author: esaulenko
*/
#ifndef DRIVERS_LIN_LINFRAME_H_
#define DRIVERS_LIN_LINFRAME_H_
#include <cstdint>
#include "Utils.h"
class TLinFrame
{
private:
enum { MaxDataLen = 16, };
public:
TLinFrame():
data_len(-1) // изначально буфер пустой
{}
uint8_t id;
int8_t data_len; // знак используется при приёме
uint16_t data[MaxDataLen + 1]; // data + chksum
// посчитать контрольную сумму по стандарту 1.1 (без ID) или по стандарту 2.0 (c ID)
uint8_t CalcChksum (bool new_mode)
{
data_len = MIN (data_len, MaxDataLen);
uint32_t chksum = new_mode ? id : 0;
for (int i = 0; i < data_len; i++)
{
chksum += data[i];
if (chksum > 0xFF)
chksum -= 0xFF;
}
return ~ chksum;
}
// добавить контрольную сумму в пакет
void AddChksum (bool new_mode)
{ data[data_len] = CalcChksum (new_mode); }
// проверить контрольную сумму пакета
bool IsChksumCorrect (bool new_mode)
{ return data[data_len] == CalcChksum (new_mode); }
// посчитать контрольные (старшие) биты в идентификаторе
void CalcIdChksum (uint8_t aId)
{
// byte = p7 p6 b5..b0
// P6 = b0 ^ b1 ^ b2 ^ b4
// P7 = ~ (b1 ^ b3 ^ b4 ^ b5)
uint8_t P6 = (aId >> 0) ^ (aId >> 1) ^ (aId >> 2) ^ (aId >> 4);
uint8_t P7 = (aId >> 1) ^ (aId >> 3) ^ (aId >> 4) ^ (aId >> 5);
P6 = ( P6 & 0x01) << 6;
P7 = ((~P7) & 0x01) << 7;
id = P7 | P6 | (aId & 0x3F);
}
// скопировать данные в кадр (до 8 байт)
template <int N>
inline void SetData (const char (&data_str)[N])
{
data_len = MIN (N - 1, MaxDataLen);
for (int i = 0; i < data_len; i++)
data[i] = (uint8_t)data_str[i];
}
};
#endif /* DRIVERS_LIN_LINFRAME_H_ */