uart_protocol.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /**
  2. ******************************************************************************
  3. * @file uart_protocol.c
  4. * @brief UART 通讯协议模块实现
  5. * 负责协议帧的组装/发送/接收/解析, 以及对 LED 显示的更新触发.
  6. ******************************************************************************
  7. */
  8. /* Includes ------------------------------------------------------------------*/
  9. #include "uart_protocol.h"
  10. #include "main.h" /* DebugUartHandle */
  11. #include "app_state.h"
  12. #include "led_driver.h"
  13. #include "battery_display.h"
  14. /* Private define ------------------------------------------------------------*/
  15. /* ========== 通讯协议常量 ========== */
  16. #define FRAME_HEADER1 0x55u
  17. #define FRAME_HEADER2 0xAAu
  18. #define CMD_READ 0x01u
  19. #define CMD_WRITE 0x02u
  20. #define CMD_REPORT 0x81u
  21. #define CMD_ACK 0xA0u /* 写操作成功回复 */
  22. /* 接收缓冲区大小 */
  23. #define RX_BUF_SIZE 32u
  24. /* UART 发送超时 (ms) */
  25. #define UART_TX_TIMEOUT 100u
  26. /* Private variables ---------------------------------------------------------*/
  27. extern UART_HandleTypeDef DebugUartHandle;
  28. /* ========== 接收缓冲 (双缓冲) ========== */
  29. #define RX_QUEUE_SIZE 2u
  30. static volatile uint8_t g_rxBuf[RX_QUEUE_SIZE][RX_BUF_SIZE];
  31. static volatile uint8_t g_frameLen[RX_QUEUE_SIZE];
  32. static volatile uint8_t g_rxLen = 0u;
  33. static volatile uint8_t g_rxWriteIdx = 0u;
  34. static volatile uint8_t g_rxReadIdx = 0u;
  35. static volatile uint8_t g_frameCount = 0u;
  36. uint8_t g_rxByte; /* 单字节接收缓冲 (extern 在 uart_protocol.h) */
  37. /* ========== 发送缓冲 ========== */
  38. static uint8_t g_txBuf[8];
  39. /* Private function prototypes -----------------------------------------------*/
  40. static void UART_SendFrame(uint8_t cmd, uint8_t item, uint8_t value);
  41. static void UART_SendWrite(uint8_t item, uint8_t value);
  42. static void HandleReportAll(uint8_t *data, uint8_t count);
  43. static void HandleReportSingle(uint8_t item, uint8_t value);
  44. /* ========== 帧状态查询 ========== */
  45. uint8_t UART_IsFrameReady(void)
  46. {
  47. return (g_frameCount > 0u) ? 1u : 0u;
  48. }
  49. void UART_ClearFrameReady(void)
  50. {
  51. /* 标志位管理移至 ProcessReceivedFrame 内完成 */
  52. }
  53. /* ========== UART 接收回调 ========== */
  54. /**
  55. * @brief USART2中断接收回调 - 每收到一个字节调用
  56. * 支持变长帧: 5字节标准帧及 AA 81 COUNT ... CRC 多字节上报
  57. */
  58. void UART_RxByteCallback(uint8_t data)
  59. {
  60. static uint8_t s_state = 0u; /* 0=Wait 55, 1=Wait AA(or A0), 2=Wait CMD, 3=Wait LEN, 4=Wait Body */
  61. static uint8_t s_expectedLen = 0u;
  62. static uint16_t s_timeout = 0u;
  63. uint8_t *curBuf = (uint8_t *)g_rxBuf[g_rxWriteIdx];
  64. if (s_state != 0u)
  65. {
  66. s_timeout++;
  67. if (s_timeout > 1000u)
  68. {
  69. s_state = 0u;
  70. s_timeout = 0u;
  71. }
  72. }
  73. else
  74. {
  75. s_timeout = 0u;
  76. }
  77. if (s_state == 0u)
  78. {
  79. if (data == FRAME_HEADER1)
  80. {
  81. curBuf[0] = data;
  82. g_rxLen = 1u;
  83. s_state = 1u;
  84. }
  85. else if (data == CMD_ACK)
  86. {
  87. curBuf[0] = CMD_ACK;
  88. if (g_frameCount < RX_QUEUE_SIZE)
  89. {
  90. g_frameLen[g_rxWriteIdx] = 1u;
  91. g_rxWriteIdx = (g_rxWriteIdx + 1u) % RX_QUEUE_SIZE;
  92. g_frameCount++;
  93. }
  94. g_rxLen = 0u;
  95. }
  96. return;
  97. }
  98. if (s_state == 1u)
  99. {
  100. if (data == FRAME_HEADER2)
  101. {
  102. curBuf[1] = data;
  103. g_rxLen = 2u;
  104. s_state = 2u;
  105. }
  106. else
  107. {
  108. s_state = 0u;
  109. }
  110. return;
  111. }
  112. if (s_state == 2u)
  113. {
  114. curBuf[g_rxLen++] = data;
  115. s_state = 3u;
  116. return;
  117. }
  118. if (s_state == 3u)
  119. {
  120. curBuf[g_rxLen++] = data;
  121. s_expectedLen = 5u + data;
  122. s_state = 4u;
  123. if (s_expectedLen > RX_BUF_SIZE)
  124. {
  125. s_state = 0u;
  126. g_rxLen = 0u;
  127. }
  128. return;
  129. }
  130. if (s_state == 4u)
  131. {
  132. curBuf[g_rxLen++] = data;
  133. if (g_rxLen >= s_expectedLen)
  134. {
  135. uint8_t cmd = curBuf[2];
  136. uint8_t len = curBuf[3];
  137. uint8_t crc = cmd ^ len;
  138. for (uint8_t i = 0; i < len; i++)
  139. {
  140. crc ^= curBuf[4 + i];
  141. }
  142. if (crc == data)
  143. {
  144. if (g_frameCount < RX_QUEUE_SIZE)
  145. {
  146. g_frameLen[g_rxWriteIdx] = g_rxLen;
  147. g_rxWriteIdx = (g_rxWriteIdx + 1u) % RX_QUEUE_SIZE;
  148. g_frameCount++;
  149. }
  150. }
  151. s_state = 0u;
  152. g_rxLen = 0u;
  153. }
  154. }
  155. }
  156. /* ========== 帧处理 ========== */
  157. /**
  158. * @brief 处理收到的完整协议帧
  159. */
  160. void ProcessReceivedFrame(void)
  161. {
  162. if (g_frameCount == 0u) return;
  163. uint8_t *frame = (uint8_t *)g_rxBuf[g_rxReadIdx];
  164. uint8_t rxLen = g_frameLen[g_rxReadIdx];
  165. if (rxLen >= 7u)
  166. {
  167. uint8_t cmd = frame[2];
  168. uint8_t len = frame[3];
  169. if (cmd == CMD_REPORT)
  170. {
  171. if (len == 2u)
  172. {
  173. /* 0x81 单条上报: 没有 COUNT 字节, frame[4]=ITEM, frame[5]=VALUE */
  174. HandleReportSingle(frame[4], frame[5]);
  175. }
  176. else if (len > 2u)
  177. {
  178. /* 0x81 多条上报: frame[4] 为键值对数量 COUNT */
  179. uint8_t count = frame[4];
  180. HandleReportAll(&frame[5], count);
  181. }
  182. }
  183. else if (cmd == CMD_READ || cmd == CMD_WRITE)
  184. {
  185. if (len == 2u)
  186. {
  187. HandleReportSingle(frame[4], frame[5]);
  188. }
  189. }
  190. }
  191. /* 释放缓冲区 */
  192. g_rxReadIdx = (g_rxReadIdx + 1u) % RX_QUEUE_SIZE;
  193. __disable_irq();
  194. g_frameCount--;
  195. __enable_irq();
  196. }
  197. /* ========== 发送函数 ========== */
  198. /**
  199. * @brief 直接寄存器操作发送单字节 (绕过 HAL, 避免 HAL 锁/超时关中断)
  200. * 在等待 TXE 时顺带清除接收端可能发生的 ORE 错误
  201. */
  202. static void UART_DirectSendByte(uint8_t byte)
  203. {
  204. uint32_t timeout = 0u;
  205. while (!(USART2->SR & USART_SR_TXE))
  206. {
  207. if (++timeout > 100000u) return; /* 安全超时, 不关中断直接返回 */
  208. /* 等待期间检查并清除 ORE (读 SR 再读 DR 清除) */
  209. if (USART2->SR & USART_SR_ORE)
  210. {
  211. (void)USART2->DR;
  212. }
  213. }
  214. USART2->DR = byte;
  215. }
  216. static void UART_SendFrame(uint8_t cmd, uint8_t item, uint8_t value)
  217. {
  218. uint8_t len = 0x02u;
  219. uint8_t crc = (uint8_t)(cmd ^ len ^ item ^ value);
  220. g_txBuf[0] = FRAME_HEADER1;
  221. g_txBuf[1] = FRAME_HEADER2;
  222. g_txBuf[2] = cmd;
  223. g_txBuf[3] = len;
  224. g_txBuf[4] = item;
  225. g_txBuf[5] = value;
  226. g_txBuf[6] = crc;
  227. for (uint8_t i = 0; i < 7u; i++)
  228. {
  229. UART_DirectSendByte(g_txBuf[i]);
  230. }
  231. /* 等待最后一个字节发送完毕 (TC) */
  232. uint32_t timeout = 0u;
  233. while (!(USART2->SR & USART_SR_TC))
  234. {
  235. if (++timeout > 100000u) break;
  236. }
  237. }
  238. static void UART_SendWrite(uint8_t item, uint8_t value)
  239. {
  240. UART_SendFrame(CMD_WRITE, item, value);
  241. }
  242. void SendSetInputSrc(uint8_t src)
  243. {
  244. UART_SendWrite(ITEM_INPUT_SRC, src);
  245. }
  246. void SendSetVolLR(uint8_t pct)
  247. {
  248. if (pct > 100u) pct = 100u;
  249. UART_SendWrite(ITEM_VOL_LR, pct);
  250. }
  251. void SendSetVolBass(uint8_t pct)
  252. {
  253. if (pct > 100u) pct = 100u;
  254. UART_SendWrite(ITEM_VOL_BASS, pct);
  255. }
  256. void SendSetDacMute(uint8_t unmute)
  257. {
  258. UART_SendWrite(ITEM_DAC_MUTE, unmute);
  259. }
  260. void SendBTDisconnect(void)
  261. {
  262. UART_SendWrite(ITEM_BT_CONN, 0x00u);
  263. }
  264. void SendSoftReset(void)
  265. {
  266. UART_SendWrite(ITEM_SOFT_RESET, 0x00u);
  267. }
  268. void SendBassMute(void)
  269. {
  270. UART_SendWrite(ITEM_BASS_MUTE, 0x00u);
  271. }
  272. void SendQueryAll(void)
  273. {
  274. UART_SendFrame(CMD_READ, ITEM_QUERY_ALL, 0x00u);
  275. }
  276. /* ========== 上报处理 (私有) ========== */
  277. /**
  278. * @brief 处理单条变化上报 (AA 81 ITEM VALUE CRC)
  279. */
  280. static void HandleReportSingle(uint8_t item, uint8_t value)
  281. {
  282. uint8_t firstTime = !g_dataReceived;
  283. if (firstTime)
  284. {
  285. g_dataReceived = 1u;
  286. }
  287. switch (item)
  288. {
  289. case ITEM_INPUT_SRC:
  290. g_inputSource = value;
  291. g_sourceReceived = 1u;
  292. UpdateSourceLED();
  293. break;
  294. case ITEM_BT_CONN:
  295. g_btConnState = value;
  296. g_sourceReceived = 1u;
  297. UpdateSourceLED();
  298. break;
  299. case ITEM_BT_AUDIO:
  300. g_audioPlaying = value;
  301. g_sourceReceived = 1u;
  302. UpdateSourceLED();
  303. break;
  304. case ITEM_BATTERY:
  305. g_batteryPct = value;
  306. g_batteryReceived = 1u;
  307. UpdateBatteryLEDs();
  308. break;
  309. case ITEM_CHG_FULL:
  310. g_chgFull = value;
  311. g_batteryReceived = 1u;
  312. UpdateBatteryLEDs();
  313. break;
  314. case ITEM_CHG_ING:
  315. g_chgIng = value;
  316. g_batteryReceived = 1u;
  317. UpdateBatteryLEDs();
  318. break;
  319. case ITEM_DAC_MUTE:
  320. g_dacMute = value;
  321. break;
  322. case ITEM_VOL_LR:
  323. if (!g_userActive)
  324. {
  325. g_volLRLevel = (int16_t)value;
  326. }
  327. g_volLRReceived = 1u;
  328. UpdateVolumeLEDs();
  329. break;
  330. case ITEM_VOL_BASS:
  331. if (!g_userActive)
  332. {
  333. g_volBassLevel = (int16_t)value;
  334. }
  335. g_volBassReceived = 1u;
  336. UpdateVolumeLEDs();
  337. break;
  338. default:
  339. break;
  340. }
  341. /* 第一次收到数据但不是完整的合并上报, 触发查询获取全部状态 */
  342. if (firstTime)
  343. {
  344. SendQueryAll();
  345. }
  346. }
  347. /**
  348. * @brief 处理多条上报 (AA 81 COUNT ITEM1 VAL1 ITEM2 VAL2 ... CRC)
  349. */
  350. static void HandleReportAll(uint8_t *data, uint8_t count)
  351. {
  352. if (!g_dataReceived)
  353. {
  354. g_dataReceived = 1u;
  355. }
  356. /* 解析每一对 ITEM+VALUE */
  357. for (uint8_t i = 0; i < count; i++)
  358. {
  359. uint8_t idx = (uint8_t)(i * 2u);
  360. uint8_t item = data[idx];
  361. uint8_t value = data[idx + 1u];
  362. switch (item)
  363. {
  364. case ITEM_INPUT_SRC:
  365. g_inputSource = value;
  366. g_sourceReceived = 1u;
  367. break;
  368. case ITEM_BT_CONN:
  369. g_btConnState = value;
  370. g_sourceReceived = 1u;
  371. break;
  372. case ITEM_BT_AUDIO:
  373. g_audioPlaying = value;
  374. g_sourceReceived = 1u;
  375. break;
  376. case ITEM_DAC_MUTE:
  377. g_dacMute = value;
  378. break;
  379. case ITEM_VOL_LR:
  380. if (!g_userActive)
  381. {
  382. g_volLRLevel = (int16_t)value;
  383. }
  384. g_volLRReceived = 1u;
  385. break;
  386. case ITEM_VOL_BASS:
  387. if (!g_userActive)
  388. {
  389. g_volBassLevel = (int16_t)value;
  390. }
  391. g_volBassReceived = 1u;
  392. break;
  393. case ITEM_BATTERY:
  394. g_batteryPct = value;
  395. g_batteryReceived = 1u;
  396. break;
  397. case ITEM_CHG_FULL:
  398. g_chgFull = value;
  399. g_batteryReceived = 1u;
  400. break;
  401. case ITEM_CHG_ING:
  402. g_chgIng = value;
  403. g_batteryReceived = 1u;
  404. break;
  405. default: break;
  406. }
  407. }
  408. /* 收到全量状态后,统一刷新所有 LED 显示,实现无缝切换 */
  409. UpdateVolumeLEDs();
  410. UpdateSourceLED();
  411. UpdateBatteryLEDs();
  412. }