123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- #include "LinCP.h"
- #include "cmsis_os.h"
- #define LIN_SYNC_BYTE (0x55)
- #define PID_MAX (0x3F)
- static u8 LIN_PID_TABLE[PID_MAX + 1];
- #define LINCP_COMM_TIMEOUT (300)
- #define LINCP_COMM_CHECK_PERIOD (5)
- typedef union _LIN_ID_Field
- {
- u8 value;
- struct
- {
- u8 b0:1;
- u8 b1:1;
- u8 b2:1;
- u8 b3:1;
- u8 b4:1;
- u8 b5:1;
- u8 p0:1;
- u8 p1:1;
- };
- } __attribute__((__packed__))
- LIN_ID_Field, *PLIN_ID_Field;
- void LIN_CreatePidTable(void)
- {
- LIN_ID_Field x;
- for (u8 i = 0; i <= PID_MAX; i++)
- {
- x.value = i;
- x.p0 = (x.b0 ^ x.b1 ^ x.b2 ^ x.b4);
- x.p1 = (x.b1 ^ x.b3 ^ x.b4 ^ x.b5) ^ 1;
- LIN_PID_TABLE[i] = x.value;
- #ifdef DEBUG_LIN_CP
- XP("PID[%02d] %02X "BYTE_TO_BINARY_PATTERN" %s",
- i, LIN_PID_TABLE[i], BYTE_TO_BINARY(LIN_PID_TABLE[i]), (i % 4 == 3 ? "\r\n" : ""));
- #endif
- }
- }
- u8 LIN_CalcCheckSum(u8 id, u8 *data, u8 len)
- {
- #ifdef LIN_VER_2X
- u32 Sum = LIN_PID_TABLE[id];
- #else
- u32 Sum = 0;
- #endif
- for (int i = 0; i < len; i++)
- {
- Sum += data[i];
- if (0xFF < Sum)
- {
- Sum = (Sum & 0xFF) + 1;
- }
- }
- return (u8)(~Sum & 0xFF);
- }
- void LIN_FlowTx(PLinCP p, HTK_BOOL bTx, HTK_BOOL bRx)
- {
- if (p == NULL)
- return;
- if (bTx == HTK_TRUE && bRx == HTK_TRUE)
- bRx = HTK_FALSE;
- if (bTx)
- {
-
- p->m_bRx = HTK_FALSE;
- LL_USART_DisableIT_RXNE(p->m_USART);
- LL_USART_DisableIT_LBD(p->m_USART);
- LL_USART_DisableIT_ERROR(p->m_USART);
- p->m_RxLen = 0;
-
- LL_USART_DisableDirectionRx(p->m_USART);
- LL_USART_EnableIT_TXE(p->m_USART);
- p->m_bTx = HTK_TRUE;
- }
- else
- {
- p->m_bTx = HTK_FALSE;
-
- LL_USART_DisableIT_TXE(p->m_USART);
- LL_USART_EnableDirectionRx(p->m_USART);
- if (!bRx)
- {
-
- p->m_bRx = HTK_FALSE;
- LL_USART_DisableIT_RXNE(p->m_USART);
- LL_USART_DisableIT_LBD(p->m_USART);
- LL_USART_DisableIT_ERROR(p->m_USART);
- }
- else
- {
-
- LL_USART_EnableIT_RXNE(p->m_USART);
- LL_USART_EnableIT_LBD(p->m_USART);
- LL_USART_EnableIT_ERROR(p->m_USART);
- p->m_bRx = HTK_TRUE;
- }
- p->m_RxLen = 0;
- }
- }
- void LIN_Init(PLinCP p, USART_TypeDef* usart)
- {
- if (p == NULL)
- return;
- LIN_CreatePidTable();
- p->m_USART = usart;
- #ifdef FUNC_LIN_MASTER
- LIN_FlowTx(p, HTK_FALSE, HTK_FALSE);
- #else
- #endif
- }
- HTK_BOOL LIN_TxHeader(PLinCP p, u8 id)
- {
- if (p == NULL)
- return HTK_FALSE;
-
- memset(p->m_TxBuf, 0, sizeof(p->m_TxBuf));
- memset(p->m_RxBuf, 0, sizeof(p->m_RxBuf));
- p->m_TxBuf[0] = LIN_SYNC_BYTE;
- p->m_TxBuf[1] = LIN_PID_TABLE[id];
- p->m_TxIdx = 0;
- p->m_TxLen = 2;
- LIN_FlowTx(p, HTK_TRUE, HTK_FALSE);
- #ifdef DEBUG_LIN_CP
- XP("LIN-TX(H): PID(%02X) ID(%02X)\r\n", p->m_TxBuf[1], id);
- #endif
- u32 BegTick = HAL_GetTick();
- do
- {
- osDelay(LINCP_COMM_CHECK_PERIOD);
- if (HTK_IsTimeout(BegTick, LINCP_COMM_TIMEOUT))
- {
- p->m_bTxTimeout = HTK_TRUE;
- p->m_nTxNG++;
- #ifdef DEBUG_LIN_CP
- XP("LIN-TX(H): PID(%02X) ID(%02X) ... TxTimeout(%d)!\r\n", p->m_TxBuf[1], id, p->m_nTxNG);
- #endif
- return HTK_FALSE;
- }
- }
- while(p->m_TxLen != 0);
- p->m_bTxTimeout = HTK_FALSE;
- p->m_nTxOK++;
- int DataIndex = 1;
- BegTick = HAL_GetTick();
- do
- {
- osDelay(LINCP_COMM_CHECK_PERIOD);
- if (p->m_RxLen == 10 && p->m_RxBuf[0] == 0xF0)
- {
- DataIndex = 1;
- break;
- }
- else if (p->m_RxLen == 9 && p->m_RxBuf[0] != 0xF0)
- {
- DataIndex = 0;
- break;
- }
- if (HTK_IsTimeout(BegTick, LINCP_COMM_TIMEOUT))
- {
- p->m_bRxTimeout = HTK_TRUE;
- p->m_nRxNG++;
- #ifdef DEBUG_LIN_CP
- 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);
- 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",
- p->m_RxBuf[0], p->m_RxBuf[1], p->m_RxBuf[2], p->m_RxBuf[3], p->m_RxBuf[4], p->m_RxBuf[5],
- p->m_RxBuf[6], p->m_RxBuf[7], p->m_RxBuf[8], p->m_RxBuf[9], p->m_RxBuf[10], p->m_RxLen);
- #endif
- return HTK_FALSE;
- }
- }
- while (1);
-
- p->m_bRxTimeout = HTK_FALSE;
- p->m_nRxOK++;
- LIN_FlowTx(p, HTK_FALSE, HTK_FALSE);
- if (!p->m_bTxTimeout && !p->m_bRxTimeout)
- {
- HTK_BOOL bChecksum = (LIN_CalcCheckSum(id, &p->m_RxBuf[DataIndex], 8) == p->m_RxBuf[DataIndex + 8]);
- #ifdef DEBUG_LIN_CP
- XP("LIN-RX(D): PID(%02X) ID(%02X) {%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X} [%02X%s] <%d, %d>\r\n",
- p->m_TxBuf[1], id,
- p->m_RxBuf[DataIndex + 0], p->m_RxBuf[DataIndex + 1], p->m_RxBuf[DataIndex + 2], p->m_RxBuf[DataIndex + 3],
- p->m_RxBuf[DataIndex + 4], p->m_RxBuf[DataIndex + 5], p->m_RxBuf[DataIndex + 6], p->m_RxBuf[DataIndex + 7],
- p->m_RxBuf[DataIndex + 8], (bChecksum ? "" : " [NG]"),
- p->m_nTxOK, p->m_nRxOK);
- #endif
- return bChecksum;
- }
- else
- {
- return HTK_FALSE;
- }
- }
- HTK_BOOL LIN_TxHeaderData(PLinCP p, u8 id, void* Data, u8 DataLen)
- {
- if (p == NULL)
- return HTK_FALSE;
-
- memset(p->m_TxBuf, 0, sizeof(p->m_TxBuf));
- memset(p->m_RxBuf, 0, sizeof(p->m_RxBuf));
- p->m_TxBuf[0] = LIN_SYNC_BYTE;
- p->m_TxBuf[1] = LIN_PID_TABLE[id];
- DataLen = HTK_GET_VAL_MIN(DataLen, 8);
- memcpy(&p->m_TxBuf[2], Data, DataLen);
- p->m_TxBuf[2 + DataLen] = LIN_CalcCheckSum(id, &p->m_TxBuf[2], DataLen);
- p->m_TxIdx = 0;
- p->m_TxLen = 2 + DataLen + 1;
- LIN_FlowTx(p, HTK_TRUE, HTK_FALSE);
- u32 BegTick = HAL_GetTick();
- do
- {
- osDelay(LINCP_COMM_CHECK_PERIOD);
- if (HTK_IsTimeout(BegTick, LINCP_COMM_TIMEOUT))
- {
- p->m_bTxTimeout = HTK_TRUE;
- p->m_nTxNG++;
- #ifdef DEBUG_LIN_CP
- XP("LIN-TX(A): PID(%02X) ID(%02X) ... TxTimeout(%d)!\r\n", p->m_TxBuf[1], id, p->m_nTxNG);
- #endif
- return HTK_FALSE;
- }
- }
- while(p->m_TxLen != 0);
- p->m_bTxTimeout = HTK_FALSE;
- p->m_nTxOK++;
- #ifdef DEBUG_LIN_CP
- XP("LIN-TX(A): PID(%02X) ID(%02X) {%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X} [%02X] <%d, %d>\r\n",
- p->m_TxBuf[1], id,
- p->m_TxBuf[2], p->m_TxBuf[3], p->m_TxBuf[4], p->m_TxBuf[5],
- p->m_TxBuf[6], p->m_TxBuf[7], p->m_TxBuf[8], p->m_TxBuf[9],
- p->m_TxBuf[10], p->m_nTxOK, p->m_nRxOK);
- #endif
- return HTK_TRUE;
- }
- void LIN_Display(PLinCP p)
- {
- if (p == NULL)
- return;
- XP("-----------------------[ LIN-CP ]------------------------\r\n");
- XP("TxOK: %d, TxNG: %d, SUM: %d\r\n", p->m_nTxOK, p->m_nTxNG, p->m_nTxOK + p->m_nTxNG);
- XP("RxOK: %d, RxNG: %d, SUM: %d\r\n", p->m_nRxOK, p->m_nRxNG, p->m_nRxOK + p->m_nRxNG);
- XP("---------------------------------------------------------\r\n");
- }
- void LIN_IRQ_Proc(PLinCP p)
- {
- if (p == NULL)
- return;
- #ifdef FUNC_LIN_MASTER
- LIN_IRQ_Master_ProcTx(p);
- LIN_IRQ_Master_ProcRx(p);
- #else
- #endif
- }
- #ifdef FUNC_LIN_MASTER
- void LIN_IRQ_Master_ProcTx(PLinCP p)
- {
- if (p == NULL)
- return;
- if (LL_USART_IsActiveFlag_TXE(p->m_USART))
- {
- if (p->m_TxIdx == 0 && p->m_TxLen == 0)
- return;
- if (p->m_TxIdx < p->m_TxLen)
- {
- if (p->m_TxIdx == 0)
- {
- LL_USART_RequestBreakSending(p->m_USART);
- }
- LL_USART_TransmitData8(p->m_USART, p->m_TxBuf[p->m_TxIdx++]);
- }
- else
- {
- p->m_TxLen = 0;
- p->m_TxIdx = 0;
- LIN_FlowTx(p, HTK_FALSE, HTK_TRUE);
- }
- }
- }
- void LIN_IRQ_Master_ProcRx(PLinCP p)
- {
- if (p == NULL)
- return;
- if (LL_USART_IsActiveFlag_LBD(p->m_USART))
- {
- LL_USART_ClearFlag_LBD(p->m_USART);
- p->m_RxLen = 0;
- }
- else if (LL_USART_IsActiveFlag_FE(p->m_USART))
- {
- u8 Data = LL_USART_ReceiveData8(p->m_USART);
- XP("#LIN_ProcRx_Flag_FE = %02X\r\n", Data);
- }
- else if (LL_USART_IsActiveFlag_ORE(p->m_USART))
- {
- u8 Data = LL_USART_ReceiveData8(p->m_USART);
- XP("#LIN_ProcRx_Flag_ORE = %02X\r\n", Data);
- }
- else if (LL_USART_IsActiveFlag_NE(p->m_USART))
- {
- u8 Data = LL_USART_ReceiveData8(p->m_USART);
- XP("#LIN_ProcRx_Flag_NE = %02X\r\n", Data);
- }
- else if (LL_USART_IsActiveFlag_RXNE(p->m_USART))
- {
- p->m_RxBuf[p->m_RxLen++] = LL_USART_ReceiveData8(p->m_USART);
- }
- else
- {
- }
- }
- #else
- #endif
|