📄 mbus_packet.c
字号:
/******************************************************************************
Filename: mbus_packet.c
******************************************************************************/
#include <hal_types.h>
#include <hal_defs.h>
#include <mbus_packet.h>
#include <manchester.h>
#include <3outof6.h>
#include <crc.h>
//----------------------------------------------------------------------------------
// Functions
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
// uint16 packetSize (uint8 lField)
//
// DESCRIPTION:
// Returns the number of bytes in a Wireless MBUS packet from
// the L-field. Note that the L-field excludes the L-field and the
// CRC fields
//
// ARGUMENTS:
// uint8 lField - The L-field value in a Wireless MBUS packet
//
// RETURNS
// uint16 - The number of bytes in a wireless MBUS packet
//----------------------------------------------------------------------------------
uint16 packetSize (uint8 lField)
{
uint16 nrBytes;
uint8 nrBlocks;
// The 2 first blocks contains 25 bytes when excluding CRC and the L-field
// The other blocks contains 16 bytes when excluding the CRC-fields
// Less than 26 (15 + 10)
if ( lField < 26 )
nrBlocks = 2;
else
nrBlocks = (((lField - 26) / 16) + 3);
// Add all extra fields, excluding the CRC fields
nrBytes = lField + 1;
// Add the CRC fields, each block is contains 2 CRC bytes
nrBytes += (2 * nrBlocks);
return (nrBytes);
}
//----------------------------------------------------------------------------------
// uint16 byteSize (uint8 Smode, uint8 transmit, uint16 packetSize)
//
// DESCRIPTION:
// Returns the total number of encoded bytes to receive or transmit, given the
// total number of bytes in a Wireless MBUS packet.
// In receive mode the postamble sequence and synchronization word is excluded
// from the calculation.
//
// ARGUMENTS:
// uint8 Smode - S-mode or T-mode
// uint8 transmit - Transmit or receive
// uint16 packetSize - Total number of bytes in the wireless MBUS packet
//
// RETURNS
// uint16 - The number of bytes of the encoded WMBUS packet
//----------------------------------------------------------------------------------
uint16 byteSize (uint8 Smode, uint8 transmit, uint16 packetSize)
{
uint16 tmodeVar;
// S-mode, data is Manchester coded
if (Smode)
{
// Transmit mode
// 1 byte for postamble and 1 byte synchronization word
if (transmit)
return (2*packetSize + 2);
// Receive mode
else
return (2*packetSize);
}
// T-mode
// Data is 3 out of 6 coded
else
{
tmodeVar = (3*packetSize) / 2;
// Transmit mode
// + 1 byte for the postamble sequence
if (transmit)
return (tmodeVar + 1);
// Receive mode
// If packetsize is a odd number 1 extra byte
// that includes the 4-postamble sequence must be
// read.
else
{
if (packetSize % 2)
return (tmodeVar + 1);
else
return (tmodeVar);
}
}
}
//----------------------------------------------------------------------------------
// void encodeTXPacket(uint8* pPacket, uint8* pData, uint8 dataSize)
//
// DESCRIPTION:
// Encode n data bytes into a Wireless MBUS packet format.
// The function will add all the control field, calculates and inserts the
// the CRC fields
//
// ARGUMENTS:
// uint8 *pPacket - Pointer to the WMBUS packet byte table
// uint8 *pData - Pointer to user data byte table
// uint8 dataSize - Number of user data bytes. Max size is 245
//----------------------------------------------------------------------------------
void encodeTXPacket(uint8* pPacket, uint8* pData, uint8 dataSize)
{
uint8 loopCnt;
uint8 dataRemaining;
uint8 dataEncoded;
uint16 crc;
dataRemaining = dataSize;
dataEncoded = 0;
crc = 0;
// **** Block 1 *****
// - L-Field -
// The length field excludes all CRC-fields and the L-field,
// e.g. L = dataSize + 10
*pPacket = dataSize + 10;
crc = crcCalc(crc,*pPacket);
pPacket++;
// - C-Field -
*(pPacket) = PACKET_C_FIELD;
crc = crcCalc(crc,*pPacket);
pPacket++;
// - M-Field -
*(pPacket) = (uint8)MAN_CODE;
crc = crcCalc(crc,*pPacket);
pPacket++;
*(pPacket) = (uint8)(MAN_CODE >> 8);
crc = crcCalc(crc,*pPacket);
pPacket++;
// - A-Field -
*(pPacket) = (uint8)MAN_NUMBER;
crc = crcCalc(crc,*pPacket);
pPacket++;
*(pPacket) = (uint8)(MAN_NUMBER >> 8);
crc = crcCalc(crc,*pPacket);
pPacket++;
*(pPacket) = (uint8)(MAN_NUMBER >> 16);
crc = crcCalc(crc,*pPacket);
pPacket++;
*(pPacket) = (uint8)(MAN_NUMBER >> 24);
crc = crcCalc(crc,*pPacket);
pPacket++;
*(pPacket) = (uint8)(MAN_ID);
crc = crcCalc(crc,*pPacket);
pPacket++;
*(pPacket) = (uint8)(MAN_VER);
crc = crcCalc(crc,*pPacket);
pPacket++;
// - CRC -
*(pPacket) = HI_UINT16(~crc);
pPacket++;
*(pPacket) = LO_UINT16(~crc);
pPacket++;
crc = 0;
// **** Block 2 *****
// - CI-Field -
*(pPacket) = PACKET_CI_FIELD;
crc = crcCalc(crc,*pPacket);
pPacket++;
// Check if last Block
if (dataRemaining < 16)
{
// Data Fields
for ( loopCnt = 0; loopCnt < dataRemaining ; loopCnt = loopCnt + 1)
{
*(pPacket) = pData[dataEncoded];
crc = crcCalc(crc,*pPacket);
pPacket++;
dataEncoded++;
}
// CRC
*(pPacket) = HI_UINT16(~crc);
pPacket++;
*(pPacket) = LO_UINT16(~crc);
pPacket++;
crc = 0;
dataRemaining = 0;
}
else
{
// Data Fields
for ( loopCnt = 0; loopCnt < 15; loopCnt = loopCnt + 1)
{
*(pPacket) = pData[dataEncoded];
crc = crcCalc(crc,*pPacket);
pPacket++;
dataEncoded++;
}
*(pPacket) = HI_UINT16(~crc);
pPacket++;
*(pPacket) = LO_UINT16(~crc);
pPacket++;
crc = 0;
dataRemaining -= 15;
}
// **** Block n *****
while (dataRemaining)
{
// Check if last Block
if (dataRemaining < 17)
{
// Data Fields
for ( loopCnt = 0; loopCnt < dataRemaining ; loopCnt = loopCnt + 1)
{
*(pPacket) = pData[dataEncoded];
crc = crcCalc(crc,*pPacket);
pPacket++;
dataEncoded++;
}
// CRC
*(pPacket) = HI_UINT16(~crc);
pPacket++;
*(pPacket) = LO_UINT16(~crc);
pPacket++;
crc = 0;
dataRemaining = 0;
}
else
{
// Data Fields
for ( loopCnt = 0; loopCnt < 16; loopCnt = loopCnt + 1)
{
*(pPacket) = pData[dataEncoded];
crc = crcCalc(crc,*pPacket);
pPacket++;
dataEncoded++;
}
// CRC
*(pPacket) = HI_UINT16(~crc);
pPacket++;
*(pPacket) = LO_UINT16(~crc);
pPacket++;
crc = 0;
dataRemaining -= 16;
}
}
}
//----------------------------------------------------------------------------------
// void encodeTXBytesSmode(uint8* pByte, uint8* pPacket, uint16 packetSize)
//
// DESCRIPTION:
// Encodes a wireless MBUS packet into a SMODE packet. This includes
// - Add Least Significant Byte of synchronization word to the TX array
// - Manchester encode the Wireless MBUS packet.
// - Add postamble sequence to the TX array
//
// ARGUMENTS:
// uint8* pByte - Pointer to SMODE packet to transmit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -