| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- #include "um482.h"
- #include <stdio.h>
- #include <string.h>
- #define CRC32_POLYNOMIAL 0xEDB88320
- /* 消息类型 */
- enum
- {
- UM482_MSG_TYPE_BINARY = 0,
- UM482_MSG_TYPE_ASCII = 1,
- UM482_MSG_TYPE_ASCII_SIMPLE = 2
- };
- /* 消息解析阶段 */
- enum
- {
- UM482_PARSE_STATE_UNINIT = 0,
- UM482_PARSE_STATE_IDLE = 1,
- UM482_PARSE_STATE_GOT_HEADER = 2,
- UM482_PARSE_STATE_GOT_DATA = 3,
- UM482_PARSE_STATE_GOT_CRC = 4
- };
- /* msg id 枚举定义 */
- enum
- {
- UM482_MSG_BESTPOS_ID = 42,
- UM482_MSG_BESTVEL_ID = 99,
- UM482_MSG_HEADING_ID = 971,
- };
- unsigned long _CRC32Value(int i)
- {
- int j;
- unsigned long ulCRC;
- ulCRC = i;
- for (j = 8; j > 0; j--)
- {
- if (ulCRC & 1)
- ulCRC = (ulCRC >> 1) ^ CRC32_POLYNOMIAL;
- else
- ulCRC >>= 1;
- }
- return ulCRC;
- }
- unsigned long _CalculateBlockCRC32(unsigned char *ucBuffer,
- unsigned long ulCount, uint32_t initValue)
- {
- unsigned long ulTemp1;
- unsigned long ulTemp2;
- unsigned long ulCRC = initValue;
- while (ulCount-- != 0)
- {
- ulTemp1 = (ulCRC >> 8) & 0x00FFFFFF;
- ulTemp2 = _CRC32Value(((int)ulCRC ^ *ucBuffer++) & 0xff);
- ulCRC = ulTemp1 ^ ulTemp2;
- }
- return (ulCRC);
- }
- void um482_rxmsg_init(um482_msg_t *msg)
- {
- msg->_parse_state = UM482_PARSE_STATE_IDLE;
- msg->_head_rx_index = 0;
- msg->_data_rx_index = 0;
- msg->_check_rx_index = 0;
- }
- void um482_rxmsg_deinit(um482_msg_t *msg)
- {
- msg->_parse_state = UM482_PARSE_STATE_UNINIT;
- }
- int8_t um482_rxmsg_parse_char(uint8_t c, um482_msg_t *msg)
- {
- int8_t ret_val = 0;
- if (msg->_parse_state == UM482_PARSE_STATE_UNINIT)
- {
- um482_rxmsg_init(msg);
- }
- switch (msg->_parse_state)
- {
- case UM482_PARSE_STATE_IDLE:
- switch (msg->_head_rx_index)
- {
- case 0:
- if (c == 0xAA)
- {
- msg->header.sync[0] = c;
- msg->_head_rx_index++;
- }
- else
- {
- um482_rxmsg_init(msg);
- }
- break;
- case 1:
- if (c == 0x44)
- {
- msg->header.sync[1] = c;
- msg->_head_rx_index++;
- }
- else
- {
- um482_rxmsg_init(msg);
- }
- break;
- case 2:
- if (c == 0x12)
- {
- msg->header.sync[2] = c;
- msg->_head_rx_index++;
- }
- else
- {
- um482_rxmsg_init(msg);
- }
- break;
- case 3:
- if (c == sizeof(msg->header))
- {
- msg->header.header_len = c;
- msg->_head_rx_index++;
- }
- else
- {
- um482_rxmsg_init(msg);
- }
- break;
- default:
- if (msg->_head_rx_index < sizeof(msg->header))
- {
- uint8_t *p = (uint8_t *)&msg->header;
- *(p + msg->_head_rx_index) = c;
- msg->_head_rx_index++;
- if (msg->_head_rx_index >= sizeof(msg->header))
- {
- if (msg->header.msg_len <= sizeof(msg->data))
- {
- msg->_parse_state = UM482_PARSE_STATE_GOT_HEADER;
- msg->_head_rx_index = 0;
- msg->_data_rx_index = 0;
- }
- else
- {
- um482_rxmsg_init(msg);
- }
- }
- }
- else
- {
- um482_rxmsg_init(msg);
- }
- break;
- }
- break;
- case UM482_PARSE_STATE_GOT_HEADER:
- if (msg->_data_rx_index < msg->header.msg_len)
- {
- msg->data[msg->_data_rx_index] = c;
- msg->_data_rx_index++;
- if (msg->_data_rx_index >= msg->header.msg_len)
- {
- msg->_parse_state = UM482_PARSE_STATE_GOT_DATA;
- msg->_check_rx_index = 0;
- msg->crc32_check = 0;
- }
- }
- else
- {
- um482_rxmsg_init(msg);
- }
- break;
- case UM482_PARSE_STATE_GOT_DATA:
- if (msg->_check_rx_index < sizeof(msg->crc32_check))
- {
- msg->crc32_check += c << (msg->_check_rx_index * 8);
- msg->_check_rx_index++;
- if (msg->_check_rx_index >= sizeof(msg->crc32_check))
- {
- uint32_t check = 0;
- /* 计算校验 */
- check = _CalculateBlockCRC32((uint8_t *)&msg->header,
- sizeof(msg->header), 0);
- check =
- _CalculateBlockCRC32(msg->data, msg->header.msg_len, check);
- if (check == msg->crc32_check)
- {
- ret_val = 1;
- }
- else
- {
- ret_val = -1;
- }
- um482_rxmsg_init(msg);
- }
- }
- else
- {
- um482_rxmsg_init(msg);
- }
- break;
- default:
- break;
- }
- return ret_val;
- }
- void um482_rxmsg_decode(um482_msg_t *msg, um482_rx_data_t *pdata)
- {
- switch (msg->header.msg_id)
- {
- case UM482_MSG_BESTPOS_ID:
- pdata->bestpos_rx_count++;
- if (pdata->bestpos_rx_count == 0)
- pdata->bestpos_rx_count = 1;
- if (pdata->bestpos_data_link_status != COMP_CLOSED)
- pdata->bestpos_data_link_status = COMP_NORMAL;
- memcpy(&pdata->bestpos, msg->data, sizeof(pdata->bestpos));
- if (pdata->bestpos_rx_callback)
- pdata->bestpos_rx_callback(pdata);
- break;
- case UM482_MSG_BESTVEL_ID:
- pdata->bestvel_rx_count++;
- if (pdata->bestvel_rx_count == 0)
- pdata->bestvel_rx_count = 1;
- if (pdata->bestvel_data_link_status != COMP_CLOSED)
- pdata->bestvel_data_link_status = COMP_NORMAL;
- memcpy(&pdata->bestvel, msg->data, sizeof(pdata->bestvel));
- if (pdata->bestvel_rx_callback)
- pdata->bestvel_rx_callback(pdata);
- break;
- case UM482_MSG_HEADING_ID:
- pdata->heading_rx_count++;
- if (pdata->heading_rx_count == 0)
- pdata->heading_rx_count = 1;
- if (pdata->heading_data_link_status != COMP_CLOSED)
- pdata->heading_data_link_status = COMP_NORMAL;
- memcpy(&pdata->heading, msg->data, sizeof(pdata->heading));
- if (pdata->heading_rx_callback)
- pdata->heading_rx_callback(pdata);
- break;
- default:
- break;
- }
- }
- void um482_rxmsg_link_check(um482_rx_data_t *pdata)
- {
- /* printf("%d %d %d\r\n", pdata->bestvel_rx_count, pdata->bestpos_rx_count,
- pdata->heading_rx_count); */
- pdata->rx_count = pdata->bestvel_rx_count + pdata->bestpos_rx_count +
- pdata->heading_rx_count;
- if (pdata->bestvel_data_link_status == COMP_NORMAL)
- {
- if (pdata->bestvel_rx_count == 0)
- {
- pdata->bestvel_data_link_status = COMP_LOST;
- }
- pdata->bestvel_rx_count = 0;
- }
- if (pdata->bestpos_data_link_status == COMP_NORMAL)
- {
- if (pdata->bestpos_rx_count == 0)
- {
- pdata->bestpos_data_link_status = COMP_LOST;
- }
- pdata->bestpos_rx_count = 0;
- }
- if (pdata->heading_data_link_status == COMP_NORMAL)
- {
- if (pdata->heading_rx_count == 0)
- {
- pdata->heading_data_link_status = COMP_LOST;
- }
- pdata->heading_rx_count = 0;
- }
- }
|