// // Created by YY on 2019/12/21. // #include #include #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 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; } }