/* * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD * All rights reserved. * * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use * exclusively with CVA's microcontroller products. This file can be freely * distributed within development tools that are supporting such microcontroller * products. * * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. */ /******************************************************************************* * the includes ******************************************************************************/ #include "dbc_comm.h" /******************************************************************************* * the defines ******************************************************************************/ /******************************************************************************* * the typedefs ******************************************************************************/ /******************************************************************************* * the globals ******************************************************************************/ /******************************************************************************* * the functions ******************************************************************************/ void DbcComm_Init(DbcCommType *obj, const DbcComm_ParamsType *pParams) { uint8_t node = 0; for(node = 0; node < DBCCOMM_NODE_NUM; ++node) { obj->enableNodeTx[node] = false; obj->enableNodeRx[node] = false; } obj->sendCanMsg = pParams->sendCanMsg; uint16_t i = 0; /* Process send message */ for(i = 0; i < obj->txMsgNum; ++i) { obj->txMsgArray[i].periodCntMax = (uint32_t)(pParams->runFreq_kHz * obj->txMsgArray[i].pInfo->period_ms); obj->txMsgArray[i].periodCnt = i; /* Stagger the start timing */ } /* Process received message */ for(i = 0; i < obj->rxMsgNum; ++i) { obj->rxMsgArray[i].timeoutCntMax = (uint32_t)(pParams->runFreq_kHz * obj->rxMsgArray[i].pInfo->timeout_ms); obj->rxMsgArray[i].timeoutCnt = 0; obj->rxMsgArray[i].isTimeout = false; } } void DbcComm_Run(DbcCommType *obj) { uint16_t i = 0; /* Process send message */ for(i = 0; i < obj->txMsgNum; ++i) { DbcComm_CanNodeType node = obj->txMsgArray[i].pInfo->node; if(obj->enableNodeTx[node]) { if(obj->txMsgArray[i].periodCntMax > 0) { obj->txMsgArray[i].periodCnt++; if(obj->txMsgArray[i].periodCnt >= obj->txMsgArray[i].periodCntMax) { obj->txMsgArray[i].periodCnt = 0; /* Pack message and send it */ DbcComm_CanMsgType msg = CAN_MSG_DEFAULT; obj->txMsgArray[i].pInfo->packMsg(obj, &msg); obj->sendCanMsg(node, &msg); } } } } /* Process received message */ for(i = 0; i < obj->rxMsgNum; ++i) { DbcComm_CanNodeType node = obj->rxMsgArray[i].pInfo->node; if(obj->enableNodeRx[node]) { if(obj->rxMsgArray[i].timeoutCntMax > 0 && false == obj->rxMsgArray[i].isTimeout) { obj->rxMsgArray[i].timeoutCnt++; if(obj->rxMsgArray[i].timeoutCnt >= obj->rxMsgArray[i].timeoutCntMax) { obj->rxMsgArray[i].timeoutCnt = 0; obj->rxMsgArray[i].isTimeout = true; } } } } } void DbcComm_ReceiveCanMsg(DbcCommType *obj, DbcComm_CanNodeType node, const DbcComm_CanMsgType *pMsg) { uint16_t i = 0; for(i = 0; i < obj->rxMsgNum; ++i) { if(pMsg->id == obj->rxMsgArray[i].pInfo->id && node == obj->rxMsgArray[i].pInfo->node) { obj->rxMsgArray[i].timeoutCnt = 0; obj->rxMsgArray[i].isTimeout = false; obj->rxMsgArray[i].pInfo->unpackMsg(obj, pMsg); break; } } } void DbcComm_EnableRx(DbcCommType *obj, DbcComm_CanNodeType node, bool enable) { if(obj->enableNodeRx[node] != enable) { /* Change the enable status */ uint16_t i = 0; for(i = 0; i < obj->rxMsgNum; ++i) { if(obj->rxMsgArray[i].pInfo->node == node) { if(obj->rxMsgArray[i].timeoutCntMax > 0) { obj->rxMsgArray[i].timeoutCnt = 0; obj->rxMsgArray[i].isTimeout = false; } } } obj->enableNodeRx[node] = enable; } } void DbcComm_EnableTx(DbcCommType *obj, DbcComm_CanNodeType node, bool enable) { if(obj->enableNodeTx[node] != enable) { /* Change the enable status */ uint16_t i = 0; for(i = 0; i < obj->txMsgNum; ++i) { if(obj->txMsgArray[i].pInfo->node == node) { if(obj->txMsgArray[i].periodCntMax > 0) { obj->txMsgArray[i].periodCnt = obj->txMsgArray[i].periodCntMax; } } } obj->enableNodeTx[node] = enable; } }