//
|
// Created by YY on 2019/12/21.
|
//
|
|
#include <cstring>
|
#include <pthread.h>
|
#include "mcu_if.h"
|
#include "../common/apptimer.h"
|
#include "../utils/crc16.h"
|
#include "../defs.h"
|
#include "../jni_log.h"
|
#include "../common/serial_port.h"
|
|
#define DEBUG(fmt, args...) LOGD("<mcu_if> <%s>: " fmt, __func__, ##args)
|
|
#define MCU_UART UART_1
|
|
enum parse_status_t {
|
SYNC_HEAD_ONE,
|
SYNC_HEAD_TWO,
|
GET_ID_HI,
|
GET_ID_LO,
|
GET_LENGTH_HI,
|
GET_LENGTH_LO,
|
GET_PAYLOAD,
|
GET_CRC16_HI,
|
GET_CRC16_LO
|
};
|
|
#define ID_CM_APP_BOOT 0x0001
|
#define ID_MC_MCU_BOOT 0x8001
|
#define ID_CM_INQ_MCU_VER 0x0002
|
#define ID_MC_MCU_VER 0x8002
|
#define ID_CM_RW_INFO 0x0003
|
#define ID_MC_RW_INFO_RSP 0x8003
|
#define ID_CM_MCU_DFU_REQ 0x0004
|
#define ID_MC_MCU_DFU_RSP 0x8004
|
#define ID_CM_MCU_DFU_DATA 0x0005
|
#define ID_CM_MCU_DFU_DATA_CMP 0x0006
|
#define ID_MC_MCU_DFU_DATA_RSP 0x8006
|
#define ID_MC_CAR_INFO 0x8007
|
#define ID_MC_RTK_DATA 0x8008
|
#define ID_CM_RTK_DATA 0x0008
|
#define ID_CM_READ_RFCARD 0x0009
|
#define ID_MC_RFCARD_RSP 0x8009
|
|
static parse_status_t parse_status;
|
|
static struct {
|
uint16_t id;
|
uint16_t length;
|
uint16_t rx_len;
|
uint8_t buffer[4096 + 4];
|
uint16_t crc16;
|
}McuPkt;
|
|
static void *UartThread1(void *p);
|
static void ParseMcuTimeout(union sigval sig);
|
static void McuCommandEntry(uint16_t id, const uint8_t *data, int lenth);
|
|
void ParseMcuInit(void)
|
{
|
parse_status = SYNC_HEAD_ONE;
|
AppTimer_delete(ParseMcuTimeout);
|
|
SendMcuCommand(ID_CM_APP_BOOT, NULL, 0);
|
}
|
|
#define PARSE_BUFF_SIZE 4096
|
|
static void *UartThread1(void *p) {
|
struct serial_config *cfg = (struct serial_config *) p;
|
|
int res = InitSerialPort(MCU_UART, cfg->baud, cfg->data_bit, cfg->verify_bit, cfg->stop_bit, cfg->flow_ctrl);
|
DEBUG("Serial %s open %d", cfg->name, res);
|
uint8_t RxBuf[PARSE_BUFF_SIZE];
|
int RxBufLen = 0;
|
|
if (res == 0)
|
ParseMcuInit();
|
|
while (res == 0) {
|
int ul = ReadSerialPort(MCU_UART, (uint8_t *)RxBuf + RxBufLen, sizeof(RxBuf) - RxBufLen);
|
RxBufLen += ul;
|
|
/*{
|
static char buffd[16384];
|
|
buffd[0] = 0;
|
int i = 0;
|
for (i = 0; i < ul; i++) {
|
if ((i % 32) == 0) {
|
sprintf(buffd + strlen(buffd), "\n");
|
}
|
sprintf(buffd + strlen(buffd), "%02X ", RxBuf[i]);
|
if (strlen(buffd) > 800) {
|
DEBUG("%s <- %s...", "UART", buffd);
|
buffd[0] = 0;
|
}
|
}
|
if (strlen(buffd) > 0)
|
DEBUG("%s <- %s", "UART", buffd);
|
}*/
|
|
if (RxBufLen > 0) {
|
DEBUG("RECV LEN %d", RxBufLen);
|
ParseMcu(RxBuf, RxBufLen);
|
RxBufLen = 0;
|
}
|
}
|
if (res == 0) {
|
UninitSerialPort(MCU_UART);
|
}
|
pthread_exit(NULL);
|
}
|
|
void ParseMcu(const uint8_t *data, int length)
|
{
|
int x = 0;
|
while (x < length) {
|
uint8_t c = data[x];
|
switch (parse_status) {
|
case SYNC_HEAD_ONE:
|
if (c == 0x55) {
|
parse_status = SYNC_HEAD_TWO;
|
AppTimer_delete(ParseMcuTimeout);
|
AppTimer_add(ParseMcuTimeout, D_SEC(5));
|
}
|
x++;
|
break;
|
case SYNC_HEAD_TWO:
|
if (c == 0xAA) {
|
parse_status = GET_ID_HI;
|
} else if (c != 0x55) {
|
parse_status = SYNC_HEAD_ONE;
|
}
|
x++;
|
break;
|
case GET_ID_HI:
|
McuPkt.id = c;
|
parse_status = GET_ID_LO;
|
x++;
|
break;
|
case GET_ID_LO:
|
McuPkt.id <<= 8;
|
McuPkt.id += c;
|
parse_status = GET_LENGTH_HI;
|
x++;
|
break;
|
case GET_LENGTH_HI:
|
McuPkt.rx_len = 0;
|
McuPkt.length = c;
|
parse_status = GET_LENGTH_LO;
|
x++;
|
break;
|
case GET_LENGTH_LO:
|
McuPkt.length <<= 8;
|
McuPkt.length += c;
|
parse_status = GET_PAYLOAD;
|
|
if (McuPkt.length >= 1500) {
|
DEBUG("Pkt Too large!");
|
parse_status = SYNC_HEAD_ONE;
|
AppTimer_delete(ParseMcuTimeout);
|
}
|
|
McuPkt.buffer[0] = HI_UINT16(McuPkt.id);
|
McuPkt.buffer[1] = LO_UINT16(McuPkt.id);
|
McuPkt.buffer[2] = HI_UINT16(McuPkt.length);
|
McuPkt.buffer[3] = LO_UINT16(McuPkt.length);
|
x++;
|
break;
|
case GET_PAYLOAD:
|
if (length - x >= McuPkt.length - McuPkt.rx_len) {
|
memcpy(McuPkt.buffer + 4 + McuPkt.rx_len, data + x, McuPkt.length - McuPkt.rx_len);
|
x += McuPkt.length - McuPkt.rx_len;
|
McuPkt.rx_len = McuPkt.length;
|
parse_status = GET_CRC16_HI;
|
} else {
|
memcpy(McuPkt.buffer + 4 + McuPkt.rx_len, data + x, length - x);
|
McuPkt.rx_len += length - x;
|
x = length;
|
}
|
break;
|
case GET_CRC16_HI:
|
McuPkt.crc16 = c;
|
parse_status = GET_CRC16_LO;
|
x++;
|
break;
|
case GET_CRC16_LO: {
|
McuPkt.crc16 <<= 8;
|
McuPkt.crc16 += c;
|
|
uint16_t crc16 = CRCCCITT(McuPkt.buffer, McuPkt.length + 4, 0, 0);
|
|
DEBUG("mcuif crc16 but 0x%04X exp 0x%04X", McuPkt.crc16, crc16);
|
|
if (McuPkt.crc16 == crc16) {
|
McuCommandEntry(McuPkt.id, McuPkt.buffer + 4, McuPkt.length);
|
}
|
|
parse_status = SYNC_HEAD_ONE;
|
AppTimer_delete(ParseMcuTimeout);
|
x++;
|
break;
|
}
|
default:
|
break;
|
}
|
}
|
}
|
|
void SendMcuCommand(uint16_t id, const uint8_t *data, int length)
|
{
|
uint8_t buffer[2048];
|
int x = 0;
|
|
buffer[x++] = 0x55;
|
buffer[x++] = 0xAA;
|
buffer[x++] = HI_UINT16(id);
|
buffer[x++] = LO_UINT16(id);
|
buffer[x++] = HI_UINT16(length);
|
buffer[x++] = LO_UINT16(length);
|
|
if (data != NULL && length > 0) {
|
memcpy(buffer + x, data, length);
|
x += length;
|
}
|
|
uint16_t crc16 = CRCCCITT(buffer + 2, length + 4, 0, 0);
|
buffer[x++] = HI_UINT16(crc16);
|
buffer[x++] = LO_UINT16(crc16);
|
|
WriteSerialPort(MCU_UART, buffer, x);
|
}
|
|
void ConfigMCU(void)
|
{
|
// TODO
|
static struct serial_config serialConfig;
|
|
strcpy(serialConfig.name, "/dev/ttyHSL1");
|
serialConfig.baud = 115200;
|
serialConfig.data_bit = 8;
|
serialConfig.verify_bit = 'N';
|
serialConfig.stop_bit = 1;
|
serialConfig.flow_ctrl = 0;
|
|
pthread_t pid;
|
pthread_attr_t attr;
|
pthread_attr_init(&attr);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
|
pthread_create(&pid, &attr, UartThread1, &serialConfig);
|
}
|
|
void SendRtkToMcu(const uint8_t *data, int length)
|
{
|
SendMcuCommand(ID_CM_RTK_DATA, data, length);
|
}
|
|
static void ParseMcuTimeout(union sigval sig) {
|
AppTimer_delete(ParseMcuTimeout);
|
parse_status = SYNC_HEAD_ONE;
|
}
|
|
static void sendrtk(union sigval sig) {
|
uint8_t data[486];
|
|
memset(data, 0x86, sizeof(data));
|
|
SendMcuCommand(ID_CM_RTK_DATA, data, sizeof(data));
|
|
SendMcuCommand(ID_CM_READ_RFCARD, NULL, 0);
|
|
AppTimer_delete(sendrtk);
|
AppTimer_add(sendrtk, D_SEC(1));
|
}
|
|
static void McuCommandEntry(uint16_t id, const uint8_t *data, int lenth)
|
{
|
static int ii = 0;
|
|
switch (id) {
|
case ID_MC_MCU_BOOT:
|
DEBUG("MCU BOOT");
|
break;
|
case ID_MC_MCU_VER:
|
DEBUG("MCU VER");
|
break;
|
case ID_MC_RW_INFO_RSP:
|
break;
|
case ID_MC_MCU_DFU_RSP:
|
break;
|
case ID_MC_MCU_DFU_DATA_RSP:
|
break;
|
case ID_MC_CAR_INFO:
|
DEBUG("ID_MC_CAR_INFO");
|
break;
|
case ID_MC_RTK_DATA:
|
DEBUG("ID_MC_RTK_DATA");
|
break;
|
case ID_MC_RFCARD_RSP:
|
DEBUG("ID_MC_RFCARD_RSP");
|
break;
|
default:
|
break;
|
}
|
}
|