| | |
| | | } |
| | | HIDO_UINT32 cr1 = huart6.Instance->CR1; |
| | | HIDO_UINT32 isr = huart6.Instance->ISR; |
| | | HIDO_Debug2("[BT] Poll: IntCnt=%u, DMA_CNDTR=%u, CR1=0x%X, ISR=0x%X\r\n", |
| | | HIDO_Debug("[BT] Poll: IntCnt=%u, DMA_CNDTR=%u, CR1=0x%X, ISR=0x%X\r\n", |
| | | g_u32BtIdleIntCount, dma_cnt, cr1, isr); |
| | | #endif |
| | | } |
| | |
| | | // rx_buf[13]: Tail |
| | | |
| | | HIDO_UINT8 *pBuf = s_bt_fsm.rx_buf; |
| | | HIDO_UINT16 total_len = 5 + s_bt_fsm.data_len; // Header(5) + Data(SeqNum + Payload + CRC + Tail) |
| | | HIDO_UINT16 total_len = 10 + s_bt_fsm.data_len; // Header(5) + Data(SeqNum + Payload + CRC + Tail) |
| | | |
| | | if (total_len < 14 || total_len > BT_RX_BUF_SIZE) |
| | | { |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | HIDO_Debug2("[BT] Invalid frame length: %u\r\n", total_len); |
| | | HIDO_Debug("[BT] Invalid frame length: %u\r\n", total_len); |
| | | #endif |
| | | return; |
| | | } |
| | | |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | // Print entire frame in hex for debugging |
| | | HIDO_Debug2("[BT] Frame (%u bytes): ", total_len); |
| | | HIDO_Debug("[BT] Frame (%u bytes): ", total_len); |
| | | for (HIDO_UINT16 i = 0; i < total_len; i++) |
| | | { |
| | | HIDO_Debug2("%02X ", pBuf[i]); |
| | | HIDO_Debug("%02X ", pBuf[i]); |
| | | } |
| | | HIDO_Debug2("\r\n"); |
| | | HIDO_Debug("\r\n"); |
| | | #endif |
| | | |
| | | // Check CRC - Try different ranges to find the correct one |
| | |
| | | HIDO_UINT16 recv_crc_be = (HIDO_UINT16)((crc_low << 8) | crc_high); // Big Endian |
| | | |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | HIDO_Debug2("[BT] CRC Test: Recv(LE)=%04X, Recv(BE)=%04X\r\n", recv_crc_le, recv_crc_be); |
| | | HIDO_Debug2(" Calc1(Full,11B)=%04X, Calc2(FromLen,8B)=%04X, Calc3(FromSeq,6B)=%04X\r\n", |
| | | HIDO_Debug("[BT] CRC Test: Recv(LE)=%04X, Recv(BE)=%04X\r\n", recv_crc_le, recv_crc_be); |
| | | HIDO_Debug(" Calc1(Full,11B)=%04X, Calc2(FromLen,8B)=%04X, Calc3(FromSeq,6B)=%04X\r\n", |
| | | calc_crc1, calc_crc2, calc_crc3); |
| | | #endif |
| | | |
| | |
| | | if (calc_crc1 != recv_crc_le && calc_crc1 != recv_crc_be) |
| | | { |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | HIDO_Debug2("[BT] CRC Fail (all methods)\r\n"); |
| | | HIDO_Debug("[BT] CRC Fail (all methods)\r\n"); |
| | | #endif |
| | | // Continue processing for debug |
| | | // return; |
| | |
| | | if (tail != BT_FRAME_TAIL) |
| | | { |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | HIDO_Debug2("[BT] Invalid Tail: %02X\r\n", tail); |
| | | HIDO_Debug("[BT] Invalid Tail: %02X\r\n", tail); |
| | | #endif |
| | | return; |
| | | } |
| | |
| | | if (SBUS_IsSignalValid(500) == HIDO_FALSE) |
| | | { |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | HIDO_Debug2("[BT] Control: Steer %d, Speed %d\r\n", pCtrl->m_i8SteerSpeed, pCtrl->m_i8TravelSpeed); |
| | | HIDO_Debug("[BT] Control: Steer %d, Speed %d\r\n", pCtrl->m_i8SteerSpeed, pCtrl->m_i8TravelSpeed); |
| | | #endif |
| | | |
| | | Set_Steering_PWM(pCtrl->m_i8SteerSpeed); |
| | |
| | | } |
| | | else |
| | | { |
| | | // HIDO_Debug2("[BT] Ignored (RC Active)\r\n"); |
| | | // HIDO_Debug("[BT] Ignored (RC Active)\r\n"); |
| | | } |
| | | break; |
| | | } |
| | | default: |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | HIDO_Debug2("[BT] Unknown Cmd: 0x%02X\r\n", s_bt_fsm.cmd_type); |
| | | HIDO_Debug("[BT] Unknown Cmd: 0x%02X\r\n", s_bt_fsm.cmd_type); |
| | | #endif |
| | | break; |
| | | } |
| | |
| | | if (s_bt_fsm.data_len > (BT_RX_BUF_SIZE - 5)) |
| | | { |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | HIDO_Debug2("[BT] FSM: Length too large (%u), resetting\r\n", s_bt_fsm.data_len); |
| | | HIDO_Debug("[BT] FSM: Length too large (%u), resetting\r\n", s_bt_fsm.data_len); |
| | | #endif |
| | | s_bt_fsm.state = BT_FSM_IDLE; |
| | | } |
| | |
| | | // data_len includes: SeqNum(2) + Payload(N) + CRC(2) + Tail(1) |
| | | // Total frame = Header(5) + data_len |
| | | // We've already stored Header(5), now need data_len more bytes |
| | | if (s_bt_fsm.data_idx >= (5 + s_bt_fsm.data_len)) |
| | | if (s_bt_fsm.data_idx >= (10 + s_bt_fsm.data_len)) |
| | | { |
| | | // Frame complete, process it |
| | | BT_ProcessFrame(); |
| | |
| | | if (s_bt_fsm.data_idx >= BT_RX_BUF_SIZE) |
| | | { |
| | | #if ENABLE_BT_DEBUG_LOG |
| | | HIDO_Debug2("[BT] FSM: Buffer overflow, resetting\r\n"); |
| | | HIDO_Debug("[BT] FSM: Buffer overflow, resetting\r\n"); |
| | | #endif |
| | | s_bt_fsm.state = BT_FSM_IDLE; |
| | | } |
| | |
| | | */ |
| | | static HIDO_VOID Process_Command(const HIDO_UINT8 *pData, HIDO_UINT16 u16Len) |
| | | { |
| | | // HIDO_Debug2("[BT] Processing %u bytes\r\n", u16Len); |
| | | // HIDO_Debug("[BT] Processing %u bytes\r\n", u16Len); |
| | | if (u16Len < sizeof(ST_BT_FrameHeader) + 3) // Header + CRC + Tail min |
| | | { |
| | | return; |
| | |
| | | // Check Header |
| | | if (pHeader->m_u8Header1 != BT_FRAME_HEADER1 || pHeader->m_u8Header2 != BT_FRAME_HEADER2) |
| | | { |
| | | HIDO_Debug2("[BT] Invalid Header: %02X %02X\r\n", pHeader->m_u8Header1, pHeader->m_u8Header2); |
| | | HIDO_Debug("[BT] Invalid Header: %02X %02X\r\n", pHeader->m_u8Header1, pHeader->m_u8Header2); |
| | | return; |
| | | } |
| | | |
| | |
| | | |
| | | if (u16Len < expectedLen) |
| | | { |
| | | HIDO_Debug2("[BT] Incomplete Frame: Recv %d, Expected %d\r\n", u16Len, expectedLen); |
| | | HIDO_Debug("[BT] Incomplete Frame: Recv %d, Expected %d\r\n", u16Len, expectedLen); |
| | | return; |
| | | } |
| | | |
| | | // Check Tail |
| | | if (pData[expectedLen - 1] != BT_FRAME_TAIL) |
| | | { |
| | | HIDO_Debug2("[BT] Invalid Tail: %02X\r\n", pData[expectedLen - 1]); |
| | | HIDO_Debug("[BT] Invalid Tail: %02X\r\n", pData[expectedLen - 1]); |
| | | return; |
| | | } |
| | | |
| | |
| | | |
| | | if (calcCRC != recvCRC) |
| | | { |
| | | HIDO_Debug2("[BT] CRC Fail: Calc %04X, Recv %04X\r\n", calcCRC, recvCRC); |
| | | HIDO_Debug("[BT] CRC Fail: Calc %04X, Recv %04X\r\n", calcCRC, recvCRC); |
| | | // Continue processing for debugging, but typically should return |
| | | // return; |
| | | } |
| | |
| | | case BT_CMD_PATH_COORDS: |
| | | { |
| | | HIDO_UINT8 pathCount = pPayload[0]; |
| | | HIDO_Debug2("[BT] Path Coords: Count %d\r\n", pathCount); |
| | | HIDO_Debug("[BT] Path Coords: Count %d\r\n", pathCount); |
| | | ST_BT_PathPoint *pPoints = (ST_BT_PathPoint *)(pPayload + 1); |
| | | for(int i=0; i<pathCount; i++) |
| | | { |
| | | HIDO_Debug2(" Pt%d: %.2f, %.2f\r\n", i, pPoints[i].m_dX, pPoints[i].m_dY); |
| | | HIDO_Debug(" Pt%d: %.2f, %.2f\r\n", i, pPoints[i].m_dX, pPoints[i].m_dY); |
| | | } |
| | | // TODO: Store path points |
| | | break; |
| | |
| | | if (realPayloadLen >= sizeof(ST_BT_RefPointData)) |
| | | { |
| | | ST_BT_RefPointData *pRef = (ST_BT_RefPointData *)pPayload; |
| | | HIDO_Debug2("[BT] Ref Point: Lat %.8f %c, Lon %.8f %c\r\n", |
| | | HIDO_Debug("[BT] Ref Point: Lat %.8f %c, Lon %.8f %c\r\n", |
| | | pRef->m_dLat, pRef->m_cLatDir, pRef->m_dLon, pRef->m_cLonDir); |
| | | // TODO: Store ref point |
| | | } |
| | |
| | | // SBUS_IsSignalValid returns HIDO_TRUE if valid (connected) |
| | | if (SBUS_IsSignalValid(500) == HIDO_FALSE) |
| | | { |
| | | HIDO_Debug2("[BT] Control: Steer %d, Speed %d\r\n", pCtrl->m_i8SteerSpeed, pCtrl->m_i8TravelSpeed); |
| | | HIDO_Debug("[BT] Control: Steer %d, Speed %d\r\n", pCtrl->m_i8SteerSpeed, pCtrl->m_i8TravelSpeed); |
| | | |
| | | Set_Steering_PWM(pCtrl->m_i8SteerSpeed); |
| | | Set_Motor_PWM(pCtrl->m_i8TravelSpeed); |
| | | } |
| | | else |
| | | { |
| | | // HIDO_Debug2("[BT] Ignored (RC Active)\r\n"); |
| | | // HIDO_Debug("[BT] Ignored (RC Active)\r\n"); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | default: |
| | | HIDO_Debug2("[BT] Unknown Cmd: 0x%02X\r\n", pHeader->m_u8CmdType); |
| | | HIDO_Debug("[BT] Unknown Cmd: 0x%02X\r\n", pHeader->m_u8CmdType); |
| | | break; |
| | | } |
| | | } |