LinCP.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. #include "LinCP.h"
  2. #include "cmsis_os.h"
  3. #define LIN_SYNC_BYTE (0x55)
  4. #define PID_MAX (0x3F) //63 (6 bit ID: 0 ~ 63)
  5. static u8 LIN_PID_TABLE[PID_MAX + 1];
  6. #define LINCP_COMM_TIMEOUT (300) //ms 100
  7. #define LINCP_COMM_CHECK_PERIOD (5) //ms
  8. typedef union _LIN_ID_Field
  9. {
  10. u8 value;
  11. struct
  12. {
  13. u8 b0:1;
  14. u8 b1:1;
  15. u8 b2:1;
  16. u8 b3:1;
  17. u8 b4:1;
  18. u8 b5:1;
  19. u8 p0:1;
  20. u8 p1:1;
  21. };
  22. } __attribute__((__packed__))
  23. LIN_ID_Field, *PLIN_ID_Field;
  24. void LIN_CreatePidTable(void)
  25. {
  26. LIN_ID_Field x;
  27. for (u8 i = 0; i <= PID_MAX; i++)
  28. {
  29. x.value = i;
  30. x.p0 = (x.b0 ^ x.b1 ^ x.b2 ^ x.b4);
  31. x.p1 = (x.b1 ^ x.b3 ^ x.b4 ^ x.b5) ^ 1;
  32. LIN_PID_TABLE[i] = x.value;
  33. #ifdef DEBUG_LIN_CP
  34. XP("PID[%02d] %02X "BYTE_TO_BINARY_PATTERN" %s",
  35. i, LIN_PID_TABLE[i], BYTE_TO_BINARY(LIN_PID_TABLE[i]), (i % 4 == 3 ? "\r\n" : ""));
  36. #endif
  37. }
  38. }
  39. u8 LIN_CalcCheckSum(u8 id, u8 *data, u8 len)
  40. {
  41. #ifdef LIN_VER_2X
  42. u32 Sum = LIN_PID_TABLE[id];
  43. #else
  44. u32 Sum = 0;
  45. #endif
  46. for (int i = 0; i < len; i++)
  47. {
  48. Sum += data[i];
  49. if (0xFF < Sum)
  50. {
  51. Sum = (Sum & 0xFF) + 1;
  52. }
  53. }
  54. return (u8)(~Sum & 0xFF);
  55. }
  56. void LIN_FlowTx(PLinCP p, HTK_BOOL bTx, HTK_BOOL bRx)
  57. {
  58. if (p == NULL)
  59. return;
  60. if (bTx == HTK_TRUE && bRx == HTK_TRUE)
  61. bRx = HTK_FALSE;
  62. if (bTx)
  63. {
  64. //Disable RX
  65. p->m_bRx = HTK_FALSE;
  66. LL_USART_DisableIT_RXNE(p->m_USART);
  67. LL_USART_DisableIT_LBD(p->m_USART);
  68. LL_USART_DisableIT_ERROR(p->m_USART);
  69. p->m_RxLen = 0;
  70. //Enable TX
  71. LL_USART_DisableDirectionRx(p->m_USART);
  72. LL_USART_EnableIT_TXE(p->m_USART);
  73. p->m_bTx = HTK_TRUE;
  74. }
  75. else //Rx
  76. {
  77. p->m_bTx = HTK_FALSE;
  78. //Disable TX
  79. LL_USART_DisableIT_TXE(p->m_USART);
  80. LL_USART_EnableDirectionRx(p->m_USART);
  81. if (!bRx)
  82. {
  83. //Disable RX
  84. p->m_bRx = HTK_FALSE;
  85. LL_USART_DisableIT_RXNE(p->m_USART);
  86. LL_USART_DisableIT_LBD(p->m_USART);
  87. LL_USART_DisableIT_ERROR(p->m_USART);
  88. }
  89. else
  90. {
  91. //Enable RX
  92. LL_USART_EnableIT_RXNE(p->m_USART);
  93. LL_USART_EnableIT_LBD(p->m_USART);
  94. LL_USART_EnableIT_ERROR(p->m_USART);
  95. p->m_bRx = HTK_TRUE;
  96. }
  97. p->m_RxLen = 0;
  98. }
  99. //#ifdef DEBUG_LIN_CP
  100. // XP("<LIN_Flow: %s, %d, %d>\r\n", bTx ? "TX" : "RX", p->m_bTx, p->m_bRx);
  101. //#endif
  102. }
  103. //void LIN_SetTx(PLinCP p, HTK_BOOL bEnable)
  104. //{
  105. // if (bEnable)
  106. // {
  107. // LL_USART_DisableDirectionRx(p->m_USART);
  108. // LL_USART_EnableIT_TXE(p->m_USART);
  109. // }
  110. // else
  111. // {
  112. // LL_USART_DisableIT_TXE(p->m_USART);
  113. // LL_USART_EnableDirectionRx(p->m_USART);
  114. // }
  115. //}
  116. //void LIN_SetRx(PLinCP p, HTK_BOOL bEnable)
  117. //{
  118. // if (bEnable)
  119. // {
  120. // LL_USART_EnableIT_RXNE(p->m_USART);
  121. // LL_USART_EnableIT_LBD(p->m_USART);
  122. // LL_USART_EnableIT_ERROR(p->m_USART);
  123. // }
  124. // else
  125. // {
  126. // LL_USART_DisableIT_RXNE(p->m_USART);
  127. // LL_USART_DisableIT_LBD(p->m_USART);
  128. // LL_USART_DisableIT_ERROR(p->m_USART);
  129. // }
  130. //}
  131. void LIN_Init(PLinCP p, USART_TypeDef* usart)
  132. {
  133. if (p == NULL)
  134. return;
  135. LIN_CreatePidTable();
  136. p->m_USART = usart;
  137. #ifdef FUNC_LIN_MASTER
  138. LIN_FlowTx(p, HTK_FALSE, HTK_FALSE);
  139. #else
  140. #endif
  141. }
  142. HTK_BOOL LIN_TxHeader(PLinCP p, u8 id)
  143. {
  144. if (p == NULL)
  145. return HTK_FALSE;
  146. //osDelay(10);
  147. memset(p->m_TxBuf, 0, sizeof(p->m_TxBuf));
  148. memset(p->m_RxBuf, 0, sizeof(p->m_RxBuf));
  149. p->m_TxBuf[0] = LIN_SYNC_BYTE;
  150. p->m_TxBuf[1] = LIN_PID_TABLE[id];
  151. p->m_TxIdx = 0;
  152. p->m_TxLen = 2;
  153. LIN_FlowTx(p, HTK_TRUE, HTK_FALSE);
  154. #ifdef DEBUG_LIN_CP
  155. XP("LIN-TX(H): PID(%02X) ID(%02X)\r\n", p->m_TxBuf[1], id);
  156. #endif
  157. u32 BegTick = HAL_GetTick();
  158. do
  159. {
  160. osDelay(LINCP_COMM_CHECK_PERIOD);
  161. if (HTK_IsTimeout(BegTick, LINCP_COMM_TIMEOUT))
  162. {
  163. p->m_bTxTimeout = HTK_TRUE;
  164. p->m_nTxNG++;
  165. #ifdef DEBUG_LIN_CP
  166. XP("LIN-TX(H): PID(%02X) ID(%02X) ... TxTimeout(%d)!\r\n", p->m_TxBuf[1], id, p->m_nTxNG);
  167. #endif
  168. return HTK_FALSE;
  169. }
  170. }
  171. while(p->m_TxLen != 0);
  172. p->m_bTxTimeout = HTK_FALSE;
  173. p->m_nTxOK++;
  174. int DataIndex = 1; //0: 0xF0
  175. BegTick = HAL_GetTick();
  176. do
  177. {
  178. osDelay(LINCP_COMM_CHECK_PERIOD);
  179. if (p->m_RxLen == 10 && p->m_RxBuf[0] == 0xF0)
  180. {
  181. DataIndex = 1;
  182. break;
  183. }
  184. else if (p->m_RxLen == 9 && p->m_RxBuf[0] != 0xF0)
  185. {
  186. DataIndex = 0;
  187. break;
  188. }
  189. if (HTK_IsTimeout(BegTick, LINCP_COMM_TIMEOUT))
  190. {
  191. p->m_bRxTimeout = HTK_TRUE;
  192. p->m_nRxNG++;
  193. #ifdef DEBUG_LIN_CP
  194. XP("LIN-TX(H): PID(%02X) ID(%02X) ... RxTimeout(%d)! (RxLen = %d)\r\n", p->m_TxBuf[1], id, p->m_nRxNG, p->m_RxLen);
  195. XP("[0]%02X [1]%02X [2]%02X [3]%02X [4]%02X [5]%02X [6]%02X [7]%02X [8]%02X [9]%02X [10]%02X Len = %d\r\n",
  196. p->m_RxBuf[0], p->m_RxBuf[1], p->m_RxBuf[2], p->m_RxBuf[3], p->m_RxBuf[4], p->m_RxBuf[5],
  197. p->m_RxBuf[6], p->m_RxBuf[7], p->m_RxBuf[8], p->m_RxBuf[9], p->m_RxBuf[10], p->m_RxLen);
  198. #endif
  199. return HTK_FALSE;
  200. }
  201. }
  202. while (1);
  203. //while (p->m_RxLen != 10);
  204. p->m_bRxTimeout = HTK_FALSE;
  205. p->m_nRxOK++;
  206. LIN_FlowTx(p, HTK_FALSE, HTK_FALSE);
  207. if (!p->m_bTxTimeout && !p->m_bRxTimeout)
  208. {
  209. HTK_BOOL bChecksum = (LIN_CalcCheckSum(id, &p->m_RxBuf[DataIndex], 8) == p->m_RxBuf[DataIndex + 8]);
  210. #ifdef DEBUG_LIN_CP
  211. XP("LIN-RX(D): PID(%02X) ID(%02X) {%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X} [%02X%s] <%d, %d>\r\n",
  212. p->m_TxBuf[1], id,
  213. p->m_RxBuf[DataIndex + 0], p->m_RxBuf[DataIndex + 1], p->m_RxBuf[DataIndex + 2], p->m_RxBuf[DataIndex + 3],
  214. p->m_RxBuf[DataIndex + 4], p->m_RxBuf[DataIndex + 5], p->m_RxBuf[DataIndex + 6], p->m_RxBuf[DataIndex + 7],
  215. p->m_RxBuf[DataIndex + 8], (bChecksum ? "" : " [NG]"),
  216. p->m_nTxOK, p->m_nRxOK);
  217. #endif
  218. return bChecksum;
  219. }
  220. else
  221. {
  222. return HTK_FALSE;
  223. }
  224. }
  225. HTK_BOOL LIN_TxHeaderData(PLinCP p, u8 id, void* Data, u8 DataLen)
  226. {
  227. if (p == NULL)
  228. return HTK_FALSE;
  229. //osDelay(10);
  230. memset(p->m_TxBuf, 0, sizeof(p->m_TxBuf));
  231. memset(p->m_RxBuf, 0, sizeof(p->m_RxBuf));
  232. p->m_TxBuf[0] = LIN_SYNC_BYTE;
  233. p->m_TxBuf[1] = LIN_PID_TABLE[id];
  234. DataLen = HTK_GET_VAL_MIN(DataLen, 8);
  235. memcpy(&p->m_TxBuf[2], Data, DataLen);
  236. p->m_TxBuf[2 + DataLen] = LIN_CalcCheckSum(id, &p->m_TxBuf[2], DataLen);
  237. p->m_TxIdx = 0;
  238. p->m_TxLen = 2 + DataLen + 1;
  239. LIN_FlowTx(p, HTK_TRUE, HTK_FALSE);
  240. u32 BegTick = HAL_GetTick();
  241. do
  242. {
  243. osDelay(LINCP_COMM_CHECK_PERIOD);
  244. if (HTK_IsTimeout(BegTick, LINCP_COMM_TIMEOUT))
  245. {
  246. p->m_bTxTimeout = HTK_TRUE;
  247. p->m_nTxNG++;
  248. #ifdef DEBUG_LIN_CP
  249. XP("LIN-TX(A): PID(%02X) ID(%02X) ... TxTimeout(%d)!\r\n", p->m_TxBuf[1], id, p->m_nTxNG);
  250. #endif
  251. return HTK_FALSE;
  252. }
  253. }
  254. while(p->m_TxLen != 0);
  255. p->m_bTxTimeout = HTK_FALSE;
  256. p->m_nTxOK++;
  257. #ifdef DEBUG_LIN_CP
  258. XP("LIN-TX(A): PID(%02X) ID(%02X) {%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X} [%02X] <%d, %d>\r\n",
  259. p->m_TxBuf[1], id,
  260. p->m_TxBuf[2], p->m_TxBuf[3], p->m_TxBuf[4], p->m_TxBuf[5],
  261. p->m_TxBuf[6], p->m_TxBuf[7], p->m_TxBuf[8], p->m_TxBuf[9],
  262. p->m_TxBuf[10], p->m_nTxOK, p->m_nRxOK);
  263. #endif
  264. return HTK_TRUE;
  265. }
  266. void LIN_Display(PLinCP p)
  267. {
  268. if (p == NULL)
  269. return;
  270. XP("-----------------------[ LIN-CP ]------------------------\r\n");
  271. XP("TxOK: %d, TxNG: %d, SUM: %d\r\n", p->m_nTxOK, p->m_nTxNG, p->m_nTxOK + p->m_nTxNG);
  272. XP("RxOK: %d, RxNG: %d, SUM: %d\r\n", p->m_nRxOK, p->m_nRxNG, p->m_nRxOK + p->m_nRxNG);
  273. XP("---------------------------------------------------------\r\n");
  274. }
  275. void LIN_IRQ_Proc(PLinCP p)
  276. {
  277. if (p == NULL)
  278. return;
  279. #ifdef FUNC_LIN_MASTER
  280. // if (p->m_bTx)
  281. // {
  282. // LIN_IRQ_Master_ProcTx(p);
  283. // }
  284. // else if (p->m_bRx)
  285. // {
  286. // LIN_IRQ_Master_ProcRx(p);
  287. // }
  288. LIN_IRQ_Master_ProcTx(p);
  289. LIN_IRQ_Master_ProcRx(p);
  290. #else
  291. // if (p->m_bTx)
  292. // {
  293. // LIN_IRQ_Slave_ProcTx(p);
  294. // }
  295. //
  296. // if (p->m_bRx)
  297. // {
  298. // LIN_IRQ_Slave_ProcRx(p);
  299. // }
  300. #endif
  301. }
  302. #ifdef FUNC_LIN_MASTER
  303. void LIN_IRQ_Master_ProcTx(PLinCP p)
  304. {
  305. if (p == NULL)
  306. return;
  307. if (LL_USART_IsActiveFlag_TXE(p->m_USART))
  308. {
  309. if (p->m_TxIdx == 0 && p->m_TxLen == 0)
  310. return;
  311. if (p->m_TxIdx < p->m_TxLen)
  312. {
  313. if (p->m_TxIdx == 0)
  314. {
  315. LL_USART_RequestBreakSending(p->m_USART);
  316. }
  317. LL_USART_TransmitData8(p->m_USART, p->m_TxBuf[p->m_TxIdx++]);
  318. }
  319. else
  320. {
  321. p->m_TxLen = 0;
  322. p->m_TxIdx = 0;
  323. LIN_FlowTx(p, HTK_FALSE, HTK_TRUE);
  324. }
  325. }
  326. }
  327. void LIN_IRQ_Master_ProcRx(PLinCP p)
  328. {
  329. if (p == NULL)
  330. return;
  331. if (LL_USART_IsActiveFlag_LBD(p->m_USART))
  332. {
  333. LL_USART_ClearFlag_LBD(p->m_USART);
  334. p->m_RxLen = 0;
  335. }
  336. // else if (
  337. // LL_USART_IsActiveFlag_FE(p->m_USART) ||
  338. // LL_USART_IsActiveFlag_ORE(p->m_USART) ||
  339. // LL_USART_IsActiveFlag_NE(p->m_USART))
  340. // {
  341. // u8 Data = LL_USART_ReceiveData8(p->m_USART);
  342. // XP("Data = %02X\r\n", Data);
  343. // }
  344. else if (LL_USART_IsActiveFlag_FE(p->m_USART))
  345. {
  346. u8 Data = LL_USART_ReceiveData8(p->m_USART);
  347. XP("#LIN_ProcRx_Flag_FE = %02X\r\n", Data);
  348. }
  349. else if (LL_USART_IsActiveFlag_ORE(p->m_USART))
  350. {
  351. u8 Data = LL_USART_ReceiveData8(p->m_USART);
  352. XP("#LIN_ProcRx_Flag_ORE = %02X\r\n", Data);
  353. }
  354. else if (LL_USART_IsActiveFlag_NE(p->m_USART))
  355. {
  356. u8 Data = LL_USART_ReceiveData8(p->m_USART);
  357. XP("#LIN_ProcRx_Flag_NE = %02X\r\n", Data);
  358. }
  359. else if (LL_USART_IsActiveFlag_RXNE(p->m_USART))
  360. {
  361. p->m_RxBuf[p->m_RxLen++] = LL_USART_ReceiveData8(p->m_USART);
  362. // if (p->m_RxLen == 10)
  363. // {
  364. // LIN_FlowTx(p, HTK_FALSE, HTK_FALSE);
  365. // }
  366. // if (LIN_BUF_MAX <= p->m_RxLen)
  367. // {
  368. // if (p->m_RxBuf[0] == LIN_SYNC_BYTE)
  369. // {
  370. // u8 id = p->m_RxBuf[1] & PID_MAX;
  371. //
  372. // if (p->m_RxBuf[1] == LIN_PID_TABLE[id])
  373. // {
  374. // if (LIN_CalcCheckSum(id, &p->m_RxBuf[2], 8) == p->m_RxBuf[10])
  375. // {
  376. //#ifdef DEBUG_LIN_CP
  377. // XP("LIN-RX : PID(%02X) ID(%02X) {%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X} [%02X]\r\n",
  378. // p->m_RxBuf[1], id,
  379. // p->m_RxBuf[2], p->m_RxBuf[3], p->m_RxBuf[4], p->m_RxBuf[5],
  380. // p->m_RxBuf[6], p->m_RxBuf[7], p->m_RxBuf[8], p->m_RxBuf[9],
  381. // p->m_RxBuf[10]);
  382. //#endif
  383. // LIN_SetRx(p, HTK_FALSE);
  384. // p->m_bRx = HTK_FALSE;
  385. // }
  386. // else
  387. // {
  388. //
  389. // }
  390. // }
  391. // else
  392. // {
  393. //
  394. // }
  395. // }
  396. // else
  397. // {
  398. //
  399. // }
  400. //
  401. // p->m_RxLen = 0;
  402. // }
  403. }
  404. else
  405. {
  406. }
  407. }
  408. #else //FUNC_LIN_MASTER
  409. #endif //FUNC_LIN_MASTER