Tool/software: Code Composer Studio
Dear team,
CANID and CAN message content are misaligned When dynamically managing the CAN message box.
Are there routines or source codes for CAN dynamic management?
The sending method I have used is:
void CANSimpleSend(canBASE_t *const canreg, uint32_t msgbox, uint32_t ID, uint8_t *const data) {
static uint32_t ret = 0U;
uint8_t trytimes = 3U;
canUpdateID(canreg, msgbox, 1U << 30U | 1U << 29U | (ID & 0x1FFFFFFFU));
do {
ret = canTransmit(canreg, msgbox, data);
if (ret == 0U) {
int16_t i = 1000U;
while (i > 0) i--;
}
trytimes--;
} while ((ret == 0U) && (trytimes > 0U));
}
uint16 CANSend(uint8 Dest, CAN_MSG_TYPE type, uint8 *const data)
{
uint32 canid = 0U;
canid |= (type & 0xFFU);
canid |= Dest << 8U;
canid |= GetBoardID() << 16U;
/* CANID 30bit: ext_ID 29bit: Dir Transmit */
static uint32_t msgbox = canMESSAGE_BOX1;
data[0U] = canindex++; /* data[0] is frame index */
/* CAN1 */
CANSimpleSend(canREG1,msgbox,canid,data);
/* CAN2 */
CANSimpleSend(canREG2,msgbox,canid,data);
msgbox++;
if (msgbox == canMESSAGE_BOX9) msgbox = canMESSAGE_BOX1;
return 0;
}
Send dynamically through messagebox1-8, in this case, the error rate is very high when sending at high speed.
The modified sending method combines the changed ID and the changed data
uint8_t canSimpleTransmit(canBASE_t *const canreg, uint32_t msgbox, uint32_t ID, uint8_t * data)
{
uint32 i;
uint32 success = 0U;
uint32 regIndex = (msgbox - 1U) >> 5U;
uint32 bitIndex = 1U << ((msgbox - 1U) & 0x1FU);
/** - Check for pending message:
* - pending message, return 0
* - no pending message, start new transmission
*/
if ((canreg->TXRQx[regIndex] & bitIndex) != 0U)
{
success = 0U;
}
else
{
/** - Wait until IF1 and IF2 is ready for use */
while(
((canreg->IF1STAT & 0x80U) ==0x80U) ||
((canreg->IF2STAT & 0x80U) ==0x80U)
)
{
} /* Wait */
/** - Configure IF2 for
* - Message direction - Read
* - Data Read
* - Clears NewDat bit in the message object.
*/
canreg->IF2CMD = 0xA0U;
/* Copy passed value into the arbitration register. */
canreg->IF2ARB &= 0x80000000U;
canreg->IF2ARB |= (ID & 0x7FFFFFFFU);
/** - Configure IF1 for
* - Message direction - Write
* - Data Update
* - Start Transmission
*/
canreg->IF1CMD = 0x87U;
/** - Copy TX data into IF1 */
for (i = 0U; i < 8U; i++)
{
#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
node->IF1DATx[i] = *data;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
data++;
#else
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
canreg->IF1DATx[s_canByteOrder[i]] = *data;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
data++;
#endif
}
/** - Update message box number. */
/*SAFETYMCUSW 93 S MR: 6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "LDRA Tool issue" */
canreg->IF2NO = (uint8) msgbox;
/** - Wait until data are copied into IF2 */
while ((canreg->IF2STAT & 0x80U) ==0x80U)
{
} /* Wait */
/** - Copy TX data into message box */
/*SAFETYMCUSW 93 S MR: 6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "LDRA Tool issue" */
canreg->IF1NO = (uint8) msgbox;
/** - Wait until data are copied into IF1 */
while ((canreg->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
success = 1U;
}
return success;
}
After the modification, the error rate is greatly reduced, but there are still occasional errors.
Now the application is built on the basis of high security requirements. This requirement is relatively strict, and I hope to get a stable management plan.
When multiple message boxes are sent, how to determine that the sending is complete?
After enabling the tx interrupt, can it be judged through the INTPNDx register? (This messagebox is only for sending)
BR,
susan